[patch 3/3] ppc64 .opd: Bidirectional provider

Jan Kratochvil jan.kratochvil at redhat.com
Fri Dec 14 19:41:44 UTC 2012


Hi,

jankratochvil/symrefactor-scnfindvma-ppc64opdbidir

this time the ppc64 code entry points are provided as first class ELF symbols.

That means dwfl_module_addrsym need to be no longer modified (almost) at all.


I was thinking about the discussion with Mark and I believe there have been
mixed the "user display form" and "ELF symbol name".  It was also said that
for example C++ demangling could be used for the "user display form" together
with the leading dot removal.

I believe such "user display form" should be completely outside of the scope
of the current patches.  These patches are about ELF symbols and ELF symbol
names.  As is probably clear no C++ demangling should take place here it IMO
clarifies why also no dot removals should be done here.


Thanks,
Jan


commit 3847e9414281a1c94bb6b6aa5111fbfb19a3eb56
Author: Jan Kratochvil <jan.kratochvil at redhat.com>
Date:   Fri Dec 14 20:09:53 2012 +0100

    backends/
    	* Makefile.am (INCLUDES): Add libdwfl.
    	(ppc64_SRCS): Add ppc64_getsym.c.
    	* ppc64_getsym.c: New file.
    	* ppc64_init.c (ppc64_init): Install getsym and destr.
    
    libdwfl/
    	* dwfl_module_addrsym.c (dwfl_module_addrsym): Search also
    	Dwfl_Module->ebllocals.
    	* dwfl_module_getdwarf.c (find_symtab): Assert also
    	Dwfl_Module->ebllocals and Dwfl_Module->eblglobals.  Call
    	__libdwfl_module_getebl and ebl_getsym.
    	(dwfl_module_getsymtab): Return also the sum of Dwfl_Module->ebllocals
    	and Dwfl_Module->eblglobals.
    	* dwfl_module_getsym.c (dwfl_module_getsym): Rename parameter ndx to
    	ndxi.  New variables ndx and name.  Call ebl_getsym for the matching
    	range.  Prefer to return NAME if set.
    	* libdwflP.h (struct Dwfl_Module): New fields ebllocals and eblglobals.
    
    libebl/
    	* Makefile.am (gen_SOURCES): Add eblgetsym.c.
    	* ebl-hooks.h (getsym): New entry.
    	* eblgetsym.c: New file.
    	* libebl.h (struct Dwfl_Module): New declaration.
    	(ebl_getsym): New declaration.
    	* libeblP.h (struct ebl): New field backend.
    
    tests/
    	* run-addrname-test.sh: New testcase for ppc64 function descriptors.
    	* testfile66.bz2: New file.
    	* Makefile.am (EXTRA_DIST): Add testfile66.bz2.
    
    Signed-off-by: Jan Kratochvil <jan.kratochvil at redhat.com>

diff --git a/backends/ChangeLog b/backends/ChangeLog
index cca7113..8cc5275 100644
--- a/backends/ChangeLog
+++ b/backends/ChangeLog
@@ -1,3 +1,10 @@
+2012-12-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* Makefile.am (INCLUDES): Add libdwfl.
+	(ppc64_SRCS): Add ppc64_getsym.c.
+	* ppc64_getsym.c: New file.
+	* ppc64_init.c (ppc64_init): Install getsym and destr.
+
 2012-10-12  Jan Kratochvil  <jan.kratochvil at redhat.com>
 
 	* linux-core-note.c (prstatus_items): Rename groups of sigpend and
diff --git a/backends/Makefile.am b/backends/Makefile.am
index 982ff2a..62fee35 100644
--- a/backends/Makefile.am
+++ b/backends/Makefile.am
@@ -29,7 +29,7 @@
 ## not, see <http://www.gnu.org/licenses/>.
 include $(top_srcdir)/config/eu.am
 INCLUDES += -I$(top_srcdir)/libebl -I$(top_srcdir)/libasm \
-	   -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw
+	   -I$(top_srcdir)/libelf -I$(top_srcdir)/libdw -I$(top_srcdir)/libdwfl
 
 
 modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64 s390 tilegx
@@ -90,7 +90,8 @@ libebl_ppc_pic_a_SOURCES = $(ppc_SRCS)
 am_libebl_ppc_pic_a_OBJECTS = $(ppc_SRCS:.c=.os)
 
 ppc64_SRCS = ppc64_init.c ppc64_symbol.c ppc64_retval.c \
-	     ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c
+	     ppc64_corenote.c ppc_regs.c ppc_auxv.c ppc_attrs.c ppc_syscall.c \
+	     ppc64_getsym.c
 libebl_ppc64_pic_a_SOURCES = $(ppc64_SRCS)
 am_libebl_ppc64_pic_a_OBJECTS = $(ppc64_SRCS:.c=.os)
 
diff --git a/backends/ppc64_getsym.c b/backends/ppc64_getsym.c
new file mode 100644
index 0000000..14902fd
--- /dev/null
+++ b/backends/ppc64_getsym.c
@@ -0,0 +1,196 @@
+/* Return NDXth backend symbol from MOD.
+   Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include "libdwflP.h"
+#include <endian.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define BACKEND ppc64_
+#include "libebl_CPU.h"
+
+/* Pointer to the first entry is stored into ebl->backend.
+   It has Dwfl_Module->eblsyments entries and follow it strings for the NAME
+   entries.  */
+
+struct sym_entry
+{
+  GElf_Sym sym;
+  GElf_Word shndx;
+  const char *name;
+};
+
+static void
+init (Dwfl_Module *mod)
+{
+  assert (mod->ebllocals == 0);
+  assert (mod->eblglobals == 0);
+  Ebl *ebl = mod->ebl;
+  Elf *elf = ebl->elf;
+  if (elf == NULL)
+    return;
+  GElf_Ehdr ehdr_mem, *ehdr = gelf_getehdr (elf, &ehdr_mem);
+  if (ehdr == NULL)
+    return;
+  GElf_Word opd_shndx = 0;
+  GElf_Shdr opd_shdr_mem, *opd_shdr;
+  Elf_Data *opd_data;
+  Elf_Scn *scn = NULL;
+  while ((scn = elf_nextscn (elf, scn)) != NULL)
+    {
+      opd_shdr = gelf_getshdr (scn, &opd_shdr_mem);
+      if (opd_shdr == NULL)
+	continue;
+      if (strcmp (elf_strptr (elf, ehdr->e_shstrndx, opd_shdr->sh_name), ".opd")
+	  != 0)
+	continue;
+      opd_data = elf_getdata (scn, NULL);
+      /* SHT_NOBITS will produce NULL D_BUF.  */
+      if (opd_data == NULL || opd_data->d_buf == NULL)
+	return;
+      assert (opd_data->d_size == opd_shdr->sh_size);
+      opd_shndx = elf_ndxscn (scn);
+      break;
+    }
+  if (opd_shndx == 0)
+    return;
+  Dwarf_Addr symbias;
+  dwfl_module_info (mod, NULL, NULL, NULL, NULL, &symbias, NULL, NULL);
+  size_t names_size = 0, ebllocals = 0, eblglobals = 0;
+  for (int symi = 1; symi < dwfl_module_getsymtab (mod); symi++)
+    {
+      GElf_Sym sym;
+      GElf_Word shndx;
+      const char *symname = dwfl_module_getsym (mod, symi, &sym, &shndx);
+      if (symname == NULL || shndx != opd_shndx)
+	continue;
+      Elf64_Addr val;
+      if (sym.st_value < opd_shdr->sh_addr + symbias
+          || sym.st_value > (opd_shdr->sh_addr + symbias
+			     + opd_shdr->sh_size - sizeof (val)))
+	continue;
+      if ((size_t) symi < mod->symlocals)
+	ebllocals++;
+      else
+	eblglobals++;
+      names_size += 1 + strlen (symname) + 1;
+    }
+  if (ebllocals + eblglobals == 0)
+    return;
+  struct sym_entry *sym_table;
+  sym_table = malloc ((ebllocals + eblglobals) * sizeof (*sym_table)
+		      + names_size);
+  if (sym_table == NULL)
+    return;
+  ebl->backend = sym_table;
+  struct sym_entry *dest = sym_table;
+  char *names = (void *) &sym_table[ebllocals + eblglobals];
+  char *names_dest = names;
+  for (int symi = 1; symi < dwfl_module_getsymtab (mod); symi++)
+    {
+      GElf_Sym sym;
+      GElf_Word shndx;
+      const char *symname = dwfl_module_getsym (mod, symi, &sym, &shndx);
+      if (symname == NULL || shndx != opd_shndx)
+	continue;
+      uint64_t val64;
+      if (sym.st_value < opd_shdr->sh_addr + symbias
+          || sym.st_value > (opd_shdr->sh_addr + symbias
+			     + opd_shdr->sh_size - sizeof (val64)))
+	continue;
+      val64 = *(const uint64_t *) (opd_data->d_buf + sym.st_value
+				   - (opd_shdr->sh_addr + symbias));
+      val64 = (elf_getident (elf, NULL)[EI_DATA] == ELFDATA2MSB
+               ? be64toh (val64) : le64toh (val64));
+      assert ((char *) dest < names);
+      dest->sym = sym;
+      dest->sym.st_value = val64; // + symbias;
+      Elf_Scn *sym_scn = elf_scnfindvma (elf, val64);
+      dest->shndx = sym_scn == NULL ? SHN_ABS : elf_ndxscn (sym_scn);
+      dest->sym.st_shndx = SHN_XINDEX;
+      dest->name = names_dest;
+      *names_dest++ = '.';
+      names_dest = stpcpy (names_dest, symname) + 1;
+      dest++;
+    }
+  assert ((char *) dest == names);
+  assert (names_dest == names + names_size);
+  mod->ebllocals = ebllocals;
+  mod->eblglobals = eblglobals;
+}
+
+const char *
+ppc64_getsym (Dwfl_Module *mod, int ndxi, GElf_Sym *sym, GElf_Word *shndxp)
+{
+  Ebl *ebl = mod->ebl;
+  assert (ebl != NULL);
+  if (ebl->backend == NULL)
+    init (mod);
+  if (ebl->backend == NULL)
+    {
+      assert (mod->ebllocals + mod->eblglobals == 0);
+      ebl->backend = malloc (1);
+      return NULL;
+    }
+  struct sym_entry *sym_table = ebl->backend;
+  const struct sym_entry *found;
+  if (ndxi < 0)
+    return NULL;
+  size_t ndx = ndxi;
+  if (ndx < mod->symlocals)
+    return NULL;
+  else if (ndx < mod->symlocals + mod->ebllocals)
+    found = &sym_table[ndx - mod->symlocals];
+  else if (ndx < mod->symlocals + mod->ebllocals + mod->symglobals)
+    return NULL;
+  else if (ndx < (mod->symlocals + mod->ebllocals + mod->symglobals
+		  + mod->eblglobals))
+    found = &sym_table[ndx - mod->symlocals - mod->symglobals];
+  else
+    return NULL;
+  if (sym)
+    *sym = found->sym;
+  if (shndxp)
+    *shndxp = found->shndx;
+  return found->name;
+}
+
+void
+ppc64_destr (Ebl *ebl)
+{
+  if (ebl->backend == NULL)
+    return;
+  struct sym_entry *sym_table = ebl->backend;
+  free (sym_table);
+  ebl->backend = NULL;
+}
diff --git a/backends/ppc64_init.c b/backends/ppc64_init.c
index 90d4f2b..c64a903 100644
--- a/backends/ppc64_init.c
+++ b/backends/ppc64_init.c
@@ -64,6 +64,8 @@ ppc64_init (elf, machine, eh, ehlen)
   HOOK (eh, syscall_abi);
   HOOK (eh, core_note);
   HOOK (eh, auxv_info);
+  HOOK (eh, getsym);
+  HOOK (eh, destr);
 
   return MODVERSION;
 }
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 8caf083..b9d0e66 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,5 +1,19 @@
 2012-12-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
 
+	* dwfl_module_addrsym.c (dwfl_module_addrsym): Search also
+	Dwfl_Module->ebllocals.
+	* dwfl_module_getdwarf.c (find_symtab): Assert also
+	Dwfl_Module->ebllocals and Dwfl_Module->eblglobals.  Call
+	__libdwfl_module_getebl and ebl_getsym.
+	(dwfl_module_getsymtab): Return also the sum of Dwfl_Module->ebllocals
+	and Dwfl_Module->eblglobals.
+	* dwfl_module_getsym.c (dwfl_module_getsym): Rename parameter ndx to
+	ndxi.  New variables ndx and name.  Call ebl_getsym for the matching
+	range.  Prefer to return NAME if set.
+	* libdwflP.h (struct Dwfl_Module): New fields ebllocals and eblglobals.
+
+2012-12-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
 	* dwfl_module_addrsym.c (dwfl_module_addrsym): Call elf_scnfindvma
 	where is the code from here moved out.
 
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index d2316c6..b2db68e 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -157,13 +157,13 @@ dwfl_module_addrsym (Dwfl_Module *mod, GElf_Addr addr,
     }
 
   /* First go through global symbols.  */
-  search_table (mod->symlocals, syments);
+  search_table (mod->symlocals + mod->ebllocals, syments);
 
   /* If we found nothing searching the global symbols, then try the locals.
      Unless we have a global sizeless symbol that matches exactly.  */
-  if (closest_name == NULL && mod->symlocals > 1
+  if (closest_name == NULL && mod->symlocals + mod->ebllocals > 1
       && (sizeless_name == NULL || sizeless_sym.st_value != addr))
-    search_table (1, mod->symlocals);
+    search_table (1, mod->symlocals + mod->ebllocals);
 
   /* If we found no proper sized symbol to use, fall back to the best
      candidate sizeless symbol we found, if any.  */
diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
index f816f2c..8e30671 100644
--- a/libdwfl/dwfl_module_getdwarf.c
+++ b/libdwfl/dwfl_module_getdwarf.c
@@ -828,7 +828,9 @@ find_symtab (Dwfl_Module *mod)
     return;
 
   assert (mod->symlocals == 0);
+  assert (mod->ebllocals == 0);
   assert (mod->symglobals == 0);
+  assert (mod->eblglobals == 0);
 
   /* First see if the main ELF file has the debugging information.  */
   Elf_Scn *symscn = NULL, *xndxscn = NULL;
@@ -913,6 +915,10 @@ find_symtab (Dwfl_Module *mod)
   mod->symdata = elf_getdata (symscn, NULL);
   if (mod->symdata == NULL)
     goto elferr;
+
+  Dwfl_Error error = __libdwfl_module_getebl (mod);
+  if (error == DWFL_E_NOERROR)
+    ebl_getsym (mod->ebl, mod, -1, NULL, NULL);
 }
 
 
@@ -1068,7 +1074,7 @@ dwfl_module_getsymtab (Dwfl_Module *mod)
 
   find_symtab (mod);
   if (mod->symerr == DWFL_E_NOERROR)
-    return mod->symlocals + mod->symglobals;
+    return mod->symlocals + mod->ebllocals + mod->symglobals + mod->eblglobals;
 
   __libdwfl_seterrno (mod->symerr);
   return -1;
diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
index 9103380..537bc59 100644
--- a/libdwfl/dwfl_module_getsym.c
+++ b/libdwfl/dwfl_module_getsym.c
@@ -29,7 +29,7 @@
 #include "libdwflP.h"
 
 const char *
-dwfl_module_getsym (Dwfl_Module *mod, int ndx,
+dwfl_module_getsym (Dwfl_Module *mod, int ndxi,
 		    GElf_Sym *sym, GElf_Word *shndxp)
 {
   if (unlikely (mod == NULL))
@@ -42,12 +42,32 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
 	return NULL;
     }
 
+  size_t ndx = ndxi;
+  const char *name = NULL;
   GElf_Word shndx;
-  sym = gelf_getsymshndx (mod->symdata, mod->symxndxdata, ndx, sym, &shndx);
-  if (unlikely (sym == NULL))
+  if (unlikely ((ndx >= mod->symlocals && ndx < mod->symlocals + mod->ebllocals)
+		|| (ndx >= mod->symlocals + mod->ebllocals + mod->symglobals
+		    && ndx < (mod->symlocals + mod->ebllocals + mod->symglobals
+			      + mod->eblglobals))))
     {
-      __libdwfl_seterrno (DWFL_E_LIBELF);
-      return NULL;
+      name = ebl_getsym (mod->ebl, mod, ndx, sym, &shndx);
+      if (unlikely (name == NULL))
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBEBL);
+	  return NULL;
+	}
+    }
+  else
+    {
+      if (ndx >= mod->symlocals)
+	ndx -= mod->ebllocals;
+
+      sym = gelf_getsymshndx (mod->symdata, mod->symxndxdata, ndx, sym, &shndx);
+      if (unlikely (sym == NULL))
+	{
+	  __libdwfl_seterrno (DWFL_E_LIBELF);
+	  return NULL;
+	}
     }
 
   if (sym->st_shndx != SHN_XINDEX)
@@ -97,6 +117,9 @@ dwfl_module_getsym (Dwfl_Module *mod, int ndx,
       break;
     }
 
+  if (name)
+    return name;
+
   if (unlikely (sym->st_name >= mod->symstrdata->d_size))
     {
       __libdwfl_seterrno (DWFL_E_BADSTROFF);
diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
index 360e1ef..bd04128 100644
--- a/libdwfl/libdwflP.h
+++ b/libdwfl/libdwflP.h
@@ -157,7 +157,9 @@ struct Dwfl_Module
   /* All symbols with local binding come first in the symbol table,
      then all globals.  */
   size_t symlocals;		/* Local symbols in SYMDATA.  */
+  size_t ebllocals;		/* Local symbols via ebl_getsym.  */
   size_t symglobals;		/* Global symbols in SYMDATA.  */
+  size_t eblglobals;		/* Global symbols via ebl_getsym.  */
 
   Dwarf *dw;			/* libdw handle for its debugging info.  */
 
diff --git a/libebl/ChangeLog b/libebl/ChangeLog
index e881ce7..5d3c015 100644
--- a/libebl/ChangeLog
+++ b/libebl/ChangeLog
@@ -1,3 +1,12 @@
+2012-12-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+
+	* Makefile.am (gen_SOURCES): Add eblgetsym.c.
+	* ebl-hooks.h (getsym): New entry.
+	* eblgetsym.c: New file.
+	* libebl.h (struct Dwfl_Module): New declaration.
+	(ebl_getsym): New declaration.
+	* libeblP.h (struct ebl): New field backend.
+
 2012-10-12  Jan Kratochvil  <jan.kratochvil at redhat.com>
 
 	* ebl-hooks.h (abi_cfi): Extend its comment for return value.
diff --git a/libebl/Makefile.am b/libebl/Makefile.am
index 65e6b5b..08fe5b6 100644
--- a/libebl/Makefile.am
+++ b/libebl/Makefile.am
@@ -54,7 +54,7 @@ gen_SOURCES = eblopenbackend.c eblclosebackend.c eblstrtab.c \
 	      eblreginfo.c eblnonerelocp.c eblrelativerelocp.c \
 	      eblsysvhashentrysize.c eblauxvinfo.c eblcheckobjattr.c \
 	      ebl_check_special_section.c ebl_syscall_abi.c eblabicfi.c \
-	      eblstother.c
+	      eblstother.c eblgetsym.c
 
 libebl_a_SOURCES = $(gen_SOURCES)
 
diff --git a/libebl/ebl-hooks.h b/libebl/ebl-hooks.h
index d3cf3e6..30bd0a2 100644
--- a/libebl/ebl-hooks.h
+++ b/libebl/ebl-hooks.h
@@ -155,5 +155,12 @@ int EBLHOOK(disasm) (const uint8_t **startp, const uint8_t *end,
    Function returns 0 on success and -1 on error.  */
 int EBLHOOK(abi_cfi) (Ebl *ebl, Dwarf_CIE *abi_info);
 
+/* Return NDXth backend symbol from MOD, store it to *SYM and *SHNDX and return
+   its new name.  If NDX is -1 then only initialize MOD's EBLSYMENTS (and
+   associated fields) and return NULL (SYM and SHNDXP are ignored in such
+   case).  Returned name is valid as long as EBL is valid.  */
+const char *EBLHOOK(getsym) (struct Dwfl_Module *mod, int ndx, GElf_Sym *sym,
+			     GElf_Word *shndxp);
+
 /* Destructor for ELF backend handle.  */
 void EBLHOOK(destr) (struct ebl *);
diff --git a/libebl/eblgetsym.c b/libebl/eblgetsym.c
new file mode 100644
index 0000000..af20ea6
--- /dev/null
+++ b/libebl/eblgetsym.c
@@ -0,0 +1,45 @@
+/* Return NDXth backend symbol from MOD.
+   Copyright (C) 2012 Red Hat, Inc.
+   This file is part of elfutils.
+
+   This file is free software; you can redistribute it and/or modify
+   it under the terms of either
+
+     * the GNU Lesser General Public License as published by the Free
+       Software Foundation; either version 3 of the License, or (at
+       your option) any later version
+
+   or
+
+     * the GNU General Public License as published by the Free
+       Software Foundation; either version 2 of the License, or (at
+       your option) any later version
+
+   or both in parallel, as here.
+
+   elfutils is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received copies of the GNU General Public License and
+   the GNU Lesser General Public License along with this program.  If
+   not, see <http://www.gnu.org/licenses/>.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libeblP.h>
+#include <assert.h>
+
+const char *
+ebl_getsym (Ebl *ebl, struct Dwfl_Module *mod, int ndx, GElf_Sym *sym,
+	    GElf_Word *shndxp)
+{
+  if (ebl == NULL)
+    return NULL;
+  if (ebl->getsym == NULL)
+    return NULL;
+  return ebl->getsym (mod, ndx, sym, shndxp);
+}
diff --git a/libebl/libebl.h b/libebl/libebl.h
index cae31c9..a9314c3 100644
--- a/libebl/libebl.h
+++ b/libebl/libebl.h
@@ -378,6 +378,15 @@ extern int ebl_auxv_info (Ebl *ebl, GElf_Xword a_type,
 			  const char **name, const char **format)
   __nonnull_attribute__ (1, 3, 4);
 
+/* Return NDXth backend symbol from MOD, store it to *SYM and *SHNDX and return
+   its new name.  If NDX is -1 then only initialize MOD's EBLSYMENTS (and
+   associated fields) and return NULL (SYM and SHNDXP are ignored in such
+   case).  Returned name is valid as long as EBL is valid.  */
+struct Dwfl_Module;
+extern const char * ebl_getsym (Ebl *ebl, struct Dwfl_Module *mod, int ndx,
+				GElf_Sym *sym, GElf_Word *shndxp)
+  __nonnull_attribute__ (1, 2);
+
 
 #ifdef __cplusplus
 }
diff --git a/libebl/libeblP.h b/libebl/libeblP.h
index 5ec26a4..c8196bd 100644
--- a/libebl/libeblP.h
+++ b/libebl/libeblP.h
@@ -62,6 +62,9 @@ struct ebl
 
   /* Internal data.  */
   void *dlhandle;
+
+  /* Data specific to the backend.  */
+  void *backend;
 };
 
 
diff --git a/tests/ChangeLog b/tests/ChangeLog
index 0289148..02adf94 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,9 @@
+2012-12-14  Jan Kratochvil  <jan.kratochvil at redhat.com>
+    
+	* run-addrname-test.sh: New testcase for ppc64 function descriptors.
+	* testfile66.bz2: New file.
+	* Makefile.am (EXTRA_DIST): Add testfile66.bz2.
+
 2012-12-03  Mark Wielaard  <mjw at redhat.com>
 
 	* Makefile.am (valgrind_cmd): Add --run-libc-freeres=no.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 8b7b751..bb442ae 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -181,7 +181,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     run-readelf-vmcoreinfo.sh testfile62.bz2 \
 	     run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
 	     testfile65.bz2 testfile69.core.bz2 testfile69.so.bz2 \
-	     testfile70.core.bz2 testfile70.exec.bz2
+	     testfile70.core.bz2 testfile70.exec.bz2 testfile66.bz2
 
 if USE_VALGRIND
 valgrind_cmd="valgrind -q --trace-children=yes --error-exitcode=1 --run-libc-freeres=no"
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index 99abf9d..06dd151 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -298,6 +298,18 @@ __vdso_time
 ??:0
 EOF
 
+testfiles testfile66
+testrun_compare ../src/addr2line -S -e testfile66 func 0x10340 .func 0x250 <<\EOF
+func
+??:0
+func
+??:0
+.func
+??:0
+.func
+??:0
+EOF
+
 testfiles testfile69.core testfile69.so
 testrun_compare ../src/addr2line --core=./testfile69.core -S 0x7f0bc6a33535 0x7f0bc6a33546 <<\EOF
 libstatic+0x9
diff --git a/tests/testfile66.bz2 b/tests/testfile66.bz2
new file mode 100644
index 0000000000000000000000000000000000000000..db07f25415729927f4e2b4985c5668c8e2ee10a2
GIT binary patch
literal 569
zcmV-90>=G9T4*^jL0KkKSrloeYybi*|NH;`Q+Gmd_t9I$azOv*{$$8R5dZ){00;sg
zN(3VzzyZ?W%~)z`O*V<ChK5r#X)zd>fu;fm0WvhiG}9)JQGyXYL8JhU5NHRe007X?
z$Qoh*0BMi_;L)Q%&}a;pfXL9u01Y(A003Zs0!0dH8USbj00000000000H3&^h5+h?
zHGH8oS#&k;tR%<0nFK6&-#1i4RnYl;-bpN9k2InZwNKHPIa5z$l?D9dtf^2;aFZ>;
z6H2`TaFp50B|IFU9;meM2nk4CXKdt!?6iqh`+DOs7204JFHHaexzT9oele)vNXcO|
z&aXz&bgUpHL5Q+$&J at iFQZPa%v>5P$Ld;?WwHgw?W$OZSUT)aw=i|cU?V{^+uO+T&
zsc1>77*MKpaR&z&l3<3FBTF`AA*kg!f+LXQdlF0z1|<OGVw|;E3MDuVYg}lF1kIB*
z2MO?2(vv|()kGjFhM>|aV;0;9Y&kKvJQ6|?q76u^Sl}`<LIO+NDfU1C1=+J>CXwR7
zvQ|1 at iR(qMOPC<M!U)iAS_QSrP$be&teWK at Xh4y??kxH~E_K((z?!P4lv4z at 9Y0sD
zK?cn^FLD~401iNn#iXf~Yy5H5(sqZpp=+#)n|DQ6r81NSyLB;KQD(6uE>?9m>Ok-8
z(YXp^O0BHJBpo)oV3bgUCvFNTfZoo at a?O8}_!iyT909f+z2<0!_i&kLzs1~<P81{s
H8flvV7_Id;

literal 0
HcmV?d00001



More information about the elfutils-devel mailing list