[v3] elf: Set image base address to the maximum page size

Message ID CAMe9rOpP7iERnrXuqB3zSOay7ULihiS3o3a-QyARzJeouR5P5Q@mail.gmail.com
State New
Headers
Series [v3] elf: Set image base address to the maximum page size |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

H.J. Lu June 20, 2026, 12:58 a.m. UTC
  On Fri, Jun 19, 2026 at 9:01 PM Jan Beulich <jbeulich@suse.com> wrote:
>
> On 28.05.2026 09:16, H.J. Lu wrote:
> > On Thu, May 28, 2026 at 11:08 AM H.J. Lu <hjl.tools@gmail.com> wrote:
> >>
> >> When generating Position Dependent Executable for ELF with the maximum
> >> page size set on command-line, if text-segment address is lower than the
> >> maximum page size, set text-segment address to the maximum page size.
> >>
> >> PR ld/34184
> >> * ldexp.c (fold_binary): Set text-segment address to the maximum
> >> page size for ELF PDE output with -z max-page-size=SIZE.
> >> * testsuite/ld-elf/elf.exp: Add ld/34184 test.
> >> * testsuite/ld-elf/pr34184.c: New file.
> >
> > Here is the v2 patch to add tests for PIE, static PDE and static PIE.
>
> Why is this special to text-segment? Doesn't something like this need
> doing either for all segments, or for whatever is the first segment?
>
> Jan

  -Ttext-segment ADDRESS      Set address of text segment

is kind of misleading.  --image-base is a better name:

‘--image-base=ORG’
     When using ELF, same as ‘-Ttext-segment’, with both options
     effectively setting the base address of the ELF executable.

     When using PE, use VALUE as the base address of your program or
     dll.  This is the lowest memory location that will be used when
     your program or dll is loaded.  To reduce the need to relocate and
     improve performance of your dlls, each should have a unique base
     address and not overlap any other dlls.  The default is 0x400000
     for executables, and 0x10000000 for dlls.

Here is the v3 patch to use image base address instead of text-segment
address.
  

Patch

From 86c2466b8ce4a917c85e388de38dab05c0dd7e4c Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Thu, 28 May 2026 10:47:37 +0800
Subject: [PATCH v3] elf: Set image base address to the maximum page size

When generating Position Dependent Executable for ELF with the maximum
page size set on command-line, if image base address is lower than the
maximum page size, set image base address to the maximum page size.

	PR ld/34184
	* ldexp.c (fold_binary): Set image base address to the maximum
	page size for ELF PDE output with -z max-page-size=SIZE.
	* testsuite/ld-elf/elf.exp: Add ld/34184 tests for PDE, PIE
	static PDE and static PIE.
	* testsuite/ld-elf/pr34184.c: New file.

Signed-off-by: H.J. Lu <hjl.tools@gmail.com>
---
 ld/ldexp.c                    | 15 +++++++++++++++
 ld/testsuite/ld-elf/elf.exp   | 36 +++++++++++++++++++++++++++++++++++
 ld/testsuite/ld-elf/pr34184.c |  8 ++++++++
 3 files changed, 59 insertions(+)
 create mode 100644 ld/testsuite/ld-elf/pr34184.c

diff --git a/ld/ldexp.c b/ld/ldexp.c
index 7bda6acc4c9..376c82b0b24 100644
--- a/ld/ldexp.c
+++ b/ld/ldexp.c
@@ -552,6 +552,21 @@  fold_binary (etree_type *tree)
       /* Check to see if the user has overridden the default
 	 value.  */
       segment_name = tree->binary.rhs->name.name;
+
+      /* When generating Position Dependent Executable for ELF with the
+	 maximum page size set on command-line, if image base address
+	 is lower than the maximum page size, set image base address
+	 to the maximum page size.  NB: For ELF, -Ttext-segment=ADDR is
+	 an alias of --image-base=ADDR, which sets the base address of
+	 the ELF executable.  */
+      if ((bfd_get_flavour (link_info.output_bfd)
+	   == bfd_target_elf_flavour)
+	  && bfd_link_pde (&link_info)
+	  && link_info.maxpagesize_is_set
+	  && link_info.maxpagesize > value
+	  && strcmp (segment_name, "text-segment") == 0)
+	value = link_info.maxpagesize;
+
       for (seg = segments; seg; seg = seg->next)
 	if (strcmp (seg->name, segment_name) == 0)
 	  {
diff --git a/ld/testsuite/ld-elf/elf.exp b/ld/testsuite/ld-elf/elf.exp
index 8fca30dbeeb..51b8c942648 100644
--- a/ld/testsuite/ld-elf/elf.exp
+++ b/ld/testsuite/ld-elf/elf.exp
@@ -535,6 +535,15 @@  if { [istarget *-*-linux*]
 		"pr14525.out" \
 		"-fPIE" \
 	    ] \
+	    [list \
+		"Run PR ld/34184 test (static PIE)" \
+		"-pie -Wl,-z,max-page-size=0x800000" \
+		"" \
+		{pr34184.c} \
+		"pr34184-static-pie" \
+		"pass.out" \
+		"-fPIE" \
+	    ] \
 	]
     }
 
@@ -580,6 +589,33 @@  if { [istarget *-*-linux*]
 	    {} \
 	    "-Wl,-R,tmpdir tmpdir/pr32690.so" \
 	] \
+	[list \
+	    "Run PR ld/34184 test (PDE)" \
+	    "$NOPIE_LDFLAGS -Wl,-z,max-page-size=0x800000" \
+	    "" \
+	    {pr34184.c} \
+	    "pr34184-pde" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run PR ld/34184 test (static PDE)" \
+	    "-static $NOPIE_LDFLAGS -Wl,-z,max-page-size=0x800000" \
+	    "" \
+	    {pr34184.c} \
+	    "pr34184-static-pde" \
+	    "pass.out" \
+	    "$NOPIE_CFLAGS" \
+	] \
+	[list \
+	    "Run PR ld/34184 test (PIE)" \
+	    "-pie -Wl,-z,max-page-size=0x800000" \
+	    "" \
+	    {pr34184.c} \
+	    "pr34184-pie" \
+	    "pass.out" \
+	    "-fPIE" \
+	] \
     ]
 }
 
diff --git a/ld/testsuite/ld-elf/pr34184.c b/ld/testsuite/ld-elf/pr34184.c
new file mode 100644
index 00000000000..8fb892c6aaa
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr34184.c
@@ -0,0 +1,8 @@ 
+#include <stdio.h>
+
+int
+main ()
+{
+  printf ("PASS\n");
+  return 0;
+}
-- 
2.54.0