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: [patchv4 4/4] Provide virtual symbols for ppc64 function descriptors


On Thu, 2013-12-12 at 11:49 +0100, Mark Wielaard wrote:
> But now that we do have to provide a new API anyway, we could make a
> lookup for an address match against either or both of the values or
> addresses. Currently I haven't done that, but we could make
> dwfl_module_addrinfo (mod, addr, off, sym) match on either the
> (adjusted) st_value and on the resolved address for the symbol.

The attached, applied on top of the original patch, does that. Also made
addr2line use it and updated the tests to show it then also displays
names for values in different sections.

Then the only feature you seem to want that is missing is a real search
on name or identifier. Where the identifier might have some modifier(s)
that have a possible arch specific meaning that matches it to some
address and/or some other properties. I think that needs its own
specific interface though. And it also doesn't seem immediately needed
right now (in contrast with the address lookups which make the unwinder
more useful).

Cheers,

Mark
>From c0f17b9778bec4a91af3642f8c5db67ca77f16b8 Mon Sep 17 00:00:00 2001
From: Mark Wielaard <mjw@redhat.com>
Date: Thu, 12 Dec 2013 16:01:42 +0100
Subject: [PATCH] dwfl_module_addrinfo: Resolve against both value and adjusted st_value.

To more easily find a name/function associated with an address make the
dwfl_module_addrinfo functions resolve against both the (resolved) value
and the original (adjusted) symbol st_value.  addr2line uses this now and
will display the section the address was found in when given -x.

Signed-off-by: Mark Wielaard <mjw@redhat.com>
---
 libdwfl/ChangeLog             |    5 +++++
 libdwfl/dwfl_module_addrsym.c |   15 +++++++++++++++
 src/ChangeLog                 |    7 +++++++
 src/addr2line.c               |   39 ++++++++++++++++++++++++++++++++++++---
 tests/ChangeLog               |    5 +++++
 tests/run-addrname-test.sh    |   22 +++++++++++++++-------
 6 files changed, 83 insertions(+), 10 deletions(-)

diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 51027e4..82376f5 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-12  Mark Wielaard  <mjw@redhat.com>
+
+	* dwfl_module_addrsym.c (__libdwfl_addrsym): Search for both value
+	and sym.st_value (adjusted) when different.
+
 2013-12-11  Mark Wielaard  <mjw@redhat.com>
 
 	* derelocate.c (__libdwfl_find_section_ndx): New internal function.
diff --git a/libdwfl/dwfl_module_addrsym.c b/libdwfl/dwfl_module_addrsym.c
index 5a72de1..22746c6 100644
--- a/libdwfl/dwfl_module_addrsym.c
+++ b/libdwfl/dwfl_module_addrsym.c
@@ -128,6 +128,7 @@ __libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
 	      /* Even if we don't choose this symbol, its existence excludes
 		 any sizeless symbol (assembly label) that is below its upper
 		 bound.  */
+	    try_value:
 	      if (value + sym.st_size > min_label)
 		min_label = value + sym.st_size;
 
@@ -197,6 +198,20 @@ __libdwfl_addrsym (Dwfl_Module *mod, GElf_Addr addr, GElf_Off *off,
 		      closest_name = name;
 		    }
 		}
+
+	      /* If this is an addrinfo variant and the value could be
+		 resolved then also try matching the (adjusted) st_value.  */
+	      if (! adjust_st_value && mod->e_type != ET_REL)
+		{
+		  GElf_Addr adjusted_st_value;
+		  adjusted_st_value = dwfl_adjusted_st_value (mod, elf,
+							      sym.st_value);
+		  if (value != adjusted_st_value)
+		    {
+		      value = adjusted_st_value;
+		      goto try_value;
+		    }
+		}
 	    }
 	}
     }
diff --git a/src/ChangeLog b/src/ChangeLog
index 9d7cd40..cddb632 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2013-12-12  Mark Wielaard  <mjw@redhat.com>
+
+	* addr2line.c (options): Add symbol-sections, 'x'.
+	(show_symbol_sections): New static bool.
+	(parse_opt): Handle 'x'.
+	(print_addrsym): Also show section of address.
+
 2013-12-11  Mark Wielaard  <mjw@redhat.com>
 
 	* addr2line.c (print_addrsym): Use dwfl_module_addrinfo.
diff --git a/src/addr2line.c b/src/addr2line.c
index 2e541ac..c7e4cb0 100644
--- a/src/addr2line.c
+++ b/src/addr2line.c
@@ -61,6 +61,7 @@ static const struct argp_option options[] =
     N_("Show absolute file names using compilation directory"), 0 },
   { "functions", 'f', NULL, 0, N_("Also show function names"), 0 },
   { "symbols", 'S', NULL, 0, N_("Also show symbol or section names"), 0 },
+  { "symbols-sections", 'x', NULL, 0, N_("Also show symbol and the section names"), 0 },
   { "flags", 'F', NULL, 0, N_("Also show line table flags"), 0 },
   { "section", 'j', "NAME", 0,
     N_("Treat addresses as offsets relative to NAME section."), 0 },
@@ -114,6 +115,9 @@ static bool show_functions;
 /* True if ELF symbol or section info should be shown.  */
 static bool show_symbols;
 
+/* True if section associated with a symbol address should be shown.  */
+static bool show_symbol_sections;
+
 /* If non-null, take address parameters as relative to named section.  */
 static const char *just_section;
 
@@ -234,6 +238,11 @@ parse_opt (int key, char *arg, struct argp_state *state)
       show_symbols = true;
       break;
 
+    case 'x':
+      show_symbols = true;
+      show_symbol_sections = true;
+      break;
+
     case 'j':
       just_section = arg;
       break;
@@ -355,10 +364,34 @@ print_addrsym (Dwfl_Module *mod, GElf_Addr addr)
       else
 	printf ("(%s)+%#" PRIx64 "\n", name, addr);
     }
-  else if (off == 0)
-    puts (name);
   else
-    printf ("%s+%#" PRIx64 "\n", name, off);
+    {
+      if (off == 0)
+	printf ("%s", name);
+      else
+	printf ("%s+%#" PRIx64 "", name, off);
+
+      // Also show section name for address.
+      if (show_symbol_sections)
+	{
+	  Dwarf_Addr ebias;
+	  Elf_Scn *scn = dwfl_module_address_section (mod, &addr, &ebias);
+	  if (scn != NULL)
+	    {
+	      GElf_Shdr shdr_mem;
+	      GElf_Shdr *shdr = gelf_getshdr (scn, &shdr_mem);
+	      if (scn != NULL)
+		{
+		  Elf *elf = dwfl_module_getelf (mod, &ebias);
+		  GElf_Ehdr ehdr;
+		  gelf_getehdr (elf, &ehdr);
+		  printf (" (%s)", elf_strptr (elf, ehdr.e_shstrndx,
+					       shdr->sh_name));
+		}
+	    }
+	}
+      puts ("");
+    }
 }
 
 static void
diff --git a/tests/ChangeLog b/tests/ChangeLog
index c1f9764..74944ce 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-11  Mark Wielaard  <mjw@redhat.com>
+
+	* run-addrname-test.sh: Test addr2line -x by showing different
+	sections for address and found name in testfile66.
+
 2013-12-11  Jan Kratochvil  <jan.kratochvil@redhat.com>
 	    Mark Wielaard  <mjw@redhat.com>
 
diff --git a/tests/run-addrname-test.sh b/tests/run-addrname-test.sh
index 58eae98..f954ee4 100755
--- a/tests/run-addrname-test.sh
+++ b/tests/run-addrname-test.sh
@@ -308,20 +308,28 @@ EOF
 #	.byte	0x7d, 0x82, 0x10, 0x08
 #	.size	_start,.-.L._start
 testfiles testfile66 testfile66.core
-testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile66 _start 0x2d8 0x2db 0x2dc <<EOF
-_start
+testrun_compare ${abs_top_builddir}/src/addr2line -x -e testfile66 _start 0x2d8 0x2db 0x2dc 0x103d0 0x103d3 0x103d4<<EOF
+_start (.text)
 ??:0
-_start
+_start (.text)
 ??:0
-_start+0x3
+_start+0x3 (.text)
 ??:0
 ()+0x2dc
 ??:0
+_start (.opd)
+??:0
+_start+0x3 (.opd)
+??:0
+()+0x103d4
+??:0
 EOF
-testrun_compare ${abs_top_builddir}/src/addr2line -S -e testfile66 --core=testfile66.core _start 0x461b02d8 <<\EOF
-_start
+testrun_compare ${abs_top_builddir}/src/addr2line -x -e testfile66 --core=testfile66.core _start 0x461b02d8 0x461c03d0<<\EOF
+_start (.text)
+??:0
+_start (.text)
 ??:0
-_start
+_start (.opd)
 ??:0
 EOF
 
-- 
1.7.1


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