This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Introduce dwfl_module_getsym_info and dwfl_module_addrinfo.


On Fri, 2013-12-13 at 07:53 +0100, Jan Kratochvil wrote:
> On Thu, 12 Dec 2013 11:51:37 +0100, Mark Wielaard wrote:
> > +extern const char *dwfl_module_getsym_info (Dwfl_Module *mod, int ndx,
> > +					    GElf_Sym *sym, GElf_Addr *addr)
> > +  __nonnull_attribute__ (3, 4);
> 
> Not sure if you have considered dropping the first NULL ELF symbol, when it is
> a new API anyway.  OTOH it will simplify neither caller nor the
> implementation.

Indeed, it wouldn't simplify anything really.

> It could also document sh_info does not match the local vs. global symbols;
> but that can be documented at any time.

Yeah, since the table is independent of any underlying ELF symbol table
the user cannot match any sh_info field. We should probably just provide
that info directly to the user, since we have it and it can be used for
optimizing how one searching through the table.

The attached patch does that by introducing a new function
dwfl_module_getsymtab_first_global which is then also used in our own
implementation.

Cheers,

Mark
>From 0d078f9fdbe5f497addadf130b5599bfb773a0d9 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Mon, 16 Dec 2013 13:28:59 +0100
Subject: [PATCH] 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>
---
 libdw/ChangeLog                |    4 ++++
 libdw/libdw.map                |    1 +
 libdwfl/ChangeLog              |   10 ++++++++++
 libdwfl/dwfl_module_addrsym.c  |    6 +++---
 libdwfl/dwfl_module_getdwarf.c |   23 +++++++++++++++++++++++
 libdwfl/libdwfl.h              |    7 +++++++
 libdwfl/libdwflP.h             |    1 +
 7 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index aa7b9ca..8b1e2c0 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -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.
diff --git a/libdw/libdw.map b/libdw/libdw.map
index 0438e24..342cdfe 100644
--- a/libdw/libdw.map
+++ b/libdw/libdw.map
@@ -286,4 +286,5 @@ ELFUTILS_0.158 {
 
     dwfl_module_addrsym_elf;
     dwfl_module_getsym_elf;
+    dwfl_module_getsymtab_first_global;
 } ELFUTILS_0.157;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index a9238d8..67f1fcf 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 320d41f..9e4f067 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 dd76f25..c4bd739 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 3d5bede..60160b6 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 ba1c758..e2e249d 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)
-- 
1.7.1


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]