diff options
author | Roland McGrath <roland@redhat.com> | 2010-06-15 23:10:35 -0700 |
---|---|---|
committer | Roland McGrath <roland@redhat.com> | 2010-06-16 12:11:03 -0700 |
commit | 3e0f7d1d1b817040cef82f41879f471ab59b663e (patch) | |
tree | 42999dc59b7bab5c0524f15a7f928cb2905f49d5 /libdw/libdw_findcu.c | |
parent | 3e4b5bbeca8987527c11a1ea048459a7ebd4ab5e (diff) | |
download | elfutils-3e0f7d1d1b817040cef82f41879f471ab59b663e.tar.gz |
Handle reading .debug_types section.
Diffstat (limited to 'libdw/libdw_findcu.c')
-rw-r--r-- | libdw/libdw_findcu.c | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/libdw/libdw_findcu.c b/libdw/libdw_findcu.c index cf79c639..7e0b3568 100644 --- a/libdw/libdw_findcu.c +++ b/libdw/libdw_findcu.c @@ -57,6 +57,58 @@ #include "libdwP.h" +struct Dwarf_CU * +internal_function +__libdw_intern_next_unit (dbg, debug_types) + Dwarf *dbg; + bool debug_types; +{ + Dwarf_Off *const offsetp + = debug_types ? &dbg->next_tu_offset : &dbg->next_cu_offset; + + Dwarf_Off oldoff = *offsetp; + uint16_t version; + uint8_t address_size; + uint8_t offset_size; + Dwarf_Off abbrev_offset; + uint64_t type_sig8 = 0; + Dwarf_Off type_offset = 0; + + if (INTUSE(dwarf_next_unit) (dbg, oldoff, offsetp, NULL, + &version, &abbrev_offset, + &address_size, &offset_size, + debug_types ? &type_sig8 : NULL, + debug_types ? &type_offset : NULL) != 0) + /* No more entries. */ + return NULL; + + /* We only know how to handle the DWARF version 2 through 4 formats. */ + if (unlikely (version < 2) || unlikely (version > 4)) + { + __libdw_seterrno (DWARF_E_INVALID_DWARF); + return NULL; + } + + /* Create an entry for this CU. */ + struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU); + + newp->dbg = dbg; + newp->start = oldoff; + newp->end = *offsetp; + newp->address_size = address_size; + newp->offset_size = offset_size; + newp->version = version; + newp->type_sig8 = type_sig8; + newp->type_offset = type_offset; + Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41); + newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; + newp->lines = NULL; + newp->locs = NULL; + + return newp; +} + + static int findcu_cb (const void *arg1, const void *arg2) { @@ -83,7 +135,6 @@ findcu_cb (const void *arg1, const void *arg2) return 0; } - struct Dwarf_CU * __libdw_findcu (dbg, start) Dwarf *dbg; @@ -97,7 +148,6 @@ __libdw_findcu (dbg, start) if (start < dbg->next_cu_offset) { - invalid: __libdw_seterrno (DWARF_E_INVALID_DWARF); return NULL; } @@ -106,43 +156,14 @@ __libdw_findcu (dbg, start) while (1) { Dwarf_Off oldoff = dbg->next_cu_offset; - uint8_t address_size; - uint8_t offset_size; - Dwarf_Off abbrev_offset; - - if (INTUSE(dwarf_nextcu) (dbg, oldoff, &dbg->next_cu_offset, NULL, - &abbrev_offset, &address_size, &offset_size) - != 0) - /* No more entries. */ + struct Dwarf_CU *newp = __libdw_intern_next_unit (dbg, false); + if (newp == NULL) return NULL; - /* XXX We need the version number but dwarf_nextcu swallows it. */ - const char *bytes = (dbg->sectiondata[IDX_debug_info]->d_buf + oldoff - + (2 * offset_size - 4)); - uint16_t version = read_2ubyte_unaligned (dbg, bytes); - - /* We only know how to handle the DWARF version 2 through 4 formats. */ - if (unlikely (version < 2) || unlikely (version > 4)) - goto invalid; - - /* Create an entry for this CU. */ - struct Dwarf_CU *newp = libdw_typed_alloc (dbg, struct Dwarf_CU); - - newp->dbg = dbg; - newp->start = oldoff; - newp->end = dbg->next_cu_offset; - newp->address_size = address_size; - newp->offset_size = offset_size; - newp->version = version; - Dwarf_Abbrev_Hash_init (&newp->abbrev_hash, 41); - newp->orig_abbrev_offset = newp->last_abbrev_offset = abbrev_offset; - newp->lines = NULL; - newp->locs = NULL; - /* Add the new entry to the search tree. */ if (tsearch (newp, &dbg->cu_tree, findcu_cb) == NULL) { - /* Something went wrong. Unfo the operation. */ + /* Something went wrong. Undo the operation. */ dbg->next_cu_offset = oldoff; __libdw_seterrno (DWARF_E_NOMEM); return NULL; |