diff options
author | Mark Wielaard <mjw@redhat.com> | 2013-12-16 13:28:59 +0100 |
---|---|---|
committer | Mark Wielaard <mjw@redhat.com> | 2013-12-16 15:27:27 +0100 |
commit | 14c2d9e614cb0e3fd50ad757eaba686b37699580 (patch) | |
tree | 039e7c4b73d00403f66b642e4bfbc43dd2117330 /libdwfl | |
parent | e6e6cc83ea27413facb310ce48bebb1579a47130 (diff) | |
download | elfutils-14c2d9e614cb0e3fd50ad757eaba686b37699580.tar.gz |
libdwfl: Add dwfl_module_getsymtab_first_global.
New function that provides the index after the last non-local symbol as
returned by dwfl_module_getsym and dwfl_module_getsym_info. Allows users to
first search through all global symbols before searching the local symbols
in the table like dwfl_module_addrsym and dwfl_module_addrsym_info do as
optimization.
Signed-off-by: Mark Wielaard <mjw@redhat.com>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 10 | ||||
-rw-r--r-- | libdwfl/dwfl_module_addrsym.c | 6 | ||||
-rw-r--r-- | libdwfl/dwfl_module_getdwarf.c | 23 | ||||
-rw-r--r-- | libdwfl/libdwfl.h | 7 | ||||
-rw-r--r-- | libdwfl/libdwflP.h | 1 |
5 files changed, 44 insertions, 3 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index a9238d80..67f1fcff 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog @@ -1,3 +1,13 @@ +2013-12-16 Mark Wielaard <mjw@redhat.com> + + * libdwfl.h (dwfl_module_getsymtab_first_global): New function + definition. + * dwfl_module_getdwarf.c (dwfl_module_getsymtab_first_global): New + function. + * libdwflP.h (dwfl_module_getsymtab_first_global): New internal + function definition. + * dwfl_module_addrsym.c (dwfl_module_addrsym_elf): Use new function. + 2013-12-14 Mark Wielaard <mjw@redhat.com> * dwfl_module.c (__libdwfl_module_free): Free mod->reloc_info if diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c index 320d41f1..9e4f0674 100644 --- a/libdwfl/dwfl_module_addrsym.c +++ b/libdwfl/dwfl_module_addrsym.c @@ -188,9 +188,9 @@ dwfl_module_addrsym_elf (Dwfl_Module *mod, GElf_Addr addr, come first in the symbol table, then all globals. The zeroth, null entry, in the auxiliary table is skipped if there is a main table. */ - int first_global = mod->first_global + mod->aux_first_global; - if (mod->syments > 0 && mod->aux_syments > 0) - first_global--; + int first_global = INTUSE (dwfl_module_getsymtab_first_global) (mod); + if (first_global < 0) + return NULL; search_table (first_global == 0 ? 1 : first_global, syments); /* If we found nothing searching the global symbols, then try the locals. diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c index dd76f257..c4bd7395 100644 --- a/libdwfl/dwfl_module_getdwarf.c +++ b/libdwfl/dwfl_module_getdwarf.c @@ -1266,3 +1266,26 @@ dwfl_module_getsymtab (Dwfl_Module *mod) return -1; } INTDEF (dwfl_module_getsymtab) + +int +dwfl_module_getsymtab_first_global (Dwfl_Module *mod) +{ + if (mod == NULL) + return -1; + + find_symtab (mod); + if (mod->symerr == DWFL_E_NOERROR) + { + /* All local symbols should come before all global symbols. If + we have an auxiliary table make sure all the main locals come + first, then all aux locals, then all main globals and finally all + aux globals. And skip the auxiliary table zero undefined + entry. */ + int skip_aux_zero = (mod->syments > 0 && mod->aux_syments > 0) ? 1 : 0; + return mod->first_global + mod->aux_first_global - skip_aux_zero; + } + + __libdwfl_seterrno (mod->symerr); + return -1; +} +INTDEF (dwfl_module_getsymtab_first_global) diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h index 3d5bede6..60160b6a 100644 --- a/libdwfl/libdwfl.h +++ b/libdwfl/libdwfl.h @@ -430,6 +430,13 @@ extern Elf *dwfl_module_getelf (Dwfl_Module *, GElf_Addr *bias) or -1 for errors. */ extern int dwfl_module_getsymtab (Dwfl_Module *mod); +/* Return the index of the first global symbol in the module's symbol + table, or -1 for errors. In each symbol table, all symbols with + STB_LOCAL binding precede the weak and global symbols. This + function returns the symbol table index one greater than the last + local symbol. */ +extern int dwfl_module_getsymtab_first_global (Dwfl_Module *mod); + /* Fetch one entry from the module's symbol table. On errors, returns NULL. If successful, fills in *SYM and returns the string for st_name. This works like gelf_getsym except that st_value is always adjusted to diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index ba1c758d..e2e249de 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -646,6 +646,7 @@ INTDECL (dwfl_module_getelf) INTDECL (dwfl_module_getsym) INTDECL (dwfl_module_getsym_elf) INTDECL (dwfl_module_getsymtab) +INTDECL (dwfl_module_getsymtab_first_global) INTDECL (dwfl_module_getsrc) INTDECL (dwfl_module_report_build_id) INTDECL (dwfl_report_elf) |