]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
readelf: Display the base symbol version as empty string
authorH.J. Lu <hjl.tools@gmail.com>
Thu, 6 Nov 2025 00:20:26 +0000 (08:20 +0800)
committerH.J. Lu <hjl.tools@gmail.com>
Fri, 7 Nov 2025 22:39:42 +0000 (06:39 +0800)
Update readelf to display the base symbol version as

Symbol table for image contains 5 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000003008     0 OBJECT  GLOBAL DEFAULT   10 bar@@
     2: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS VERS_1
     3: 0000000000003008     0 OBJECT  GLOBAL DEFAULT   10 bar@@VERS_1
     4: 0000000000003000     0 OBJECT  GLOBAL DEFAULT   10 foo@

instead of

Symbol table for image contains 5 entries:
   Num:    Value          Size Type    Bind   Vis      Ndx Name
     0: 0000000000000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 0000000000003008     0 OBJECT  GLOBAL DEFAULT   10 bar
     2: 0000000000000000     0 OBJECT  GLOBAL DEFAULT  ABS VERS_1
     3: 0000000000003008     0 OBJECT  GLOBAL DEFAULT   10 bar@@VERS_1
     4: 0000000000003000     0 OBJECT  GLOBAL DEFAULT   10 foo

That is bar@@ and foo@ vs bar and foo.

binutils/

PR binutils/33599
* readelf.c (process_version_sections): Replace 0x8001 with
(VERSYM_HIDDEN | VERSYM_BASE).
(get_symbol_version_string): Likewise.  Return "" for the base
version.

include/

PR binutils/33599
* elf/common.h (VERSYM_BASE): New.

ld/

PR binutils/33599
* testsuite/ld-elf/pr33599.d: New file.
* testsuite/ld-elf/pr33599.map: Likewise.
* testsuite/ld-elf/pr33599.s: Likewise.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
binutils/readelf.c
include/elf/common.h
ld/testsuite/ld-elf/pr33599.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr33599.map [new file with mode: 0644]
ld/testsuite/ld-elf/pr33599.s [new file with mode: 0644]

index 2d1d20413c440d997b92860cf1c4aeba9e679ebf..933dd34d4a869eb7dadee3f858999d11f0063ec0 100644 (file)
@@ -14074,7 +14074,7 @@ process_version_sections (Filedata * filedata)
                          while (ivn.vn_next);
                        }
 
-                     if (data[cnt + j] != 0x8001
+                     if (data[cnt + j] != (VERSYM_HIDDEN | VERSYM_BASE)
                          && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
                        {
                          Elf_Internal_Verdef ivd;
@@ -14500,6 +14500,10 @@ get_symbol_version_string (Filedata *filedata,
   *sym_info = (vers_data & VERSYM_HIDDEN) != 0 ? symbol_hidden : symbol_public;
   max_vd_ndx = 0;
 
+  /* Return the empty string for the base version.  */
+  if ((vers_data & VERSYM_VERSION) == VERSYM_BASE)
+    return "";
+
   /* Usually we'd only see verdef for defined symbols, and verneed for
      undefined symbols.  However, symbols defined by the linker in
      .dynbss for variables copied from a shared library in order to
@@ -14510,7 +14514,7 @@ get_symbol_version_string (Filedata *filedata,
      verneed.  .dynbss might not be mapped to a SHT_NOBITS section.  */
 
   if (psym->st_shndx != SHN_UNDEF
-      && vers_data != 0x8001
+      && vers_data != (VERSYM_HIDDEN | VERSYM_BASE)
       && filedata->version_info[DT_VERSIONTAGIDX (DT_VERDEF)])
     {
       Elf_Internal_Verdef ivd;
index 5d0f93ebf5694ecaeb6285ed2f58471c041f5e73..8a2ab7b055e86cfab792255536e7dab3d605dee4 100644 (file)
 
 #define VERSYM_HIDDEN          0x8000
 
+/* This flag appears in a Versym structure.  It means that the symbol
+   is the base version.  */
+
+#define VERSYM_BASE            0x0001
+
 /* This is the mask for the rest of the Versym information.  */
 
 #define VERSYM_VERSION         0x7fff
diff --git a/ld/testsuite/ld-elf/pr33599.d b/ld/testsuite/ld-elf/pr33599.d
new file mode 100644 (file)
index 0000000..9a06427
--- /dev/null
@@ -0,0 +1,11 @@
+#ld: -shared --version-script $srcdir/$subdir/pr33599.map
+#readelf : --dyn-syms --wide
+#target: *-*-linux* *-*-gnu* *-*-solaris* arm*-*-uclinuxfdpiceabi
+#xfail: ![check_shared_lib_support]
+
+Symbol table '\.dynsym' contains [0-9]+ entries:
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +OBJECT +GLOBAL +DEFAULT +[0-9]+ +bar@@
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +OBJECT +GLOBAL +DEFAULT +[0-9]+ +foo@
+#pass
diff --git a/ld/testsuite/ld-elf/pr33599.map b/ld/testsuite/ld-elf/pr33599.map
new file mode 100644 (file)
index 0000000..0f7b32a
--- /dev/null
@@ -0,0 +1,7 @@
+VERS_1 {
+  global:
+    foo;
+    bar;
+  local:
+    *;
+};
diff --git a/ld/testsuite/ld-elf/pr33599.s b/ld/testsuite/ld-elf/pr33599.s
new file mode 100644 (file)
index 0000000..f08e0c9
--- /dev/null
@@ -0,0 +1,20 @@
+       .globl foo
+       .globl foo_base
+       .type foo, %object
+       .type foo_base, %object
+       .data
+foo:
+foo_base:
+       .dc.a bar
+
+       .symver foo_base,foo@
+
+       .globl bar
+       .globl bar_base
+       .type bar, %object
+       .type bar_base, %object
+bar:
+bar_base:
+       .dc.a foo
+
+       .symver bar_base,bar@@