bfd: Display symbol version for nm -D

Message ID 20200322122947.270417-1-hjl.tools@gmail.com
State New
Headers show
Series
  • bfd: Display symbol version for nm -D
Related show

Commit Message

H.J. Lu via Binutils March 22, 2020, 12:29 p.m.
Extend _bfd_elf_get_symbol_version_string for nm -D to display symbol
version.  _bfd_elf_get_symbol_version_name is added to avoid updating
all XXX_get_symbol_version_string functions.

bfd/

	PR binutils/25708
	* elf-bfd.h (_bfd_elf_get_symbol_version_name): New.
	* elf.c (_bfd_elf_get_symbol_version_name): New function.  Based
	on the previous _bfd_elf_get_symbol_version_string.
	(_bfd_elf_get_symbol_version_string): Use it.

binutils/

	PR binutils/25708
	* nm.c (SYM_NAME): Removed.
	(print_symname): Add a pointer to struct extended_symbol_info
	argument.  Call _bfd_elf_get_symbol_version_name to get symbol
	version.
	(print_symdef_entry): Pass NULL to print_symname.
	(print_symbol_info_bsd): Update call to print_symname.
	(print_symbol_info_sysv): Likewise.
	(print_symbol_info_posix): Likewise.

ld/

	PR binutils/25708
	* testsuite/ld-elf/pr25707.d: New file.
---
 bfd/elf-bfd.h                 |  2 ++
 bfd/elf.c                     | 27 +++++++++++++++++++++------
 binutils/nm.c                 | 26 ++++++++++++++++++++------
 ld/testsuite/ld-elf/pr25707.d |  9 +++++++++
 4 files changed, 52 insertions(+), 12 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr25707.d

-- 
2.25.1

Comments

H.J. Lu via Binutils March 24, 2020, 10:38 a.m. | #1
Hi H.J.

> bfd/

> 

> 	PR binutils/25708

> 	* elf-bfd.h (_bfd_elf_get_symbol_version_name): New.

> 	* elf.c (_bfd_elf_get_symbol_version_name): New function.  Based

> 	on the previous _bfd_elf_get_symbol_version_string.

> 	(_bfd_elf_get_symbol_version_string): Use it.

> 

> binutils/

> 

> 	PR binutils/25708

> 	* nm.c (SYM_NAME): Removed.

> 	(print_symname): Add a pointer to struct extended_symbol_info

> 	argument.  Call _bfd_elf_get_symbol_version_name to get symbol

> 	version.

> 	(print_symdef_entry): Pass NULL to print_symname.

> 	(print_symbol_info_bsd): Update call to print_symname.

> 	(print_symbol_info_sysv): Likewise.

> 	(print_symbol_info_posix): Likewise.

> 

> ld/

> 

> 	PR binutils/25708

> 	* testsuite/ld-elf/pr25707.d: New file.


Approved - please apply.

Cheers
  Nick
H.J. Lu via Binutils March 24, 2020, 5:47 p.m. | #2
On Tue, Mar 24, 2020 at 3:38 AM Nick Clifton <nickc@redhat.com> wrote:
>

> Hi H.J.

>

> > bfd/

> >

> >       PR binutils/25708

> >       * elf-bfd.h (_bfd_elf_get_symbol_version_name): New.

> >       * elf.c (_bfd_elf_get_symbol_version_name): New function.  Based

> >       on the previous _bfd_elf_get_symbol_version_string.

> >       (_bfd_elf_get_symbol_version_string): Use it.

> >

> > binutils/

> >

> >       PR binutils/25708

> >       * nm.c (SYM_NAME): Removed.

> >       (print_symname): Add a pointer to struct extended_symbol_info

> >       argument.  Call _bfd_elf_get_symbol_version_name to get symbol

> >       version.

> >       (print_symdef_entry): Pass NULL to print_symname.

> >       (print_symbol_info_bsd): Update call to print_symname.

> >       (print_symbol_info_sysv): Likewise.

> >       (print_symbol_info_posix): Likewise.

> >

> > ld/

> >

> >       PR binutils/25708

> >       * testsuite/ld-elf/pr25707.d: New file.

>

> Approved - please apply.

>


We can't call _bfd_elf_get_symbol_version_name from nm.c since it isn't
available for all target configurations.  This patch add a bfd_boolean
argument to bfd_get_symbol_version_string instead.

OK for master?


-- 
H.J.
H.J. Lu via Binutils March 24, 2020, 9:51 p.m. | #3
On Tue, Mar 24, 2020 at 10:47:58AM -0700, H.J. Lu via Binutils wrote:
> We can't call _bfd_elf_get_symbol_version_name from nm.c since it isn't

> available for all target configurations.  This patch add a bfd_boolean

> argument to bfd_get_symbol_version_string instead.

> 

> OK for master?


OK.

-- 
Alan Modra
Australia Development Lab, IBM

Patch

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index d4ac5152df..c546b583b8 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2078,6 +2078,8 @@  extern bfd_boolean _bfd_elf_print_private_bfd_data
   (bfd *, void *);
 const char * _bfd_elf_get_symbol_version_string
   (bfd *, asymbol *, bfd_boolean *);
+const char * _bfd_elf_get_symbol_version_name
+  (bfd *, asymbol *, bfd_boolean, bfd_boolean *);
 extern void bfd_elf_print_symbol
   (bfd *, void *, asymbol *, bfd_print_symbol_type);
 
diff --git a/bfd/elf.c b/bfd/elf.c
index 975eeb06b8..1004809e45 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -1883,11 +1883,13 @@  _bfd_elf_print_private_bfd_data (bfd *abfd, void *farg)
   return FALSE;
 }
 
-/* Get version string.  */
+/* Get version name.  If BASE_P is TRUE, return "Base" for VER_FLG_BASE
+   and return symbol version for symbol version itself.   */
 
 const char *
-_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
-				    bfd_boolean *hidden)
+_bfd_elf_get_symbol_version_name (bfd *abfd, asymbol *symbol,
+				  bfd_boolean base_p,
+				  bfd_boolean *hidden)
 {
   const char *version_string = NULL;
   if (elf_dynversym (abfd) != 0
@@ -1904,10 +1906,14 @@  _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
 	       && (vernum > elf_tdata (abfd)->cverdefs
 		   || (elf_tdata (abfd)->verdef[0].vd_flags
 		       == VER_FLG_BASE)))
-	version_string = "Base";
+	version_string = base_p ? "Base" : "";
       else if (vernum <= elf_tdata (abfd)->cverdefs)
-	version_string =
-	  elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+	{
+	  const char *nodename
+	    = elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+	  version_string = ((base_p || strcmp (symbol->name, nodename))
+			    ? nodename : "");
+	}
       else
 	{
 	  Elf_Internal_Verneed *t;
@@ -1933,6 +1939,15 @@  _bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
   return version_string;
 }
 
+/* Get version string.  */
+
+const char *
+_bfd_elf_get_symbol_version_string (bfd *abfd, asymbol *symbol,
+				    bfd_boolean *hidden)
+{
+  return _bfd_elf_get_symbol_version_name (abfd, symbol, TRUE, hidden);
+}
+
 /* Display ELF-specific fields of a symbol.  */
 
 void
diff --git a/binutils/nm.c b/binutils/nm.c
index 0ee3f88386..0e475f8006 100644
--- a/binutils/nm.c
+++ b/binutils/nm.c
@@ -67,7 +67,6 @@  struct extended_symbol_info
   coff_symbol_type *coffinfo;
   /* FIXME: We should add more fields for Type, Line, Section.  */
 };
-#define SYM_NAME(sym)        (sym->sinfo->name)
 #define SYM_VALUE(sym)       (sym->sinfo->value)
 #define SYM_TYPE(sym)        (sym->sinfo->type)
 #define SYM_STAB_NAME(sym)   (sym->sinfo->stab_name)
@@ -394,8 +393,11 @@  get_coff_symbol_type (const struct internal_syment *sym)
    demangling it if requested.  */
 
 static void
-print_symname (const char *form, const char *name, bfd *abfd)
+print_symname (const char *form, struct extended_symbol_info *info,
+	       const char *name, bfd *abfd)
 {
+  if (name == NULL)
+    name = info->sinfo->name;
   if (do_demangle && *name)
     {
       char *res = bfd_demangle (abfd, name, demangle_flags);
@@ -409,6 +411,18 @@  print_symname (const char *form, const char *name, bfd *abfd)
     }
 
   printf (form, name);
+  if (info != NULL && info->elfinfo)
+    {
+      const char *version_string;
+      bfd_boolean hidden;
+
+      version_string
+	= _bfd_elf_get_symbol_version_name (abfd,
+					    &info->elfinfo->symbol,
+					    FALSE, &hidden);
+      if (version_string && version_string[0])
+	printf ("%s%s", hidden ? "@" : "@@", version_string);
+    }
 }
 
 static void
@@ -433,7 +447,7 @@  print_symdef_entry (bfd *abfd)
 	bfd_fatal ("bfd_get_elt_at_index");
       if (thesym->name != (char *) NULL)
 	{
-	  print_symname ("%s", thesym->name, abfd);
+	  print_symname ("%s", NULL, thesym->name, abfd);
 	  printf (" in %s\n", bfd_get_filename (elt));
 	}
     }
@@ -1606,13 +1620,13 @@  print_symbol_info_bsd (struct extended_symbol_info *info, bfd *abfd)
       printf (desc_format, SYM_STAB_DESC (info));
       printf (" %5s", SYM_STAB_NAME (info));
     }
-  print_symname (" %s", SYM_NAME (info), abfd);
+  print_symname (" %s", info, NULL, abfd);
 }
 
 static void
 print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd)
 {
-  print_symname ("%-20s|", SYM_NAME (info), abfd);
+  print_symname ("%-20s|", info, NULL, abfd);
 
   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
     {
@@ -1667,7 +1681,7 @@  print_symbol_info_sysv (struct extended_symbol_info *info, bfd *abfd)
 static void
 print_symbol_info_posix (struct extended_symbol_info *info, bfd *abfd)
 {
-  print_symname ("%s ", SYM_NAME (info), abfd);
+  print_symname ("%s ", info, NULL, abfd);
   printf ("%c ", SYM_TYPE (info));
 
   if (bfd_is_undefined_symclass (SYM_TYPE (info)))
diff --git a/ld/testsuite/ld-elf/pr25707.d b/ld/testsuite/ld-elf/pr25707.d
new file mode 100644
index 0000000000..e487d227b3
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr25707.d
@@ -0,0 +1,9 @@ 
+#source: pr13195.s
+#ld: -shared -version-script pr13195.t
+#nm: -D
+#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi
+
+#..
+0+ A VERS_2.0
+[0-9a-f]+ T foo@@VERS_2.0
+#pass