diff options
author | Josh Stone <jistone@redhat.com> | 2014-12-10 18:28:04 -0800 |
---|---|---|
committer | Josh Stone <jistone@redhat.com> | 2014-12-11 11:23:26 -0800 |
commit | b849f813e6753ea60784175321d4bde78c0c2ad9 (patch) | |
tree | 188555c682eb0f62537aba273dbba673f61d570a | |
parent | 2098b3d315b612d12b1425639707552e06131cde (diff) | |
download | elfutils-b849f813e6753ea60784175321d4bde78c0c2ad9.tar.gz |
libdw: unify die->abbrev lookups
Add a new internal function, __libdw_dieabbrev, which deals with checking
a die for an abbrev, and setting it as needed.
Signed-off-by: Josh Stone <jistone@redhat.com>
-rw-r--r-- | libdw/ChangeLog | 8 | ||||
-rw-r--r-- | libdw/dwarf_child.c | 42 | ||||
-rw-r--r-- | libdw/dwarf_getattrs.c | 19 | ||||
-rw-r--r-- | libdw/dwarf_haschildren.c | 20 | ||||
-rw-r--r-- | libdw/dwarf_tag.c | 20 | ||||
-rw-r--r-- | libdw/libdwP.h | 25 |
6 files changed, 64 insertions, 70 deletions
diff --git a/libdw/ChangeLog b/libdw/ChangeLog index b9b868b5..0d3150b9 100644 --- a/libdw/ChangeLog +++ b/libdw/ChangeLog @@ -1,3 +1,11 @@ +2014-12-10 Josh Stone <jistone@redhat.com> + + * libdwP.h (__libdw_dieabbrev): New die->abbrev lookup function. + * dwarf_child.c (__libdw_find_attr, dwarf_child): Use it. + * dwarf_getattrs.c (dwarf_getattrs): Likewise. + * dwarf_haschildren.c (dwarf_haschildren): Likewise. + * dwarf_tag.c (dwarf_tag): Likewise. + 2014-12-04 Mark Wielaard <mjw@redhat.com> * libdwP.h (__libdw_form_val_compute_len): Add endp argument. diff --git a/libdw/dwarf_child.c b/libdw/dwarf_child.c index fa316006..daf4c265 100644 --- a/libdw/dwarf_child.c +++ b/libdw/dwarf_child.c @@ -44,21 +44,11 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name, unsigned int *codep, unsigned int *formp) { Dwarf *dbg = die->cu->dbg; - const unsigned char *readp = (unsigned char *) die->addr; - - /* First we have to get the abbreviation code so that we can decode - the data in the DIE. */ - unsigned int abbrev_code; - get_uleb128 (abbrev_code, readp); + const unsigned char *readp; /* Find the abbreviation entry. */ - Dwarf_Abbrev *abbrevp = die->abbrev; - if (abbrevp == NULL) - { - abbrevp = __libdw_findabbrev (die->cu, abbrev_code); - die->abbrev = abbrevp ?: DWARF_END_ABBREV; - } - if (unlikely (die->abbrev == DWARF_END_ABBREV)) + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &readp); + if (unlikely (abbrevp == DWARF_END_ABBREV)) { invalid_dwarf: __libdw_seterrno (DWARF_E_INVALID_DWARF); @@ -70,7 +60,7 @@ __libdw_find_attr (Dwarf_Die *die, unsigned int search_name, = ((unsigned char *) dbg->sectiondata[IDX_debug_abbrev]->d_buf + dbg->sectiondata[IDX_debug_abbrev]->d_size); - const unsigned char *attrp = die->abbrev->attrp; + const unsigned char *attrp = abbrevp->attrp; while (1) { /* Are we still in bounds? This test needs to be refined. */ @@ -137,21 +127,21 @@ dwarf_child (die, result) if (die == NULL) return -1; - /* Skip past the last attribute. */ - void *addr = NULL; - - /* If we already know there are no children do not search. */ - if (die->abbrev != DWARF_END_ABBREV - && (die->abbrev == NULL || die->abbrev->has_children)) - addr = __libdw_find_attr (die, INVALID, NULL, NULL); - if (unlikely (die->abbrev == (Dwarf_Abbrev *) -1l)) - return -1; + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return -1; + } - /* Make sure the DIE really has children. */ - if (! die->abbrev->has_children) - /* There cannot be any children. */ + /* If there are no children, do not search. */ + if (! abbrevp->has_children) return 1; + /* Skip past the last attribute. */ + void *addr = __libdw_find_attr (die, INVALID, NULL, NULL); + if (addr == NULL) return -1; diff --git a/libdw/dwarf_getattrs.c b/libdw/dwarf_getattrs.c index 627a8511..9ea70fca 100644 --- a/libdw/dwarf_getattrs.c +++ b/libdw/dwarf_getattrs.c @@ -44,17 +44,12 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), if (unlikely (offset == 1)) return 1; - const unsigned char *die_addr = die->addr; + const unsigned char *die_addr; - /* Get the abbreviation code. */ - unsigned int u128; - get_uleb128 (u128, die_addr); + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, &die_addr); - if (die->abbrev == NULL) - /* Find the abbreviation. */ - die->abbrev = __libdw_findabbrev (die->cu, u128); - - if (unlikely (die->abbrev == DWARF_END_ABBREV)) + if (unlikely (abbrevp == DWARF_END_ABBREV)) { invalid_dwarf: __libdw_seterrno (DWARF_E_INVALID_DWARF); @@ -62,8 +57,8 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), } /* This is where the attributes start. */ - const unsigned char *attrp = die->abbrev->attrp; - const unsigned char *const offset_attrp = die->abbrev->attrp + offset; + const unsigned char *attrp = abbrevp->attrp; + const unsigned char *const offset_attrp = abbrevp->attrp + offset; /* Go over the list of attributes. */ Dwarf *dbg = die->cu->dbg; @@ -105,7 +100,7 @@ dwarf_getattrs (Dwarf_Die *die, int (*callback) (Dwarf_Attribute *, void *), /* 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; + return remembered_attrp - abbrevp->attrp; } /* Skip over the rest of this attribute (if there is any). */ diff --git a/libdw/dwarf_haschildren.c b/libdw/dwarf_haschildren.c index b2273982..d0ce51ea 100644 --- a/libdw/dwarf_haschildren.c +++ b/libdw/dwarf_haschildren.c @@ -1,5 +1,5 @@ /* Return string associated with given attribute. - Copyright (C) 2003, 2005, 2008 Red Hat, Inc. + Copyright (C) 2003, 2005, 2008, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -40,25 +40,13 @@ dwarf_haschildren (die) Dwarf_Die *die; { /* Find the abbreviation entry. */ - Dwarf_Abbrev *abbrevp = die->abbrev; - if (abbrevp != DWARF_END_ABBREV) - { - const unsigned char *readp = (unsigned char *) die->addr; - - /* First we have to get the abbreviation code so that we can decode - the data in the DIE. */ - unsigned int abbrev_code; - get_uleb128 (abbrev_code, readp); - - abbrevp = __libdw_findabbrev (die->cu, abbrev_code); - die->abbrev = abbrevp ?: DWARF_END_ABBREV; - } - if (unlikely (die->abbrev == DWARF_END_ABBREV)) + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return -1; } - return die->abbrev->has_children; + return abbrevp->has_children; } INTDEF (dwarf_haschildren) diff --git a/libdw/dwarf_tag.c b/libdw/dwarf_tag.c index ff012cf4..0b1a4b08 100644 --- a/libdw/dwarf_tag.c +++ b/libdw/dwarf_tag.c @@ -1,5 +1,5 @@ /* Return tag of given DIE. - Copyright (C) 2003-2011 Red Hat, Inc. + Copyright (C) 2003-2011, 2014 Red Hat, Inc. This file is part of elfutils. Written by Ulrich Drepper <drepper@redhat.com>, 2003. @@ -82,24 +82,14 @@ int dwarf_tag (die) Dwarf_Die *die; { - /* Do we already know the abbreviation? */ - if (die->abbrev == NULL) - { - /* Get the abbreviation code. */ - unsigned int u128; - const unsigned char *addr = die->addr; - get_uleb128 (u128, addr); - - /* Find the abbreviation. */ - die->abbrev = __libdw_findabbrev (die->cu, u128); - } - - if (unlikely (die->abbrev == DWARF_END_ABBREV)) + /* Find the abbreviation entry. */ + Dwarf_Abbrev *abbrevp = __libdw_dieabbrev (die, NULL); + if (unlikely (abbrevp == DWARF_END_ABBREV)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); return DW_TAG_invalid; } - return die->abbrev->tag; + return abbrevp->tag; } INTDEF(dwarf_tag) diff --git a/libdw/libdwP.h b/libdw/libdwP.h index 351c5b47..06338539 100644 --- a/libdw/libdwP.h +++ b/libdw/libdwP.h @@ -444,7 +444,7 @@ extern struct Dwarf_CU *__libdw_intern_next_unit (Dwarf *dbg, bool debug_types) extern struct Dwarf_CU *__libdw_findcu (Dwarf *dbg, Dwarf_Off offset, bool tu) __nonnull_attribute__ (1) internal_function; -/* Return tag of given DIE. */ +/* Get abbreviation with given code. */ extern Dwarf_Abbrev *__libdw_findabbrev (struct Dwarf_CU *cu, unsigned int code) __nonnull_attribute__ (1) internal_function; @@ -455,6 +455,29 @@ extern Dwarf_Abbrev *__libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Abbrev *result) __nonnull_attribute__ (1) internal_function; +/* Get abbreviation of given DIE, and optionally set *READP to the DIE memory + just past the abbreviation code. */ +static inline Dwarf_Abbrev * +__nonnull_attribute__ (1) +__libdw_dieabbrev (Dwarf_Die *die, const unsigned char **readp) +{ + /* Do we need to get the abbreviation, or need to read after the code? */ + if (die->abbrev == NULL || readp != NULL) + { + /* Get the abbreviation code. */ + unsigned int code; + const unsigned char *addr = die->addr; + get_uleb128 (code, addr); + if (readp != NULL) + *readp = addr; + + /* Find the abbreviation. */ + if (die->abbrev == NULL) + die->abbrev = __libdw_findabbrev (die->cu, code); + } + return die->abbrev; +} + /* Helper functions for form handling. */ extern size_t __libdw_form_val_compute_len (Dwarf *dbg, struct Dwarf_CU *cu, unsigned int form, |