[PATCH 3/3] binutils/testsuite: test compress-debug-info round trip

Tobias Deiminger tobias.deiminger@linutronix.de
Mon Sep 28 09:01:46 GMT 2026


This adds a new test case that basically runs

 target_cc testprog.c testprog
 for every enabled BFD target
   objcopy -I <host> -O <target> testprog  # reformat to target
   objcopy --compress-debug-sections       # compress
   objdump --dwarf=info                    # main()/fn() info expected
   objcopy --decompress-debug-sections     # decompress
   objdump --dwarf=info                    # main()/fn() info expected

The input test vector is generated best effort (whatever target formats
can be created by objcopy reformatting from target compiler output as
starting point).

To increase coverage, this test can be repeated in multiple
--target=[x,y,z] build configurations.

Signed-off-by: Tobias Deiminger <tobias.deiminger@linutronix.de>
---
I tested the following configurations locally, leading to following
coverage:

configure --target=x86_64-pc-linux-gnu, 14 targets covered:
coff-go32 coff-go32-exe elf32-little elf32-x86-64 elf64-little
elf64-x86-64 elf64-x86-64-freebsd elf64-x86-64-sol2 pe-bigobj-i386
pe-bigobj-x86-64 pe-i386 pe-x86-64 pei-i386 pei-x86-64

configure --target=x86_64-w64-mingw32, 10 targets covered:
elf32-i386 elf32-little elf64-little elf64-x86-64 pe-bigobj-i386
pe-bigobj-x86-64 pe-i386 pe-x86-64 pei-i386 pei-x86-64

configure --target=aarch64-linux-gnu, 6 targets covered:
elf32-little elf32-littleaarch64 elf64-little elf64-littleaarch64
pe-aarch64-little pei-aarch64-little

configure --target=riscv64-linux-gnu, 5 targets covered:
elf32-little elf32-littleriscv elf64-little elf64-littleriscv
pei-riscv64-little

Note that the new test reveals another unrelated bug where

 objcopy -I elf64-x86-64 -O elf32-i386 testprog testprog-elf32-i386

produces invalid output that can't be processed further by objdump
("file format not recognized"). The issue isn't fixed here, since it
doesn't block the series. The test skips over it as unsupported.

 binutils/testsuite/binutils-all/compress.exp | 104 ++++++++++++++++++-
 1 file changed, 103 insertions(+), 1 deletion(-)

diff --git a/binutils/testsuite/binutils-all/compress.exp b/binutils/testsuite/binutils-all/compress.exp
index ae2bf8010f8..1dd2389e21b 100644
--- a/binutils/testsuite/binutils-all/compress.exp
+++ b/binutils/testsuite/binutils-all/compress.exp
@@ -14,9 +14,111 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
+if { [is_remote host] } then {
+    return
+}
+
+proc assert_testprog_debug_info { testname target testprog_bin expected } {
+    global OBJDUMP
+
+    set dwarf_info_lines [split [binutils_run $OBJDUMP "-b $target --dwarf=info $testprog_bin"] \n]
+    set expected_nr [llength $expected]
+    set dw_lines_nr [llength $dwarf_info_lines]
+    for {set i 0} {$i < $dw_lines_nr} {incr i} {
+	set line [lindex $dwarf_info_lines $i]
+	set is_entry_start [string equal -length 2 " <" $line]
+	if { !$is_entry_start && [regexp {DW_AT_(\S+)\s*:.*\s(\S+)$} $line -> attr value] } {
+	    set dw_entry($attr) $value
+	}
+	if { $is_entry_start || $i == $dw_lines_nr - 1 } {
+	    if { [info exists dw_entry(name)] && [info exists dw_entry(decl_line)]
+		&& [lsearch -exact $expected [list $dw_entry(name) $dw_entry(decl_line)]] >= 0 } {
+		incr expected_nr -1
+	    }
+	    array unset dw_entry
+	}
+    }
+    if { $expected_nr == 0 } {
+	pass "$testname"
+    } else {
+	fail "$testname"
+    }
+}
+
+proc test_compress_decompress_roundtrip_all_targets {} {
+    global binutils_run_status
+    global srcdir
+    global subdir
+    global OBJCOPY
+    global OBJDUMP
+
+    set test "objcopy compress debug sections round trip"
+    set known_unsupported_targets {
+	msdos binary srec symbolsrec ihex verilog wasm
+	coff-i386 coff-i386-lynx coff-x86-64
+    }
+    set test_in_host "tmpdir/testprog[exeext]"
+
+    if { [target_compile $srcdir/$subdir/testprog.c $test_in_host executable debug] != "" } {
+	unsupported "$test (can't compile testprog)"
+	return
+    }
+
+    set objdump_out [binutils_run $OBJDUMP "-f $test_in_host"]
+    if { ![regexp {file format (\S+)} $objdump_out -> input_fmt] } {
+	unsupported "$test (can't determine BFD input format)"
+	return
+    }
+
+    set info [split [binutils_run $OBJCOPY "--info"] \n]
+    set enabled_targets [lsort -unique [lsearch -all -inline -regexp [lrange $info 1 end] {^[[:alnum:]]}]]
+
+    set tested 0
+    set expected { {fn 12} {main 18} }
+    foreach target $enabled_targets {
+	if { [lsearch -exact $known_unsupported_targets $target] >= 0 } continue
+
+	set test_in "tmpdir/testprog-[string map {/ _} $target]"
+	set test_z   "${test_in}.z"
+	set test_unz "${test_in}.unz"
+
+	binutils_run $OBJCOPY "-I $input_fmt -O $target $test_in_host $test_in"
+	if { $binutils_run_status != 0 } continue
+	binutils_run $OBJDUMP "-f -b $target $test_in"
+	if { $binutils_run_status != 0 } {
+	    unsupported "$test ($target, unreadable after conversion from $input_fmt)"
+	    continue
+	}
+
+	incr tested
+	set testname "$test (compress, $target)"
+
+	binutils_run $OBJCOPY "-I $target --compress-debug-sections $test_in $test_z"
+	if { $binutils_run_status != 0 } {
+	    fail $testname
+	    continue
+	}
+	assert_testprog_debug_info $testname $target $test_z $expected
+
+	set testname "$test (decompress, $target)"
+	binutils_run $OBJCOPY "-I $target --decompress-debug-sections $test_z $test_unz"
+	if { $binutils_run_status != 0 } {
+	    fail $testname
+	    continue
+	}
+	assert_testprog_debug_info $testname $target $test_unz $expected
+    }
+
+    if { $tested == 0 } {
+	unsupported "$test (no compatible targets found)"
+    }
+}
+
+test_compress_decompress_roundtrip_all_targets
+
 # Test compressed .debug section.
 
-if { [is_remote host] || ![is_elf_format] } then {
+if { ![is_elf_format] } then {
     return
 }
 
-- 
2.55.0



More information about the Binutils mailing list