diff options
author | Petr Machata <pmachata@redhat.com> | 2009-05-05 02:53:40 +0200 |
---|---|---|
committer | Petr Machata <pmachata@redhat.com> | 2009-05-05 02:53:40 +0200 |
commit | 8273a2adaf8cb2ee203926af2849e4f96f8a6eaf (patch) | |
tree | 8590bde46e67bb9ee2feb357b44a497b794e7d2d | |
parent | 1c897f4abde1530038d332f4fc03a596a24f6aaf (diff) | |
download | elfutils-8273a2adaf8cb2ee203926af2849e4f96f8a6eaf.tar.gz |
Introduce __libdw_read_udata_address
* the use in dwarf_ranges is iffy, there's a functionality mismatch.
Need to find some better way
-rw-r--r-- | libdw/ChangeLog | 9 | ||||
-rw-r--r-- | libdw/dwarf_formudata.c | 47 | ||||
-rw-r--r-- | libdw/dwarf_getlocation.c | 23 | ||||
-rw-r--r-- | libdw/dwarf_getsrclines.c | 19 | ||||
-rw-r--r-- | libdw/dwarf_ranges.c | 28 | ||||
-rw-r--r-- | libdw/libdwP.h | 5 |
6 files changed, 86 insertions, 45 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index 39b190f1..abea245a 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,12 @@ +2009-05-05 Petr Machata <pmachata@redhat.com> + + * libdwP.h (__libdw_read_udata_addr): Declare new function. + * dwarf_formudata.c: Implement it here. + * dwarf_getlocation.c (dwarf_getlocation_addr): + Call it instead of hand-rolled offset handling code. + * dwarf_getsrclines.c (dwarf_getsrclines): Likewise. + * dwarf_ranges.c (dwarf_ranges): Likewise. + 2009-05-04 Petr Machata <pmachata@redhat.com> * libdwP.h (__libdw_read_begin_end_pair_inc): Declare new function. diff --git a/libdw/dwarf_formudata.c b/libdw/dwarf_formudata.c index b346afb3..71a5e967 100644 --- a/libdw/dwarf_formudata.c +++ b/libdw/dwarf_formudata.c @@ -55,6 +55,45 @@ #include <dwarf.h> #include "libdwP.h" +internal_function unsigned char * +__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index, + int err_nodata, unsigned char **endpp) +{ + if (attr == NULL) + return NULL; + + Dwarf_Word offset; + switch (attr->form) + { + case DW_FORM_data4: + case DW_FORM_data8: + if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp, + attr->form == DW_FORM_data4 ? 4 : 8, + &offset)) + return NULL; + break; + + default: + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + }; + + const Elf_Data *d = attr->cu->dbg->sectiondata[sec_index]; + if (unlikely (d == NULL)) + { + invalid: + __libdw_seterrno (err_nodata); + return NULL; + } + + unsigned char *readp = d->d_buf + offset; + unsigned char *endp = d->d_buf + d->d_size; + if (readp >= endp) + goto invalid; + + *endpp = endp; + return readp; +} int dwarf_formudata (attr, return_uval) @@ -77,11 +116,11 @@ dwarf_formudata (attr, return_uval) break; case DW_FORM_data4: + *return_uval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp); + break; + case DW_FORM_data8: - if (__libdw_read_address (attr->cu->dbg, IDX_debug_info, attr->valp, - attr->form == DW_FORM_data4 ? 4 : 8, - return_uval)) - return -1; + *return_uval = read_8ubyte_unaligned (attr->cu->dbg, attr->valp); break; case DW_FORM_sdata: diff --git a/libdw/dwarf_getlocation.c b/libdw/dwarf_getlocation.c index 95ad5259..3480f3dd 100644 --- a/libdw/dwarf_getlocation.c +++ b/libdw/dwarf_getlocation.c @@ -378,25 +378,17 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs) return -1; } - /* Must have the form data4 or data8 which act as an offset. */ - Dwarf_Word offset; - if (unlikely (INTUSE(dwarf_formudata) (attr, &offset) != 0)) + unsigned char *endp, *readp + = __libdw_read_udata_addr (attr, IDX_debug_loc, + DWARF_E_NO_LOCLIST, &endp); + if (readp == NULL) return -1; - const Elf_Data *d = attr->cu->dbg->sectiondata[IDX_debug_loc]; - if (unlikely (d == NULL)) - { - __libdw_seterrno (DWARF_E_NO_LOCLIST); - return -1; - } - Dwarf_Addr base = (Dwarf_Addr) -1; - unsigned char *readp = d->d_buf + offset; size_t got = 0; while (got < maxlocs) { - if ((unsigned char *) d->d_buf + d->d_size - readp - < attr->cu->address_size * 2) + if (endp - readp < attr->cu->address_size * 2) { invalid: __libdw_seterrno (DWARF_E_INVALID_DWARF); @@ -417,14 +409,13 @@ dwarf_getlocation_addr (attr, address, llbufs, listlens, maxlocs) else if (status < 0) return status; - if ((unsigned char *) d->d_buf + d->d_size - readp < 2) + if (endp - readp < 2) goto invalid; /* We have a location expression. */ block.length = read_2ubyte_unaligned_inc (attr->cu->dbg, readp); block.data = readp; - if ((unsigned char *) d->d_buf + d->d_size - readp - < (ptrdiff_t) block.length) + if (endp - readp < (ptrdiff_t) block.length) goto invalid; readp += block.length; diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c index 67b62aac..df510e1d 100644 --- a/libdw/dwarf_getsrclines.c +++ b/libdw/dwarf_getsrclines.c @@ -135,20 +135,13 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) /* Get the offset into the .debug_line section. NB: this call also checks whether the previous dwarf_attr call failed. */ - Dwarf_Word offset; - if (INTUSE(dwarf_formudata) (stmt_list, &offset) != 0) + const unsigned char *lineendp, *linep + = __libdw_read_udata_addr (stmt_list, IDX_debug_line, + DWARF_E_NO_DEBUG_LINE, + (unsigned char **) &lineendp); + if (linep == NULL) goto out; - Dwarf *dbg = cu->dbg; - if (dbg->sectiondata[IDX_debug_line] == NULL) - { - __libdw_seterrno (DWARF_E_NO_DEBUG_LINE); - goto out; - } - const uint8_t *linep = dbg->sectiondata[IDX_debug_line]->d_buf + offset; - const uint8_t *lineendp = (dbg->sectiondata[IDX_debug_line]->d_buf - + dbg->sectiondata[IDX_debug_line]->d_size); - /* Get the compilation directory. */ Dwarf_Attribute compdir_attr_mem; Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie, @@ -162,6 +155,8 @@ dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); goto out; } + + Dwarf *dbg = cu->dbg; Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); unsigned int length = 4; if (unlikely (unit_length == DWARF3_LENGTH_64_BIT)) diff --git a/libdw/dwarf_ranges.c b/libdw/dwarf_ranges.c index ccb4f6b7..875068cb 100644 --- a/libdw/dwarf_ranges.c +++ b/libdw/dwarf_ranges.c @@ -125,11 +125,11 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, const Elf_Data *d = die->cu->dbg->sectiondata[IDX_debug_ranges]; if (d == NULL && offset != 0) { - no_ranges: __libdw_seterrno (DWARF_E_NO_DEBUG_RANGES); return -1; } + unsigned char *readp, *readendp; if (offset == 0) { Dwarf_Attribute attr_mem; @@ -139,13 +139,12 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, /* No PC attributes in this DIE at all, so an empty range list. */ return 0; - /* Must have the form data4 or data8 which act as an offset. */ - Dwarf_Word start_offset; - if (INTUSE(dwarf_formudata) (attr, &start_offset) != 0) + if ((readp = __libdw_read_udata_addr (attr, IDX_debug_ranges, + DWARF_E_NO_DEBUG_RANGES, + &readendp)) == NULL) return -1; - if (d == NULL) - goto no_ranges; + Dwarf_Word start_offset = (void *) readp - d->d_buf; offset = start_offset; assert ((Dwarf_Word) offset == start_offset); @@ -172,17 +171,20 @@ dwarf_ranges (Dwarf_Die *die, ptrdiff_t offset, Dwarf_Addr *basep, return -1; } } - else if (offset < 0 || (size_t) offset >= d->d_size) + else { - __libdw_seterrno (DWARF_E_INVALID_OFFSET); - return -1l; - } + if (offset < 0 || (size_t) offset >= d->d_size) + { + __libdw_seterrno (DWARF_E_INVALID_OFFSET); + return -1l; + } - unsigned char *readp = d->d_buf + offset; + readp = d->d_buf + offset; + readendp = d->d_buf + d->d_size; + } next: - if ((unsigned char *) d->d_buf + d->d_size - readp - < die->cu->address_size * 2) + if (readendp - readp < die->cu->address_size * 2) goto invalid; Dwarf_Addr begin; diff --git a/libdw/libdwP.h b/libdw/libdwP.h index be0b99a8..16b19c6f 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -510,6 +510,11 @@ __libdw_read_begin_end_pair_inc (Dwarf *dbg, int sec_index, Dwarf_Addr *basep) internal_function; +unsigned char * +__libdw_read_udata_addr (Dwarf_Attribute *attr, int sec_index, + int err_nodata, unsigned char **endpp) + internal_function; + static inline int __libdw_read_address (Dwarf *dbg, int sec_index, const unsigned char *addr, |