[PATCH 2/2] ld: testsuite: Add sframe test for PR 33401

claudiu.zissulescu-ianculescu@oracle.com claudiu.zissulescu-ianculescu@oracle.com
Wed Dec 3 09:20:50 GMT 2025
From: Claudiu Zissulescu <claudiu.zissulescu-ianculescu@oracle.com>

When linking for a relocable output file (-r), one or more R_*_NONE
relocations may be generated for .sframe section. Two new tcl
procedures are added to sframe.exp file. 'check-dump' is checking if
an input bin file has the same relocation as specified in the second
input argument. 'check_pr33401' is the main checking function for
PR33401 which calls twice the ld tool to produce an relocable output
file.

ld:

	PR ld/33401
	* testsuite/ld-sframe/StateClient.cpp:  New file.
	* testsuite/ld-sframe/StatePlaying.cpp: Likewise.
	* testsuite/ld-sframe/pr33401.rd: Likewise.
	* testsuite/ld-sframe/sframe.exp (check_dump): New procedure.
	(check_pr33401): Likewise.
---
 ld/testsuite/ld-sframe/StateClient.cpp  |  26 ++++++
 ld/testsuite/ld-sframe/StatePlaying.cpp |  41 +++++++++
 ld/testsuite/ld-sframe/pr33401.rd       |   3 +
 ld/testsuite/ld-sframe/sframe.exp       | 114 ++++++++++++++++++++++++
 4 files changed, 184 insertions(+)
 create mode 100644 ld/testsuite/ld-sframe/StateClient.cpp
 create mode 100644 ld/testsuite/ld-sframe/StatePlaying.cpp
 create mode 100644 ld/testsuite/ld-sframe/pr33401.rd

diff --git a/ld/testsuite/ld-sframe/StateClient.cpp b/ld/testsuite/ld-sframe/StateClient.cpp
new file mode 100644
index 00000000000..0154469ce6c
--- /dev/null
+++ b/ld/testsuite/ld-sframe/StateClient.cpp
@@ -0,0 +1,26 @@
+void a(void *);
+class b {
+  long ag;
+  bool c();
+  void m_fn2() {
+    if (c())
+      d(ag);
+  }
+  void d(long);
+
+public:
+  ~b() { m_fn2(); }
+};
+class Player {
+  int *an;
+  b ao;
+  char be;
+
+public:
+  virtual ~Player() {
+    a(&be);
+    a(&be);
+    a(&be);
+    delete an;
+  }
+} e;
diff --git a/ld/testsuite/ld-sframe/StatePlaying.cpp b/ld/testsuite/ld-sframe/StatePlaying.cpp
new file mode 100644
index 00000000000..f61c32d54c1
--- /dev/null
+++ b/ld/testsuite/ld-sframe/StatePlaying.cpp
@@ -0,0 +1,41 @@
+void b(void *);
+class c {
+public:
+  long am;
+  bool d();
+  void e() {
+    if (d())
+      f(am);
+  }
+  void f(long);
+  ~c() { e(); }
+};
+class g {
+public:
+  virtual ~g();
+};
+class Player {
+  int *bh;
+  c bi;
+  char bj;
+
+public:
+  virtual ~Player() {
+    b(&bj);
+    b(&bj);
+    b(&bj);
+    delete bh;
+  }
+};
+class h {
+public:
+  ~h() {
+    Player *a[0];
+    delete a[0];
+  }
+};
+class i : g {
+  h bo;
+  virtual int j();
+};
+int i::j() {}
diff --git a/ld/testsuite/ld-sframe/pr33401.rd b/ld/testsuite/ld-sframe/pr33401.rd
new file mode 100644
index 00000000000..00142818b34
--- /dev/null
+++ b/ld/testsuite/ld-sframe/pr33401.rd
@@ -0,0 +1,3 @@
+#...
+[0-9a-f]+ +0+ +R_.*_NONE +.*
+#pass
\ No newline at end of file
diff --git a/ld/testsuite/ld-sframe/sframe.exp b/ld/testsuite/ld-sframe/sframe.exp
index 61dc4dafa2e..42faeafca5f 100644
--- a/ld/testsuite/ld-sframe/sframe.exp
+++ b/ld/testsuite/ld-sframe/sframe.exp
@@ -18,6 +18,118 @@
 # MA 02110-1301, USA.
 #
 
+proc check_dump { binfile dumpfile } {
+    global srcdir
+    global READELF
+    global subdir
+    global env
+    global runtests
+
+    set binary $READELF
+    set progopts "-j .rela.sframe"
+    set failed 0
+
+    # Ensure consistent sorting of symbols
+    if {[info exists env(LC_ALL)]} {
+	set old_lc_all $env(LC_ALL)
+    }
+    set env(LC_ALL) "C"
+    set cmd "$binary $progopts $binfile > dump.out"
+    send_log "$cmd\n"
+    catch "exec $cmd" comp_output
+    if {[info exists old_lc_all]} {
+	set env(LC_ALL) $old_lc_all
+    } else {
+	unset env(LC_ALL)
+    }
+    set comp_output [prune_warnings $comp_output]
+    if ![string match "" $comp_output] then {
+	send_log "$comp_output\n"
+	return 1
+    }
+
+    if { [regexp_diff "dump.out" "$srcdir/$subdir/$dumpfile"] } then {
+	verbose -log "output is [file_contents "dump.out"]" 2
+	return 1
+    }
+    return 0
+}
+
+# Test infrastructure for bug 33401
+# https://sourceware.org/bugzilla/show_bug.cgi?id=33401
+# Sframe section contains R_*_NONE relocations intermingled with other
+# relas in the output relocatable object.
+#
+# src_files filenames of assembler files
+proc check_pr33401 { src_files } {
+    global ld
+    global CXX_FOR_TARGET
+    global as
+    global LDFLAGS
+    global srcdir
+    global subdir
+    global env
+    global runtests
+
+    set objfiles {}
+    set testname "PR33401"
+    set failed 0
+    set linkfile "tmpdir/automa_module.o"
+
+    if ![runtest_file_p $runtests $testname] then {
+	return 0
+    }
+
+    # Assemble each file in the test.
+    foreach src_file $src_files {
+	set fileroot "[file rootname [file tail $src_file]]"
+	set objfile "tmpdir/$fileroot.o"
+
+	if { [file extension $src_file] == ".cpp" } {
+	    set as_file "tmpdir/$fileroot.s"
+	    if ![ld_compile "$CXX_FOR_TARGET -S -O2 -w" $srcdir/$subdir/$src_file $as_file] {
+		set failed 1
+		break
+	    }
+	} else {
+	    set as_file "$srcdir/$subdir/$src_file"
+	}
+	if { ![ld_assemble $as "--gsframe $as_file" $objfile] } {
+	    set failed 1
+	    break
+	}
+	lappend objfiles $objfile
+    }
+
+    # Catch assembler errors.
+    if { $failed } {
+	verbose -log "Error during assembling one if the input files."
+	unresolved $testname
+	return 0
+    }
+
+    # Do the first linking. If this fails, we cannot resolve the test.
+    if { ![ld_link $ld $linkfile "-L$srcdir/$subdir -r $objfiles"] } {
+	verbose -log "Error during linking assembled objects."
+	unresolved $testname
+	return 0
+    }
+
+    # Check the output of the first ld invocation
+    if { [check_dump $linkfile pr33401.rd] } {
+	verbose -log "No R_*_NONE in .rela.sframe"
+	unresolved $testname
+	return 0
+    }
+
+    # Check if the second ld -r invocation is ok
+    if { ![ld_link $ld /dev/null "-L$srcdir/$subdir -r $linkfile"] } {
+	fail $testname
+    } else {
+	pass $testname
+    }
+}
+
 if [skip_sframe_tests] {
     unsupported "no SFrame format support in the assembler, or SFrame disabled"
     return 0
@@ -40,6 +152,8 @@ foreach sframe_test $sframe_test_list {
     run_dump_test [file rootname $sframe_test]
 }
 
+check_pr33401 {StateClient.cpp  StatePlaying.cpp}
+
 if {[info exists old_lc_all]} {
     set env(LC_ALL) $old_lc_all
 } else {
-- 
2.52.0



More information about the Binutils mailing list