summaryrefslogtreecommitdiff
path: root/libdwfl
diff options
context:
space:
mode:
authorMark Wielaard <mjw@redhat.com>2013-12-16 13:28:59 +0100
committerMark Wielaard <mjw@redhat.com>2013-12-16 15:27:27 +0100
commit14c2d9e614cb0e3fd50ad757eaba686b37699580 (patch)
tree039e7c4b73d00403f66b642e4bfbc43dd2117330 /libdwfl
parente6e6cc83ea27413facb310ce48bebb1579a47130 (diff)
downloadelfutils-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/ChangeLog10
-rw-r--r--libdwfl/dwfl_module_addrsym.c6
-rw-r--r--libdwfl/dwfl_module_getdwarf.c23
-rw-r--r--libdwfl/libdwfl.h7
-rw-r--r--libdwfl/libdwflP.h1
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)