[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