From: H.J. Lu Date: Sat, 15 Nov 2025 03:43:45 +0000 (+0800) Subject: elf: Verify base symbol version works properly X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=beab972c07d53ba1b0cafc2d16420c40a799bbfd;p=thirdparty%2Fbinutils-gdb.git 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 --- 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 + +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 + +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" + } + } +}