[binutils-gdb] elf: Verify base symbol version works properly

H.J. Lu hjl@sourceware.org
Mon Nov 24 00:15:19 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=beab972c07d53ba1b0cafc2d16420c40a799bbfd

commit beab972c07d53ba1b0cafc2d16420c40a799bbfd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sat Nov 15 11:43:45 2025 +0800

    elf: Verify base symbol version works properly
    
    Add a testcase to verify that VER_NDX_GLOBAL can be used with
    
    asm (".symver foo_base, foo@");
    
    to create the base version to provide an unversioned compatible symbol.
    
            PR ld/33577
            * testsuite/ld-elfvers/pass.out: New file.
            * testsuite/ld-elfvers/pr33577-unversioned.c: Likewise.
            * testsuite/ld-elfvers/pr33577-unversioned.rd: Likewise.
            * testsuite/ld-elfvers/pr33577-versioned.c: Likewise.
            * testsuite/ld-elfvers/pr33577-versioned.rd: Likewise.
            * testsuite/ld-elfvers/pr33577.map: Likewise.
            * testsuite/ld-elfvers/pr33577a.c: Likewise.
            * testsuite/ld-elfvers/pr33577b.c: Likewise.
            * testsuite/ld-elfvers/vers.exp: Run ld/33577 tests.
    
    Signed-off-by: H.J. Lu <hjl.tools@gmail.com>

Diff:
---
 ld/testsuite/ld-elfvers/pass.out               |  1 +
 ld/testsuite/ld-elfvers/pr33577-unversioned.c  |  9 +++
 ld/testsuite/ld-elfvers/pr33577-unversioned.rd |  7 ++
 ld/testsuite/ld-elfvers/pr33577-versioned.c    | 18 +++++
 ld/testsuite/ld-elfvers/pr33577-versioned.rd   |  7 ++
 ld/testsuite/ld-elfvers/pr33577.map            |  6 ++
 ld/testsuite/ld-elfvers/pr33577a.c             | 17 +++++
 ld/testsuite/ld-elfvers/pr33577b.c             | 17 +++++
 ld/testsuite/ld-elfvers/vers.exp               | 96 ++++++++++++++++++++++++++
 9 files changed, 178 insertions(+)

diff --git a/ld/testsuite/ld-elfvers/pass.out b/ld/testsuite/ld-elfvers/pass.out
new file mode 100644
index 00000000000..7ef22e9a431
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pass.out
@@ -0,0 +1 @@
+PASS
diff --git a/ld/testsuite/ld-elfvers/pr33577-unversioned.c b/ld/testsuite/ld-elfvers/pr33577-unversioned.c
new file mode 100644
index 00000000000..e2577759203
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577-unversioned.c
@@ -0,0 +1,9 @@
+extern int foo (void);
+extern void bar (void);
+
+int
+foo (void)
+{
+  bar ();
+  return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/pr33577-unversioned.rd b/ld/testsuite/ld-elfvers/pr33577-unversioned.rd
new file mode 100644
index 00000000000..8ce9ea71115
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577-unversioned.rd
@@ -0,0 +1,7 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +UND +_?bar
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +GLOBAL +DEFAULT .*[0-9]+ _?foo
+#pass
diff --git a/ld/testsuite/ld-elfvers/pr33577-versioned.c b/ld/testsuite/ld-elfvers/pr33577-versioned.c
new file mode 100644
index 00000000000..e33417c14c5
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577-versioned.c
@@ -0,0 +1,18 @@
+extern int foo (void);
+extern int foo_base (void);
+extern void bar (void);
+
+int
+foo (void)
+{
+  return 1;
+}
+
+int
+foo_base (void)
+{
+  bar ();
+  return 0;
+}
+
+asm (".symver foo_base, foo@");
diff --git a/ld/testsuite/ld-elfvers/pr33577-versioned.rd b/ld/testsuite/ld-elfvers/pr33577-versioned.rd
new file mode 100644
index 00000000000..1a579bc9357
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577-versioned.rd
@@ -0,0 +1,7 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[a-f0-9]+ +0 +NOTYPE +GLOBAL +DEFAULT +UND +_?bar
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +GLOBAL +DEFAULT .*[0-9]+ _?foo@
+#pass
diff --git a/ld/testsuite/ld-elfvers/pr33577.map b/ld/testsuite/ld-elfvers/pr33577.map
new file mode 100644
index 00000000000..4be898be3f0
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577.map
@@ -0,0 +1,6 @@
+VERS_1 {
+  global:
+    foo;
+  local:
+    *;
+};
diff --git a/ld/testsuite/ld-elfvers/pr33577a.c b/ld/testsuite/ld-elfvers/pr33577a.c
new file mode 100644
index 00000000000..97f9efa76c6
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577a.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+extern int foo (void);
+extern void bar (void);
+
+void
+bar (void)
+{
+}
+
+int
+main ()
+{
+  if (foo () == 0)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/pr33577b.c b/ld/testsuite/ld-elfvers/pr33577b.c
new file mode 100644
index 00000000000..d40715e6402
--- /dev/null
+++ b/ld/testsuite/ld-elfvers/pr33577b.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+extern int foo (void);
+extern void bar (void);
+
+void
+bar (void)
+{
+}
+
+int
+main ()
+{
+  if (foo () == 1)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-elfvers/vers.exp b/ld/testsuite/ld-elfvers/vers.exp
index 80faaa01079..d744c3600e8 100644
--- a/ld/testsuite/ld-elfvers/vers.exp
+++ b/ld/testsuite/ld-elfvers/vers.exp
@@ -1018,3 +1018,99 @@ build_vers_lib_pic "vers31" vers31.c vers31 "" vers31.map vers31.ver vers31.dsym
 # Test #32 -- linker --defsym
 build_vers_lib_pic "vers32a" vers32a.c vers32a "" vers32.map vers32a.ver vers32a.dsym ""
 build_vers_lib_pic_flags "vers32b" vers32b.c vers32b "vers32a.so" vers32.map vers32b.ver vers32b.dsym "" "--defsym foo=0"
+
+if [check_compiler_available] {
+    run_cc_link_tests [list \
+	[list \
+	    "Build pr33577-unversioned.so" \
+	    "-shared -Wl,-soname,libpr33577.so" \
+	    "-fPIC" \
+	    { pr33577-unversioned.c } \
+	    {{readelf {--dyn-syms -W} pr33577-unversioned.rd}} \
+	    "libpr33577-unversioned.so" \
+	] \
+	[list \
+	    "Build pr33577-versioned.so" \
+	    "-shared -Wl,-soname,libpr33577.so,--version-script=pr33577.map" \
+	    "-fPIC" \
+	    { pr33577-versioned.c } \
+	    {{readelf {--dyn-syms -W} pr33577-versioned.rd}} \
+	    "libpr33577-versioned.so" \
+	] \
+    ]
+
+    set cmd "cp tmpdir/libpr33577-unversioned.so tmpdir/libpr33577.so"
+    send_log "$cmd\n"
+    remote_exec host "$cmd"
+
+    run_cc_link_tests [list \
+	[list \
+	    "Build pr33577a with tmpdir/libpr33577-unversioned.so" \
+	    "" \
+	    "" \
+	    { pr33577a.c } \
+	    "" \
+	    "pr33577a" \
+	    "c" \
+	    "tmpdir/libpr33577.so" \
+	] \
+    ]
+
+    if [isnative] {
+	run_ld_link_exec_tests [list \
+	    [list \
+		"Run pr33577a with tmpdir/libpr33577-unversioned.so" \
+		"-Wl,-R,tmpdir" \
+		"" \
+		{ pr33577a.c } \
+		"pr33577a" \
+		"pass.out" \
+		"" \
+		"c" \
+		"" \
+		"tmpdir/libpr33577.so" \
+	    ] \
+	] \
+    }
+
+    set cmd "cp tmpdir/libpr33577-versioned.so tmpdir/libpr33577.so"
+    send_log "$cmd\n"
+    remote_exec host "$cmd"
+
+    run_cc_link_tests [list \
+	[list \
+	    "Build pr33577b with tmpdir/libpr33577-versioned.so" \
+	    "-Wl,-R,tmpdir" \
+	    "" \
+	    { pr33577b.c } \
+	    "" \
+	    "pr33577b" \
+	    "c" \
+	    "tmpdir/libpr33577.so" \
+	] \
+    ]
+
+    if [isnative] {
+	set test_name "Run pr33577a with tmpdir/libpr33577-versioned.so"
+	set cmd tmpdir/pr33577a
+	send_log "$cmd\n"
+	set got [remote_exec host "$cmd"]
+	if { [lindex $got 0] == 0 && [regexp "PASS" [lindex $got 1]] } then {
+	    pass "$test_name"
+	} else {
+	    send_log "$got\n"
+	    fail "$test_name"
+	}
+
+	set test_name "Run pr33577b with tmpdir/libpr33577-versioned.so"
+	set cmd tmpdir/pr33577b
+	send_log "$cmd\n"
+	set got [remote_exec host "$cmd"]
+	if { [lindex $got 0] == 0 && [regexp "PASS" [lindex $got 1]] } then {
+	    pass "$test_name"
+	} else {
+	    send_log "$got\n"
+	    fail "$test_name"
+	}
+    }
+}


More information about the Binutils-cvs mailing list