libdwfl: Add dwfl_module_getsymtab_first_global.
authorMark Wielaard <mjw@redhat.com>
Mon, 16 Dec 2013 12:28:59 +0000 (13:28 +0100)
committerMark Wielaard <mjw@redhat.com>
Mon, 16 Dec 2013 14:27:27 +0000 (15:27 +0100)
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>
ChangeLog
NEWS
libdw/ChangeLog
libdw/libdw.map
libdwfl/ChangeLog
libdwfl/dwfl_module_addrsym.c
libdwfl/dwfl_module_getdwarf.c
libdwfl/libdwfl.h
libdwfl/libdwflP.h

index c1a42ee..334c769 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-12-16  Mark Wielaard  <mjw@redhat.com>
+
+       * NEWS (libdwfl): Add dwfl_module_getsymtab_first_global.
+
 2013-12-09  Josh Stone  <jistone@redhat.com>
 
        * .gitignore: Add config/ar-lib, installed due to AM_PROG_AR.
diff --git a/NEWS b/NEWS
index 9d73f09..35f2387 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,7 @@
 Version 0.158
 
 libdwfl: dwfl_core_file_report has new parameter executable.
+         New function dwfl_module_getsymtab_first_global.
 
 Version 0.157
 
index aa7b9ca..8b1e2c0 100644 (file)
@@ -1,3 +1,7 @@
+2013-12-16  Mark Wielaard  <mjw@redhat.com>
+
+       * libdw.map (ELFUTILS_0.158): Add dwfl_module_getsymtab_first_global.
+
 2013-12-10  Josh Stone  <jistone@redhat.com>
 
        * memory-access.h (get_uleb128_rest_return): Removed.
index 0438e24..342cdfe 100644 (file)
@@ -286,4 +286,5 @@ ELFUTILS_0.158 {
 
     dwfl_module_addrsym_elf;
     dwfl_module_getsym_elf;
+    dwfl_module_getsymtab_first_global;
 } ELFUTILS_0.157;
index a9238d8..67f1fcf 100644 (file)
@@ -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
index 320d41f..9e4f067 100644 (file)
@@ -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.
index dd76f25..c4bd739 100644 (file)
@@ -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)
index 3d5bede..60160b6 100644 (file)
@@ -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
index ba1c758..e2e249d 100644 (file)
@@ -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)