[RFC PATCH] ld: Nullify GCC default PIE in all linker tests
Jens Remus
jremus@linux.ibm.com
Fri Mar 21 17:01:17 GMT 2025
Some distributions configure GCC with --enable-default-pie. This causes
compiles to default to -fPIE and links to default to -pie, unless other
options are explicitly given. As a consequence several linker tests
are compiled and linked in unexpected ways and may even unexpectedly fail
or pass.
Test whether GCC is configured with --default-pie. Unconditionally
prepend $NOPIE_CFLAGS to the compile flags and $NOPIE_LDFLAGS to the
link flags for all linker tests to nullify GCC configured with default
PIE. These are then overridden by any deviating compiler flags
(e.g. -fPIC or -fPIE) and linker flags (e.g -pie or -shared) explicitly
specified by the tests.
Signed-off-by: Jens Remus <jremus@linux.ibm.com>
---
Notes (jremus):
With my recent "ld: Pass $NOPIE_CFLAGS and $NOPIE_LDFLAGS to more tests"
patch series I proposed to manually nullify GCC configured with default
PIE in selected linker tests. The tests addressed with that series is
far from complete.
So far I could not come up with a simple mean to determine which linker
tests are built differently when GCC is configured with default PIE, to
then manually add NOPIE_CFLAGS and NOPIE_LDFLAGS to those.
This patch proposes a programmatic approach to nullify GCC configured
with default PIE in general. Sending as RFC as this is kind of
invasive and I may not oversee all consequences.
If this or a similar solution would be accepted, it would then make
sense to get rid of NOPIE_CFLAGS and NOPIE_LDFLAGS.
Any feedback is very welcome!
ld/testsuite/lib/ld-lib.exp | 39 +++++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/ld/testsuite/lib/ld-lib.exp b/ld/testsuite/lib/ld-lib.exp
index 96152718d6f2..913fc6fc2651 100644
--- a/ld/testsuite/lib/ld-lib.exp
+++ b/ld/testsuite/lib/ld-lib.exp
@@ -220,11 +220,16 @@ proc get_board_flags {} {
proc default_ld_link { ld target objects } {
global host_triplet
global exec_output
+ global NOPIE_LDFLAGS
set flags ""
if [is_endian_output_format $objects] then {
set flags [big_or_little_endian]
}
+ # Nullify default -pie, if GCC configured with --enable-default-pie.
+ if [check_default_pie] then {
+ set flags "$flags $NOPIE_LDFLAGS"
+ }
# When using GCC as the linker driver, we need to specify board cflags when
# linking because cflags may contain linker options. For example when
@@ -257,6 +262,7 @@ proc default_ld_compile { cc source object } {
global subdir
global host_triplet
global gcc_B_opt
+ global NOPIE_CFLAGS
set cc_prog $cc
if {[llength $cc_prog] > 1} then {
@@ -271,6 +277,10 @@ proc default_ld_compile { cc source object } {
remote_file host delete "$object"
set flags "$gcc_B_opt -I$srcdir/$subdir"
+ # Nullify default -fPIE, if GCC configured with --enable-default-pie.
+ if [check_default_pie] then {
+ append flags " $NOPIE_CFLAGS"
+ }
# If we are compiling with gcc, we want to add gcc_B_opt to flags.
# However, if $prog already has -B options, which might be the
@@ -1709,3 +1719,32 @@ proc skip_sframe_tests { } {
return 1
}
+
+# Returns true if the target compiler is configured with default PIE
+proc check_default_pie { } {
+ global default_pie_saved
+ global CC_FOR_TARGET
+
+ if {![info exists default_pie_saved]} {
+ # Check if gcc is configured with --enable-default-pie
+ set flags [get_board_flags]
+ set basename "tmpdir/check_default_pie[pid]"
+ set src ${basename}.c
+ set output ${basename}.out
+ set f [open $src "w"]
+ puts $f "#ifdef __PIE__"
+ puts $f "int main() { return 0; }"
+ puts $f "#else /* ! __PIE__ */"
+ puts $f "#error \"compiler is not configured with --enable-default-pie\""
+ puts $f "#endif /* ! __PIE__ */"
+ close $f
+ if [is_remote host] {
+ set src [remote_download host $src]
+ }
+ set default_pie_saved [run_host_noleak "$CC_FOR_TARGET" "$flags $src -o $output"]
+ remote_file host delete $src
+ remote_file host delete $output
+ file delete $src
+ }
+ return $default_pie_saved
+}
--
2.45.2
More information about the Binutils
mailing list