summaryrefslogtreecommitdiff
path: root/libdw/libdw_findcu.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@redhat.com>2010-06-15 23:10:35 -0700
committerRoland McGrath <roland@redhat.com>2010-06-16 12:11:03 -0700
commit3e0f7d1d1b817040cef82f41879f471ab59b663e (patch)
tree42999dc59b7bab5c0524f15a7f928cb2905f49d5 /libdw/libdw_findcu.c
parent3e4b5bbeca8987527c11a1ea048459a7ebd4ab5e (diff)
downloadelfutils-3e0f7d1d1b817040cef82f41879f471ab59b663e.tar.gz
Handle reading .debug_types section.
Diffstat (limited to 'libdw/libdw_findcu.c')
-rw-r--r--libdw/libdw_findcu.c89
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;