diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-01-18 19:59:08 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-01-18 19:59:08 +0000 |
commit | 35f08c4d52d0ffd9f8aa50f47b84de5603842b1f (patch) | |
tree | 7def9d6d4ef3ffea169252d44325cb039294129d | |
parent | 4173bd8d5dd43413ba0635e2a74bc57a9478fb13 (diff) |
propagate from branch 'com.redhat.elfutils.nickc.pending' (head 28d6423325f0cc14a133eb6b92a8c3604e437ba6)
to branch 'com.redhat.elfutils' (head 6ef48518ed8497626058574c787852bd939d46ee)
-rw-r--r-- | config/elfutils.spec.in | 2 | ||||
-rw-r--r-- | libdw/ChangeLog | 46 | ||||
-rw-r--r-- | libdw/dwarf.h | 15 | ||||
-rw-r--r-- | libdw/dwarf_child.c | 8 | ||||
-rw-r--r-- | libdw/dwarf_diecu.c | 2 | ||||
-rw-r--r-- | libdw/dwarf_entry_breakpoints.c | 7 | ||||
-rw-r--r-- | libdw/dwarf_formref.c | 6 | ||||
-rw-r--r-- | libdw/dwarf_getaranges.c | 11 | ||||
-rw-r--r-- | libdw/dwarf_getattrs.c | 15 | ||||
-rw-r--r-- | libdw/dwarf_getpubnames.c | 22 | ||||
-rw-r--r-- | libdw/dwarf_getsrclines.c | 2 | ||||
-rw-r--r-- | libdw/dwarf_haschildren.c | 6 | ||||
-rw-r--r-- | libdw/dwarf_nextcu.c | 29 | ||||
-rw-r--r-- | libdw/dwarf_siblingof.c | 18 | ||||
-rw-r--r-- | libdw/dwarf_tag.c | 5 | ||||
-rw-r--r-- | libdw/libdw.h | 14 | ||||
-rw-r--r-- | libdw/libdwP.h | 15 | ||||
-rw-r--r-- | libdwarf/ChangeLog | 4 | ||||
-rw-r--r-- | libdwarf/libdwarf.h | 2 | ||||
-rw-r--r-- | src/readelf.c | 11 |
20 files changed, 184 insertions, 56 deletions
diff --git a/config/elfutils.spec.in b/config/elfutils.spec.in index 5c5fc540..380e5c5a 100644 --- a/config/elfutils.spec.in +++ b/config/elfutils.spec.in @@ -8,7 +8,7 @@ Group: Development/Tools Source: elfutils-%{version}.tar.gz Obsoletes: libelf libelf-devel Requires: elfutils-libelf = %{version}-%{release} -Requires: glibc >= 2.7 +Requires: glibc >= 2.3.1-2 # ExcludeArch: xxx diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 3b416242..004e0fa1 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,49 @@ +2008-01-17 Nick Clifton <nickc@redhat.com> + + * dwarf.h (DWARF3_LENGTH_MIN_ESCAPE_CODE): New define. + (DWARF3_LENGTH_MAX_ESCAPE_CODE): New define. + (DWARF3_LENGTH_64_BIT): New define. + * dwarf_getaranges (dwarf_getaranges): Use the new definitions. + * dwarf_getpubnames: Include dwarf.h. + (get_offsets): Use the new definitions. + * dwarf_getsrclines.c (dwarf_getsrclines): Use the new defintions. + * dwarf_nextcu.c: Include dwarf.h. Correct comment. + (dwarf_nextcu): Use the new definitions. + + * libdwP.h (DIE_OFFSET_FROM_CU_OFFSET): New macro. + * dwarf_die.c (dwarf_diecu): Use the new macro. + * dwarf_getaranges (dwarf_getaranges): Use the new macro. + * dwarf_nextcu.c (dwarf_nextcu): Use the new macro. + + * dwarf_getpubnames (get_offsets): Replace assertion with test and + error return. + + * dwarf_entry_breakpoints.c (dwarf_entry_breakpoints): Use CUDIE. + + * dwarf_siblingof (dwarf_siblingof): Detect a NULL return pointer. + Set the address in the return structure to the address of the next + non-sibling die, if there is no sibling and the return pointer is + not the same as the die pointer. + * libdw.h: Expand the description of the dwarf_siblingof prototype. + + * dwarf_child.c: Fix typo in comment. + + * libdwP.h (DWARF_VERSION): Change to 3. + + * dwarf_formref.c (__libdw_formref.c): Handle attributes which do + not have a initialised valp pointer. + + * dwarf_getattrs.c (dwarf_getattrs): Return 1 rather than 0 when + the end of the attributes is reached. When the callback fails, + return the address of the failing attribute, not the address of + its successor. + * libdw.h: Expand the description of the dwarf_getattrs prototype. + + * dwarf_child.c (__libdw_find_attr): Use the new definition. + (dwarf_child): Likewise. + * dwarf_tag.c (__libdw_findabbrev): Likewise. + (dwarf_tag): Likewise. + 2008-01-08 Roland McGrath <roland@redhat.com> * Makefile.am (euinclude): Variable removed. diff --git a/libdw/dwarf.h b/libdw/dwarf.h index 4b763ffa..f760b9d5 100644 --- a/libdw/dwarf.h +++ b/libdw/dwarf.h @@ -672,4 +672,19 @@ enum /* DWARF XXX. */ #define DW_ADDR_none 0 +/* Section 7.2.2 of the DWARF3 specification defines a range of escape + codes that can appear in the length field of certain DWARF structures. + + These defines enumerate the minium and maximum values of this range. + Currently only the maximum value is used (to indicate that 64-bit + values are going to be used in the dwarf data that accompanies the + structure). The other values are reserved. + + Note: There is a typo in DWARF3 spec (published Dec 20, 2005). In + sections 7.4, 7.5.1, 7.19, 7.20 the minimum escape code is referred to + as 0xffffff00 whereas in fact it should be 0xfffffff0. */ +#define DWARF3_LENGTH_MIN_ESCAPE_CODE 0xfffffff0u +#define DWARF3_LENGTH_MAX_ESCAPE_CODE 0xffffffffu +#define DWARF3_LENGTH_64_BIT DWARF3_LENGTH_MAX_ESCAPE_CODE + #endif /* dwarf.h */ diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c index b22b010e..bbc75075 100644 --- a/libdw/dwarf_child.c +++ b/libdw/dwarf_child.c @@ -1,4 +1,4 @@ -/* Return vhild of current DIE. +/* Return child of current DIE. Copyright (C) 2003, 2004, 2005, 2006, 2007 Red Hat, Inc. This file is part of Red Hat elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -77,9 +77,9 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name, if (abbrevp == NULL) { abbrevp = __libdw_findabbrev (die->cu, abbrev_code); - die->abbrev = abbrevp ?: (Dwarf_Abbrev *) -1l; + die->abbrev = abbrevp ?: DWARF_END_ABBREV; } - if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l)) + if (unlikely (die->abbrev == DWARF_END_ABBREV)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return NULL; @@ -163,7 +163,7 @@ dwarf_child (die, result) void *addr = NULL; /* If we already know there are no children do not search. */ - if (die->abbrev != (Dwarf_Abbrev *) -1 + if (die->abbrev != DWARF_END_ABBREV && (die->abbrev == NULL || die->abbrev->has_children)) addr = __libdw_find_attr (die, INVALID, NULL, NULL); if (die->abbrev == (Dwarf_Abbrev *) -1l) diff --git a/libdw/dwarf_diecu.c b/libdw/dwarf_diecu.c index 0724ee06..963c7d06 100644 --- a/libdw/dwarf_diecu.c +++ b/libdw/dwarf_diecu.c @@ -70,7 +70,7 @@ dwarf_diecu (die, result, address_sizep, offset_sizep) memset (result, '\0', sizeof (Dwarf_Die)); result->addr = ((char *) die->cu->dbg->sectiondata[IDX_debug_info]->d_buf - + die->cu->start + 3 * die->cu->offset_size - 4 + 3); + + DIE_OFFSET_FROM_CU_OFFSET (die->cu->start, die->cu->offset_size)); result->cu = die->cu; if (address_sizep != NULL) diff --git a/libdw/dwarf_entry_breakpoints.c b/libdw/dwarf_entry_breakpoints.c index e568bc99..d4966e95 100644 --- a/libdw/dwarf_entry_breakpoints.c +++ b/libdw/dwarf_entry_breakpoints.c @@ -87,12 +87,7 @@ dwarf_entry_breakpoints (die, bkpts) } /* Fetch the CU's line records to look for this DIE's addresses. */ - Dwarf_Die cudie = - { - .cu = die->cu, - .addr = ((char *) die->cu->dbg->sectiondata[IDX_debug_info]->d_buf - + die->cu->start + 3 * die->cu->offset_size - 4 + 3), - }; + Dwarf_Die cudie = CUDIE (die->cu); Dwarf_Lines *lines; size_t nlines; if (INTUSE(dwarf_getsrclines) (&cudie, &lines, &nlines) < 0) diff --git a/libdw/dwarf_formref.c b/libdw/dwarf_formref.c index 7c4fb71a..9d472df8 100644 --- a/libdw/dwarf_formref.c +++ b/libdw/dwarf_formref.c @@ -62,6 +62,12 @@ __libdw_formref (attr, return_offset) { const unsigned char *datap; + if (attr->valp == NULL) + { + __libdw_seterrno (DWARF_E_INVALID_REFERENCE); + return -1; + } + switch (attr->form) { case DW_FORM_ref1: diff --git a/libdw/dwarf_getaranges.c b/libdw/dwarf_getaranges.c index d2294ea3..b6c19425 100644 --- a/libdw/dwarf_getaranges.c +++ b/libdw/dwarf_getaranges.c @@ -55,7 +55,7 @@ #include <stdlib.h> #include <assert.h> #include "libdwP.h" - +#include <dwarf.h> struct arangelist { @@ -131,11 +131,14 @@ dwarf_getaranges (dbg, aranges, naranges) a segment descriptor on the target system. */ Dwarf_Word length = read_4ubyte_unaligned_inc (dbg, readp); unsigned int length_bytes = 4; - if (length == 0xffffffff) + if (length == DWARF3_LENGTH_64_BIT) { length = read_8ubyte_unaligned_inc (dbg, readp); length_bytes = 8; } + else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + goto invalid; unsigned int version = read_2ubyte_unaligned_inc (dbg, readp); if (version != 2) @@ -197,11 +200,11 @@ dwarf_getaranges (dbg, aranges, naranges) const char *cu_header = (dbg->sectiondata[IDX_debug_info]->d_buf + offset); unsigned int offset_size; - if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff) + if (read_4ubyte_unaligned_noncvt (cu_header) == DWARF3_LENGTH_64_BIT) offset_size = 8; else offset_size = 4; - new_arange->arange.offset = offset + 3 * offset_size - 4 + 3; + new_arange->arange.offset = DIE_OFFSET_FROM_CU_OFFSET (offset, offset_size); /* Sanity-check the data. */ if (new_arange->arange.offset diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c index ebf0869c..876475e6 100644 --- a/libdw/dwarf_getattrs.c +++ b/libdw/dwarf_getattrs.c @@ -72,7 +72,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), /* Find the abbreviation. */ die->abbrev = __libdw_findabbrev (die->cu, u128); - if (die->abbrev == (Dwarf_Abbrev *) -1l) + if (die->abbrev == DWARF_END_ABBREV) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return -1l; @@ -96,13 +96,19 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), /* Get attribute name and form. */ Dwarf_Attribute attr; + const unsigned char * remembered_attrp = attrp; + // XXX Fix bound checks get_uleb128 (attr.code, attrp); get_uleb128 (attr.form, attrp); /* We can stop if we found the attribute with value zero. */ if (attr.code == 0 && attr.form == 0) - return 0; + /* Do not return 0 here - there would be no way to + distinguish this value from the attribute at offset 0. + Instead we return +1 which would never be a valid + offset of an attribute. */ + return 1l; /* Fill in the rest. */ attr.valp = (unsigned char *) die_addr; @@ -110,7 +116,10 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), /* Now call the callback function. */ if (callback (&attr, arg) != DWARF_CB_OK) - return attrp - die->abbrev->attrp; + /* Return the offset of the start of the attribute, so that + dwarf_getattrs() can be restarted from this point if the + caller so desires. */ + return remembered_attrp - die->abbrev->attrp; /* Skip over the rest of this attribute (if there is any). */ if (attr.form != 0) diff --git a/libdw/dwarf_getpubnames.c b/libdw/dwarf_getpubnames.c index 6d07a3b7..91dad311 100644 --- a/libdw/dwarf_getpubnames.c +++ b/libdw/dwarf_getpubnames.c @@ -58,6 +58,7 @@ #include <sys/param.h> #include <libdwP.h> +#include <dwarf.h> static int @@ -93,11 +94,17 @@ get_offsets (Dwarf *dbg) /* Read the set header. */ int len_bytes = 4; Dwarf_Off len = read_4ubyte_unaligned_inc (dbg, readp); - if (len == 0xffffffff) + if (len == DWARF3_LENGTH_64_BIT) { len = read_8ubyte_unaligned_inc (dbg, readp); len_bytes = 8; } + else if (unlikely (len >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && len <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + goto err_return; + } /* Now we know the offset of the first offset/name pair. */ mem[cnt].set_start = readp + 2 + 2 * len_bytes - startp; @@ -122,14 +129,17 @@ get_offsets (Dwarf *dbg) mem[cnt].cu_offset = read_8ubyte_unaligned (dbg, readp + 2); /* Determine the size of the CU header. */ - assert (dbg->sectiondata[IDX_debug_info] != NULL); - assert (dbg->sectiondata[IDX_debug_info]->d_buf != NULL); - assert (mem[cnt].cu_offset + 3 - < dbg->sectiondata[IDX_debug_info]->d_size); + if (dbg->sectiondata[IDX_debug_info] == NULL + || dbg->sectiondata[IDX_debug_info]->d_buf == NULL + || mem[cnt].cu_offset + 3 >= dbg->sectiondata[IDX_debug_info]->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + goto err_return; + } unsigned char *infop = ((unsigned char *) dbg->sectiondata[IDX_debug_info]->d_buf + mem[cnt].cu_offset); - if (read_4ubyte_unaligned_noncvt (infop) == 0xffffffff) + if (read_4ubyte_unaligned_noncvt (infop) == DWARF3_LENGTH_64_BIT) mem[cnt].cu_header_size = 23; else mem[cnt].cu_header_size = 11; diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 666cca22..e4ec267f 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -164,7 +164,7 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) } Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); unsigned int length = 4; - if (unlikely (unit_length == 0xffffffff)) + if (unlikely (unit_length == DWARF3_LENGTH_64_BIT)) { if (unlikely (linep + 8 > lineendp)) goto invalid_data; diff --git a/libdw/dwarf_haschildren.c b/libdw/dwarf_haschildren.c index 7b21f690..fe431955 100644 --- a/libdw/dwarf_haschildren.c +++ b/libdw/dwarf_haschildren.c @@ -62,7 +62,7 @@ dwarf_haschildren (die) { /* Find the abbreviation entry. */ Dwarf_Abbrev *abbrevp = die->abbrev; - if (abbrevp != (Dwarf_Abbrev *) -1l) + if (abbrevp != DWARF_END_ABBREV) { const unsigned char *readp = (unsigned char *) die->addr; @@ -72,9 +72,9 @@ dwarf_haschildren (die) get_uleb128 (abbrev_code, readp); abbrevp = __libdw_findabbrev (die->cu, abbrev_code); - die->abbrev = abbrevp ?: (Dwarf_Abbrev *) -1l; + die->abbrev = abbrevp ?: DWARF_END_ABBREV; } - if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l)) + if (unlikely (die->abbrev == DWARF_END_ABBREV)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return 0; diff --git a/libdw/dwarf_nextcu.c b/libdw/dwarf_nextcu.c index 30743022..3927c41e 100644 --- a/libdw/dwarf_nextcu.c +++ b/libdw/dwarf_nextcu.c @@ -53,6 +53,7 @@ #endif #include <libdwP.h> +#include <dwarf.h> int @@ -91,9 +92,9 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp, of the .debug_info contribution for that compilation unit, not including the length field itself. In the 32-bit DWARF format, this is a 4-byte unsigned integer (which must be less than - 0xffffff00); in the 64-bit DWARF format, this consists of the + 0xfffffff0); in the 64-bit DWARF format, this consists of the 4-byte value 0xffffffff followed by an 8-byte unsigned integer - that gives the actual length (see Section 7.4). + that gives the actual length (see Section 7.2.2). 2. A 2-byte unsigned integer representing the version of the DWARF information for that compilation unit. For DWARF Version @@ -112,22 +113,27 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp, offset portion of an address. */ uint64_t length = read_4ubyte_unaligned_inc (dwarf, bytes); size_t offset_size = 4; - if (length == 0xffffffffu) + /* Lengths of 0xfffffff0 - 0xffffffff are escape codes. Oxffffffff is + used to indicate that 64-bit dwarf information is being used, the + other values are currently reserved. */ + if (length == DWARF3_LENGTH_64_BIT) offset_size = 8; + else if (unlikely (length >= DWARF3_LENGTH_MIN_ESCAPE_CODE + && length <= DWARF3_LENGTH_MAX_ESCAPE_CODE)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } - /* Now we know how large the header is. Note the trick in the - computation. If the offset_size is 4 the '- 4' term undoes the - '2 *'. If offset_size is 8 this term computes the size of the - escape value plus the 8 byte offset. */ - if (unlikely (off + 2 * offset_size - 4 + sizeof (uint16_t) - + offset_size + sizeof (uint8_t) + /* Now we know how large the header is. */ + if (unlikely (DIE_OFFSET_FROM_CU_OFFSET (off, offset_size) >= dwarf->sectiondata[IDX_debug_info]->d_size)) { *next_off = -1; return 1; } - if (length == 0xffffffffu) + if (length == DWARF3_LENGTH_64_BIT) /* This is a 64-bit DWARF format. */ length = read_8ubyte_unaligned_inc (dwarf, bytes); @@ -160,7 +166,8 @@ dwarf_nextcu (dwarf, off, next_off, header_sizep, abbrev_offsetp, - ((char *) dwarf->sectiondata[IDX_debug_info]->d_buf + off)); - /* See above for an explanation of the trick in this formula. */ + /* See definition of DIE_OFFSET_FROM_CU_OFFSET macro + for an explanation of the trick in this expression. */ *next_off = off + 2 * offset_size - 4 + length; return 0; diff --git a/libdw/dwarf_siblingof.c b/libdw/dwarf_siblingof.c index a6cca394..ac9d2877 100644 --- a/libdw/dwarf_siblingof.c +++ b/libdw/dwarf_siblingof.c @@ -56,7 +56,6 @@ #include <dwarf.h> #include <string.h> - int dwarf_siblingof (die, result) Dwarf_Die *die; @@ -66,6 +65,12 @@ dwarf_siblingof (die, result) if (die == NULL) return -1; + if (result == NULL) + return -1; + + if (result != die) + result->addr = NULL; + unsigned int level = 0; /* Copy of the current DIE. */ @@ -102,13 +107,12 @@ dwarf_siblingof (die, result) + sibattr.cu->start + offset); } else if (unlikely (addr == NULL) - || unlikely (this_die.abbrev == (Dwarf_Abbrev *) -1l)) + || unlikely (this_die.abbrev == DWARF_END_ABBREV)) return -1; else if (this_die.abbrev->has_children) /* This abbreviation has children. */ ++level; - while (1) { /* Make sure we are still in range. Some producers might skip @@ -120,8 +124,12 @@ dwarf_siblingof (die, result) break; if (level-- == 0) - /* No more sibling at all. */ - return 1; + { + if (result != die) + result->addr = addr; + /* No more sibling at all. */ + return 1; + } ++addr; } diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c index 05222821..7fcd89ca 100644 --- a/libdw/dwarf_tag.c +++ b/libdw/dwarf_tag.c @@ -76,8 +76,7 @@ __libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code) { /* Make sure we do not try to search for it again. */ cu->last_abbrev_offset = (size_t) -1l; - abb = (void *) -1l; - break; + return DWARF_END_ABBREV; } cu->last_abbrev_offset += length; @@ -107,7 +106,7 @@ dwarf_tag (die) die->abbrev = __libdw_findabbrev (die->cu, u128); } - if (die->abbrev == (Dwarf_Abbrev *) -1l) + if (die->abbrev == DWARF_END_ABBREV) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return DW_TAG_invalid; diff --git a/libdw/libdw.h b/libdw/libdw.h index 6242d04f..4720739a 100644 --- a/libdw/libdw.h +++ b/libdw/libdw.h @@ -252,14 +252,24 @@ extern Dwarf_Die *dwarf_addrdie (Dwarf *dbg, Dwarf_Addr addr, extern int dwarf_child (Dwarf_Die *die, Dwarf_Die *result) __nonnull_attribute__ (2); -/* Return sibling of given DIE. */ +/* Locates the first sibling of DIE and places it in RESULT. + Returns 0 if a sibling was found, -1 if something went wrong. + Returns 1 if no sibling could be found and, if RESULT is not + the same as DIE, it sets RESULT->addr to the address of the + (non-sibling) DIE that follows this one, or NULL if this DIE + was the last one in the cokmpilation unit. */ extern int dwarf_siblingof (Dwarf_Die *die, Dwarf_Die *result) __nonnull_attribute__ (2); /* Check whether the DIE has children. */ extern int dwarf_haschildren (Dwarf_Die *die) __nonnull_attribute__ (1); -/* Get attributes of the DIE. */ +/* Walks the attributes of DIE, starting at the one OFFSET bytes in, + calling the CALLBACK function for each one. Stops if the callback + function ever returns a value other than DWARF_CB_OK and returns the + offset of the offending attribute. If the end of the attributes + is reached 1 is returned. If something goes wrong -1 is returned and + the dwarf error number is set. */ extern ptrdiff_t dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), void *arg, ptrdiff_t offset) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 78fd5ce7..2277f39c 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -62,7 +62,7 @@ /* Version of the DWARF specification we support. */ -#define DWARF_VERSION 2 +#define DWARF_VERSION 3 /* Version of the CIE format. */ #define CIE_VERSION 1 @@ -286,6 +286,19 @@ struct Dwarf_CU void *locs; }; +/* Compute the offset of a CU's first DIE from its offset. This + is either: + LEN VER OFFSET ADDR + 4-bytes + 2-bytes + 4-bytes + 1-byte for 32-bit dwarf + 12-bytes + 2-bytes + 8-bytes + 1-byte for 64-bit dwarf + + Note the trick in the computation. If the offset_size is 4 + the '- 4' term changes the '3 *' into a '2 *'. If the + offset_size is 8 it accounts for the 4-byte escape value + used at the start of the length. */ +#define DIE_OFFSET_FROM_CU_OFFSET(cu_offset, offset_size) \ + ((cu_offset) + 3 * (offset_size) - 4 + 3) + #define CUDIE(fromcu) \ ((Dwarf_Die) \ { \ diff --git a/libdwarf/ChangeLog b/libdwarf/ChangeLog index c46ffcb6..4c63735e 100644 --- a/libdwarf/ChangeLog +++ b/libdwarf/ChangeLog @@ -1,3 +1,7 @@ +2008-01-17 Nick Clifton <nickc@redhat.com> + + * libdwarf.h: Fix typo in comment. + 2003-08-11 Ulrich Drepper <drepper@redhat.com> * Moved to CVS archive. diff --git a/libdwarf/libdwarf.h b/libdwarf/libdwarf.h index 284b8a38..2a2b9e3e 100644 --- a/libdwarf/libdwarf.h +++ b/libdwarf/libdwarf.h @@ -134,7 +134,7 @@ extern int dwarf_init (int fd, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, Dwarf_Debug *dbg, Dwarf_Error *errdesc); -/* Similar to `dwarf_init' but instead of a file descriptor of ELF +/* Similar to `dwarf_init' but instead of a file descriptor an ELF descriptor is passed. */ extern int dwarf_elf_init (Elf *elf, Dwarf_Unsigned access, Dwarf_Handler errhand, Dwarf_Ptr errarg, diff --git a/src/readelf.c b/src/readelf.c index d65f8103..f243f626 100644 --- a/src/readelf.c +++ b/src/readelf.c @@ -4041,7 +4041,8 @@ attr_callback (Dwarf_Attribute *attrp, void *arg) if (unlikely (dwarf_formaddr (attrp, &addr) != 0)) { attrval_out: - error (0, 0, gettext ("cannot get attribute value: %s"), + error (0, 0, gettext ("offset: %" PRIx64 " cannot get attribute value: %s"), + attrp->valp - (unsigned char *) attrp->cu->dbg->sectiondata[IDX_debug_info]->d_buf, dwarf_errmsg (-1)); return DWARF_CB_ABORT; } @@ -4285,7 +4286,7 @@ print_debug_info_section (Dwfl_Module *dwflmod, int tag = dwarf_tag (&dies[level]); if (unlikely (tag == DW_TAG_invalid)) { - error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIu64 + error (0, 0, gettext ("cannot get tag of DIE at offset %" PRIx64 " in section '%s': %s"), (uint64_t) offset, ".debug_info", dwarf_errmsg (-1)); goto do_return; @@ -4309,8 +4310,10 @@ print_debug_info_section (Dwfl_Module *dwflmod, if (res > 0) { while ((res = dwarf_siblingof (&dies[level], &dies[level])) == 1) - if (level-- == 0) - break; + { + if (level-- == 0) + break; + } if (unlikely (res == -1)) { |