| # Expect script for -z nosectionheader and --strip-section-headers tests |
| # Copyright (C) 2023-2025 Free Software Foundation, Inc. |
| # |
| # This file is part of the GNU Binutils. |
| # |
| # This program is free software; you can redistribute it and/or modify |
| # it under the terms of the GNU General Public License as published by |
| # the Free Software Foundation; either version 3 of the License, or |
| # (at your option) any later version. |
| # |
| # This program is distributed in the hope that it will be useful, |
| # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| # GNU General Public License for more details. |
| # |
| # You should have received a copy of the GNU General Public License |
| # along with this program; if not, write to the Free Software |
| # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| # MA 02110-1301, USA. |
| # |
| # Written by H.J. Lu (hongjiu.lu@intel.com) |
| # |
| |
| if { ![istarget *-*-gnu*] } { |
| return |
| } |
| |
| proc binutils_test { prog_name ld_options test readelf_expected nm_expected} { |
| global as |
| global ld |
| global READELF |
| global NM |
| global objcopy |
| global strip |
| global srcdir |
| global subdir |
| global link_output |
| |
| eval set prog \$$prog_name |
| |
| set test_name "$prog_name --strip-section-headers $ld_options ($test)" |
| |
| if { ![ld_assemble $as $srcdir/$subdir/$test.s tmpdir/$test.o ] } { |
| unresolved "$test_name" |
| return |
| } |
| |
| append ld_options " -z separate-code -z stack-size=0" |
| if { ![ld_link $ld tmpdir/$test "$ld_options tmpdir/$test.o"] } { |
| if { [string match "*not supported*" $link_output] |
| || [string match "*unrecognized option*" $link_output] |
| || [string match "*-z .* ignored*" $link_output] } { |
| unsupported "$ld_options is not supported by this target" |
| } else { |
| unresolved "$test_name" |
| } |
| return |
| } |
| |
| send_log "$prog --strip-section-headers tmpdir/$test\n" |
| set got [remote_exec host "$prog --strip-section-headers tmpdir/$test"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| fail "$test_name" |
| return |
| } |
| |
| send_log "$READELF -lSDs --wide tmpdir/$test > tmpdir/$test.out\n" |
| set got [remote_exec host "$READELF -lSDs --wide tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "$test_name" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/$test.out" "$srcdir/$subdir/$readelf_expected"] } then { |
| fail "$test_name" |
| return |
| } |
| |
| if { [string match "*-shared *" $ld_options] } { |
| send_log "$NM -D tmpdir/$test > tmpdir/$test.out\n" |
| set got [remote_exec host "$NM -D tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "$test_name" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/$test.out" "$srcdir/$subdir/$nm_expected"] } then { |
| fail "$test_name" |
| return |
| } |
| } |
| |
| pass "$test_name" |
| } |
| |
| if { [istarget "mips*-*-*"] } { |
| set gnu_hash_style "sysv" |
| } else { |
| set gnu_hash_style "gnu" |
| } |
| |
| binutils_test objcopy "--hash-style=both" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test objcopy "--hash-style=gnu" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test objcopy "--hash-style=sysv" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test objcopy "--hash-style=both -shared" start \ |
| start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd |
| binutils_test objcopy "--hash-style=gnu -shared" start \ |
| start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd |
| binutils_test objcopy "--hash-style=sysv -shared" start \ |
| start-shared-noheader-sysv.rd start-shared-noheader.nd |
| binutils_test strip "--hash-style=both" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test strip "--hash-style=gnu" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test strip "--hash-style=sysv" start start-noheader.rd \ |
| start-noheader.nd |
| binutils_test strip "--hash-style=both -shared" start \ |
| start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd |
| binutils_test strip "--hash-style=gnu -shared" start \ |
| start-shared-noheader-$gnu_hash_style.rd start-shared-noheader.nd |
| binutils_test strip "--hash-style=sysv -shared" start \ |
| start-shared-noheader-sysv.rd start-shared-noheader.nd |
| |
| |
| if { ![check_compiler_available] || ![check_shared_lib_support] } { |
| return |
| } |
| |
| proc binutils_run_test { prog } { |
| global CC_FOR_TARGET |
| global READELF |
| global NM |
| global objcopy |
| global strip |
| global srcdir |
| global subdir |
| # Add $NOPIE_CFLAGS and $NOPIE_LDFLAGS if non-PIE is required. |
| global NOPIE_CFLAGS NOPIE_LDFLAGS |
| |
| set sec_hdr "sec-hdr" |
| if { "$prog" == "" } { |
| set prog_name none |
| } else { |
| set prog_name $prog |
| set ld_options "" |
| switch -- $prog { |
| objcopy |
| { set prog $objcopy } |
| strip |
| { set prog $strip } |
| default |
| { |
| fail "Build pr25617-1a-no-sec-hdr.so ($prog_name)" |
| break |
| } |
| } |
| } |
| |
| run_cc_link_tests [list \ |
| [list \ |
| "Build pr25617-1a-no-sec-hdr.so ($prog_name)" \ |
| "-shared -Wl,-z,separate-code,--hash-style=sysv" \ |
| "-fPIC" \ |
| {pr25617-1a.c} \ |
| [list \ |
| [list "readelf" "-lWSDs" "pr25617-1a-$sec_hdr.rd"] \ |
| [list "nm" "-D" "pr25617-1a-no-sec-hdr.nd"] \ |
| ]\ |
| "pr25617-1a-no-sec-hdr.so" \ |
| ] \ |
| [list \ |
| "Build pr25617-1a-now-no-sec-hdr.so ($prog_name)" \ |
| "-shared -Wl,-z,separate-code,-z,now,--hash-style=gnu" \ |
| "-fPIC" \ |
| {pr25617-1a.c} \ |
| [list \ |
| [list "readelf" "-lWSDs" "pr25617-1a-$sec_hdr.rd"] \ |
| [list "nm" "-D" "pr25617-1a-no-sec-hdr.nd"] \ |
| ]\ |
| "pr25617-1a-now-no-sec-hdr.so" \ |
| ] \ |
| [list \ |
| "Build pr25617-1 (-z nosectionheader, $prog_name)" \ |
| "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed \ |
| -Wl,--hash-style=sysv -Wl,-z,nosectionheader \ |
| tmpdir/pr25617-1a-no-sec-hdr.so" \ |
| "$NOPIE_CFLAGS" \ |
| {pr25617-1b.c} \ |
| {{readelf -lWSDs pr25617-1-no-sec-hdr.rd} \ |
| {nm -D pr25617-1-no-sec-hdr.nd}} \ |
| "pr25617-1-no-sec-hdr" \ |
| ] \ |
| [list \ |
| "Build pr25617-1 (PIE, -z nosectionheader, $prog_name)" \ |
| "-pie -Wl,-z,separate-code,--no-as-needed,--hash-style=gnu \ |
| -Wl,-z,nosectionheader tmpdir/pr25617-1a-now-no-sec-hdr.so" \ |
| "-fPIE" \ |
| {pr25617-1b.c} \ |
| {{readelf -lWSDs pr25617-1-no-sec-hdr.rd} \ |
| {nm -D pr25617-1-no-sec-hdr.nd}} \ |
| "pr25617-1-pie-no-sec-hdr" \ |
| ] \ |
| [list \ |
| "Build pr25617-1 (static, -z nosectionheader, $prog_name)" \ |
| "-static -Wl,-z,separate-code -Wl,-z,nosectionheader" \ |
| "" \ |
| {pr25617-1a.c pr25617-1b.c} \ |
| {{readelf -lSWDs pr25617-1-static-no-sec-hdr.rd}} \ |
| "pr25617-1-static-no-sec-hdr" \ |
| ] \ |
| ] |
| |
| run_ld_link_exec_tests [list \ |
| [list \ |
| "Run pr25617-1 (-z nosectionheader, $prog_name)" \ |
| "$NOPIE_LDFLAGS -Wl,-z,separate-code,--no-as-needed \ |
| -Wl,--hash-style=sysv -Wl,-z,nosectionheader \ |
| tmpdir/pr25617-1a-no-sec-hdr.so" \ |
| "" \ |
| {pr25617-1b.c} \ |
| "pr25617-1-no-sec-hdr" \ |
| "pass.out" \ |
| "$NOPIE_CFLAGS" \ |
| ] \ |
| [list \ |
| "Run pr25617-1 (PIE, -z nosectionheader, $prog_name)" \ |
| "-pie -Wl,-z,separate-code,--no-as-needed,--hash-style=gnu \ |
| -Wl,-z,nosectionheader tmpdir/pr25617-1a-now-no-sec-hdr.so" \ |
| "" \ |
| {pr25617-1b.c} \ |
| "pr25617-1-pie-no-sec-hdr" \ |
| "pass.out" \ |
| "-fPIE" \ |
| ] \ |
| [list \ |
| "Run pr25617-1 (static, -z nosectionheader, $prog_name)" \ |
| "-static -Wl,-z,separate-code -Wl,-z,nosectionheader" \ |
| "" \ |
| {pr25617-1a.c pr25617-1b.c} \ |
| "pr25617-1-static-no-sec-hdr" \ |
| "pass.out" \ |
| ] \ |
| ] |
| |
| if { "$prog_name" != "none" } { |
| send_log "$prog --strip-section-headers tmpdir/pr25617-1a-no-sec-hdr.so\n" |
| set got [remote_exec host "$prog --strip-section-headers tmpdir/pr25617-1a-no-sec-hdr.so"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| fail "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "$READELF -lWSDs tmpdir/pr25617-1a-no-sec-hdr.so > tmpdir/dump.out\n" |
| set got [remote_exec host "$READELF -lWSDs tmpdir/pr25617-1a-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr25617-1a-no-sec-hdr.rd"] } then { |
| unresolved "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "$NM -D tmpdir/pr25617-1a-no-sec-hdr.so > tmpdir/dump.out\n" |
| set got [remote_exec host "$NM -D tmpdir/pr25617-1a-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr25617-1a-no-sec-hdr.nd"] } then { |
| unresolved "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [isnative] } { |
| send_log "tmpdir/pr25617-1-no-sec-hdr > tmpdir/pr25617-1.out\n" |
| catch "exec tmpdir/pr25617-1-no-sec-hdr > tmpdir/pr25617-1.out" got |
| if ![string match "" $got] then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "diff tmpdir/pr25617-1.out $srcdir/$subdir/pass.out\n" |
| catch "exec diff tmpdir/pr25617-1.out $srcdir/$subdir/pass.out" got |
| if ![string match "" $got] then { |
| send_log "$got\n" |
| fail "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| } |
| |
| pass "Update pr25617-1a-no-sec-hdr.so ($prog_name)" |
| |
| send_log "$prog --strip-section-headers tmpdir/pr25617-1a-now-no-sec-hdr.so\n" |
| set got [remote_exec host "$prog --strip-section-headers tmpdir/pr25617-1a-now-no-sec-hdr.so"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| fail "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "$READELF -lWSDs tmpdir/pr25617-1a-now-no-sec-hdr.so > tmpdir/dump.out\n" |
| set got [remote_exec host "$READELF -lWSDs tmpdir/pr25617-1a-now-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr25617-1a-no-sec-hdr.rd"] } then { |
| unresolved "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "$NM -D tmpdir/pr25617-1a-now-no-sec-hdr.so > tmpdir/dump.out\n" |
| set got [remote_exec host "$NM -D tmpdir/pr25617-1a-now-no-sec-hdr.so" "" "/dev/null" "tmpdir/dump.out"] |
| if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [regexp_diff "tmpdir/dump.out" "$srcdir/$subdir/pr25617-1a-no-sec-hdr.nd"] } then { |
| unresolved "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| if { [isnative] } { |
| send_log "tmpdir/pr25617-1-pie-no-sec-hdr > tmpdir/pr25617-1-pie.out\n" |
| catch "exec tmpdir/pr25617-1-pie-no-sec-hdr > tmpdir/pr25617-1-pie.out" got |
| if ![string match "" $got] then { |
| send_log "$got\n" |
| unresolved "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| send_log "diff tmpdir/pr25617-1-pie.out $srcdir/$subdir/pass.out\n" |
| catch "exec diff tmpdir/pr25617-1-pie.out $srcdir/$subdir/pass.out" got |
| if ![string match "" $got] then { |
| send_log "$got\n" |
| fail "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| } |
| |
| set got [run_host_cmd $CC_FOR_TARGET "-o tmpdir/pr25617-1 tmpdir/pr25617-1b.o tmpdir/pr25617-1a-now-no-sec-hdr.so"] |
| if ![string match "*pr25617-1a-now-no-sec-hdr.so*file in wrong format*" $got] then { |
| send_log "$got\n" |
| fail "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| return |
| } |
| |
| pass "Update pr25617-1a-now-no-sec-hdr.so ($prog_name)" |
| } |
| } |
| |
| binutils_run_test "" |
| binutils_run_test objcopy |
| binutils_run_test strip |