diff options
| author | Mark Wielaard <[email protected]> | 2013-10-10 11:40:12 +0200 |
|---|---|---|
| committer | Mark Wielaard <[email protected]> | 2013-10-22 13:59:23 +0200 |
| commit | e6a9bb8c63adaeaceafc50301b085121c962b631 (patch) | |
| tree | 569d2939a228f29fa48b6b8bc66bde1c29014a3a /libdw/dwarf_getfuncs.c | |
| parent | d182974079c7205973ae7885b95216a5b83b6f82 (diff) | |
libdw: Handle dwz multi files correctly in dwarf_getfuncs.
Don't use DIE offsets, but use their addresses to make sure they are unique.
Include test cases where main and alt file have subprograms at same offsets.
Reported-by: Josh Stone <[email protected]>
Signed-off-by: Mark Wielaard <[email protected]>
Diffstat (limited to 'libdw/dwarf_getfuncs.c')
| -rw-r--r-- | libdw/dwarf_getfuncs.c | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/libdw/dwarf_getfuncs.c b/libdw/dwarf_getfuncs.c index 87e0341a..82894c98 100644 --- a/libdw/dwarf_getfuncs.c +++ b/libdw/dwarf_getfuncs.c @@ -43,11 +43,11 @@ struct visitor_info /* The user arg value to dwarf_getfuncs. */ void *arg; - /* The DIE offset where to (re)start the search. Zero for all. */ - Dwarf_Off start_offset; + /* Addr of the DIE offset where to (re)start the search. Zero for all. */ + void *start_addr; - /* Last subprogram DIE offset seen. */ - Dwarf_Off last_offset; + /* Last subprogram DIE addr seen. */ + void *last_addr; /* The CU only contains C functions. Allows pruning of most subtrees. */ bool c_cu; @@ -59,8 +59,8 @@ tree_visitor (unsigned int depth __attribute__ ((unused)), { struct visitor_info *const v = arg; Dwarf_Die *die = &chain->die; - Dwarf_Off start_offset = v->start_offset; - Dwarf_Off die_offset = INTUSE(dwarf_dieoffset) (die); + void *start_addr = v->start_addr; + void *die_addr = die->addr; /* Pure C CUs can only contain defining subprogram DIEs as direct children of the CU DIE or as nested function inside a normal C @@ -75,11 +75,11 @@ tree_visitor (unsigned int depth __attribute__ ((unused)), return DWARF_CB_OK; } - /* Skip all DIEs till we found the (re)start offset. */ - if (start_offset != 0) + /* Skip all DIEs till we found the (re)start addr. */ + if (start_addr != NULL) { - if (die_offset == start_offset) - v->start_offset = 0; + if (die_addr == start_addr) + v->start_addr = NULL; return DWARF_CB_OK; } @@ -88,7 +88,7 @@ tree_visitor (unsigned int depth __attribute__ ((unused)), || INTUSE(dwarf_hasattr) (die, DW_AT_declaration)) return DWARF_CB_OK; - v->last_offset = die_offset; + v->last_addr = die_addr; return (*v->callback) (die, v->arg); } @@ -105,13 +105,13 @@ dwarf_getfuncs (Dwarf_Die *cudie, int (*callback) (Dwarf_Die *, void *), || lang == DW_LANG_C || lang == DW_LANG_C99); - struct visitor_info v = { callback, arg, offset, 0, c_cu }; + struct visitor_info v = { callback, arg, (void *) offset, NULL, c_cu }; struct Dwarf_Die_Chain chain = { .die = CUDIE (cudie->cu), .parent = NULL }; int res = __libdw_visit_scopes (0, &chain, &tree_visitor, NULL, &v); if (res == DWARF_CB_ABORT) - return v.last_offset; + return (ptrdiff_t) v.last_addr; else return res; } |
