From ea9f87de71b8d5cd0f9d62ebca57cef7ee879324 Mon Sep 17 00:00:00 2001 From: Tom de Vries Date: Fri, 21 Apr 2023 18:01:00 +0200 Subject: [PATCH 5/5] [gdb/testsuite] Prevent compilation fails with unix/-fPIE/-pie A regular test-case will produce an executable, and depending on the compiler default, it will be a PIE or not. A test-case can force one or the other using the pie and nopie options. However, when running with target board unix/-fPIE/-pie, the nopie option will have no effect, and likewise for target board unix/-fno-PIE/-no-pie and the pie option. When say we run test-case gdb.base/attach-pie-noexec.exp, which passes the pie option with target board unix/-fno-PIE/-no-pie we get: ... Running src/gdb/testsuite/gdb.base/attach-pie-noexec.exp ... gdb compile failed, pie failed to generate PIE executable === gdb Summary === # of untested testcases 1 ... However, this works only when we actually manage to generate an executable. There are other test-cases, like f.i. gdb.arch/amd64-disp-step.exp that specify nopie, but will generate a compilation failure with target board unix/-fPIE/-pie due to using a hard-coded .S file: ... Running src/gdb/testsuite/gdb.arch/amd64-disp-step.exp ... gdb compile failed, ld: outputs/gdb.arch/amd64-disp-step/amd64-disp-step0.o: \ relocation R_X86_64_32S against `.text' can not be used when making a PIE \ object; recompile with -fPIE collect2: error: ld returned 1 exit status === gdb Summary === # of untested testcases 1 ... Hide this compilation error by: - adding a gdb_caching_proc pie_forced, and - using it in gdb_compile to bail out before even trying compilation such that we simply have: ... UNTESTED: gdb.arch/amd64-disp-step.exp: failed to prepare ... Likewise, add nopie_forced. Tested on x86_64-linux. --- gdb/testsuite/lib/gdb.exp | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/gdb/testsuite/lib/gdb.exp b/gdb/testsuite/lib/gdb.exp index 2be69479d70..85ef279bfe9 100644 --- a/gdb/testsuite/lib/gdb.exp +++ b/gdb/testsuite/lib/gdb.exp @@ -4966,6 +4966,17 @@ proc gdb_compile {source dest type options} { set options [lreplace $options $macros $macros $flag] } + if { $pie != -1 && [nopie_forced] } { + set result "pie unsupported" + verbose -log "gdb_compile: $result" + return $result + } + if { $nopie != -1 && [pie_forced] } { + set result "nopie unsupported" + verbose -log "gdb_compile: $result" + return $result + } + if { $type == "executable" } { if { ([istarget "*-*-mingw*"] || [istarget "*-*-*djgpp"] @@ -8875,6 +8886,48 @@ gdb_caching_proc linker_supports_image_base_flag { } +# Helper function for pie_forced. +proc pie_forced_0 { } { return 0 } + +# Return 1 if nopie fails to prevent a PIE, 0 if nopie prevented a PIE, +# and -1 if an error occurred. +gdb_caching_proc pie_forced { + set me "pie_forced" + set src { int main() { return 0; } } + # gdb_compile calls pie_forced when nopie is passed, so pretend it + # returns 0, to allow us to find out the actual pie_forced value. + with_override pie_forced pie_forced_0 { + gdb_simple_compile $me $src executable nopie + } + set res [exec_is_pie $obj] + if { $res == -1 } { + return -1 + } + set res [expr $res == 1] + return $res +} + +# Helper function for nopie_forced. +proc nopie_forced_0 {} { return 0 } + +# Return 1 if pie fails to generated a PIE, 0 if pie generated a PIE, +# and -1 if an error occurred. +gdb_caching_proc nopie_forced { + set me "nopie_forced" + set src { int main() { return 0; } } + # gdb_compile calls nopie_forced when pie is passed, so pretend it + # returns 0, to allow us to find out the actual nopie_forced value. + with_override nopie_forced nopie_forced_0 { + gdb_simple_compile $me $src executable pie + } + set res [exec_is_pie $obj] + if { $res == -1 } { + return -1 + } + set res [expr $res == 0] + return $res +} + # Return 1 if compiler supports scalar_storage_order attribute, otherwise # return 0. gdb_caching_proc supports_scalar_storage_order_attribute { -- 2.35.3