From 2be0f2da2100cc2b5047f5d055cd039ac494d563 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Thu, 6 Nov 2025 08:20:26 +0800 Subject: [PATCH] readelf: Display the base symbol version as empty string 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 --- binutils/readelf.c | 8 ++++++-- include/elf/common.h | 5 +++++ ld/testsuite/ld-elf/pr33599.d | 11 +++++++++++ ld/testsuite/ld-elf/pr33599.map | 7 +++++++ ld/testsuite/ld-elf/pr33599.s | 20 ++++++++++++++++++++ 5 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 ld/testsuite/ld-elf/pr33599.d create mode 100644 ld/testsuite/ld-elf/pr33599.map create mode 100644 ld/testsuite/ld-elf/pr33599.s diff --git a/binutils/readelf.c b/binutils/readelf.c index 2d1d20413c4..933dd34d4a8 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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; diff --git a/include/elf/common.h b/include/elf/common.h index 5d0f93ebf56..8a2ab7b055e 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -1377,6 +1377,11 @@ #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 index 00000000000..9a06427aca2 --- /dev/null +++ b/ld/testsuite/ld-elf/pr33599.d @@ -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 index 00000000000..0f7b32aba6b --- /dev/null +++ b/ld/testsuite/ld-elf/pr33599.map @@ -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 index 00000000000..f08e0c91c4d --- /dev/null +++ b/ld/testsuite/ld-elf/pr33599.s @@ -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@@ -- 2.47.3