]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
ld/ELF: Add --image-base command line option to the ELF linker
authorHakan Candar <hakancandar@protonmail.com>
Mon, 28 Oct 2024 11:01:59 +0000 (11:01 +0000)
committerAlan Modra <amodra@gmail.com>
Tue, 29 Oct 2024 09:08:39 +0000 (19:38 +1030)
LLD has dropped the option -Ttext-segment for specifying image base
addresses, instead forcing the use of the --image-base option for both
ELF and PE targets. As it stands, GNU LD and LLVM LLD are incompatible,
having two different options for the same functionality.

This patch enables the use of --image-base on ELF targets, advancing
consistency and compatibility.

See: https://reviews.llvm.org/D70468
     https://maskray.me/blog/2020-11-15-explain-gnu-linker-options#address-related
     https://sourceware.org/bugzilla/show_bug.cgi?id=25207

Moreover, a new test has been added to ensure -z separate-code behaviour
when used with -Ttext-segment stays the same. When this combination is
used, -Ttext-segment sets the address of the first segment (R), not the
text segment (RX), and like with -z noseparate-code, no segments lesser
than the specified address are created. If this behaviour was to change,
the first (R) segment of the ELF file would begin in a lesser address
than the specified text (RX) segment, breaking traditional use of this
option for specifying image base address.

ld/NEWS
ld/emultempl/beos.em
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/ld.texi
ld/ldlex.h
ld/lexsup.c
ld/testsuite/ld-elf/pr25207.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr25207.s [new file with mode: 0644]

diff --git a/ld/NEWS b/ld/NEWS
index 1f14dd6bc77b83d75d18f748048370ad5aa6a8f2..f7de85bd3ceb9ee0a5c2b993f58236a6595b262c 100644 (file)
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -2,6 +2,9 @@
 
 Changes in 2.44:
 
+* Add --image-base=<ADDR> option to the ELF linker to behave the same
+  as -Ttext-segment for compatibility with LLD.
+
 * Add a "--build-id=xx" option, if built with the xxhash library.  This
   produces a 128-bit hash, 2-4x faster than md5 or sha1.
 
index 29c386c61f8fdcf28db278262a2f376e435ae5c4..54d03537de69575dee114a6cc34b74fdda4f462f 100644 (file)
@@ -82,7 +82,6 @@ gld${EMULATION_NAME}_add_options
     {"dll", no_argument, NULL, OPTION_DLL},
     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
     {"heap", required_argument, NULL, OPTION_HEAP},
-    {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
index 9ab5e6ef481cef9dca021b8660a00daed2f2d1b2..869ffd3f6234241b9e3d65bcebd70a774fe70761 100644 (file)
@@ -251,7 +251,6 @@ gld${EMULATION_NAME}_add_options
     {"dll", no_argument, NULL, OPTION_DLL},
     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
     {"heap", required_argument, NULL, OPTION_HEAP},
-    {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
index 00c4ea9e15a765c29b15b621f53d6bfcb499e5ed..c225d052fb8876fea7899c8fc0c97c5eade1a3e2 100644 (file)
@@ -261,7 +261,6 @@ gld${EMULATION_NAME}_add_options
     {"dll", no_argument, NULL, OPTION_DLL},
     {"file-alignment", required_argument, NULL, OPTION_FILE_ALIGNMENT},
     {"heap", required_argument, NULL, OPTION_HEAP},
-    {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
     {"major-image-version", required_argument, NULL, OPTION_MAJOR_IMAGE_VERSION},
     {"major-os-version", required_argument, NULL, OPTION_MAJOR_OS_VERSION},
     {"major-subsystem-version", required_argument, NULL, OPTION_MAJOR_SUBSYSTEM_VERSION},
index b5733df00314dc2ddc5719d329f1ed962ee769df..c66ac5de4b2cf8a6802bfacb74c6714bb4383257 100644 (file)
@@ -2732,6 +2732,19 @@ for compatibility with other linkers, you may omit the leading
 should be no white space between @var{sectionname}, the equals
 sign (``@key{=}''), and @var{org}.
 
+@kindex --image-base=@var{org}
+@item --image-base=@var{org}
+@cindex image base address, cmd line
+When using ELF, same as @option{-Ttext-segment}, with both options effectively
+setting the base address of the ELF executable.
+
+When using PE, use @var{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.
+
 @kindex -Tbss=@var{org}
 @kindex -Tdata=@var{org}
 @kindex -Ttext=@var{org}
@@ -2746,7 +2759,7 @@ Same as @option{--section-start}, with @code{.bss}, @code{.data} or
 @item -Ttext-segment=@var{org}
 @cindex text segment origin, cmd line
 When creating an ELF executable, it will set the address of the first
-byte of the text segment.  Note that when @option{-pie} is used with
+byte of the first segment.  Note that when @option{-pie} is used with
 @option{-Ttext-segment=@var{org}}, the output executable is marked
 ET_EXEC so that the address of the first byte of the text segment will
 be guaranteed to be @var{org} at run time.
@@ -3392,17 +3405,6 @@ to be used as heap for this program.  The default is 1MB reserved, 4K
 committed.
 [This option is specific to the i386 PE targeted port of the linker]
 
-@cindex image base
-@kindex --image-base
-@item --image-base @var{value}
-Use @var{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.
-[This option is specific to the i386 PE targeted port of the linker]
-
 @kindex --kill-at
 @item --kill-at
 If given, the stdcall suffixes (@@@var{nn}) will be stripped from
index defe3fcbbb990e017378362f15ed617d2277f276..bb431101fb2f5dae392c82e06e5e982cd013ce81 100644 (file)
@@ -67,6 +67,7 @@ enum option_values
   OPTION_SYMBOLIC,
   OPTION_SYMBOLIC_FUNCTIONS,
   OPTION_TASK_LINK,
+  OPTION_IMAGE_BASE,
   OPTION_TBSS,
   OPTION_TDATA,
   OPTION_TTEXT,
@@ -325,7 +326,6 @@ enum option_values
   /* Used by emultempl/pe.em, emultempl/pep.em and emultempl/beos.em.  */
   OPTION_DLL,
   OPTION_FILE_ALIGNMENT,
-  OPTION_IMAGE_BASE,
   OPTION_MAJOR_IMAGE_VERSION,
   OPTION_MAJOR_OS_VERSION,
   OPTION_MAJOR_SUBSYSTEM_VERSION,
index 37d746652ca06322ddb683ed400b77e2e648b611..533535c2b89ba1450757da108afb1d62350a4ca2 100644 (file)
@@ -510,6 +510,8 @@ static const struct ld_option ld_options[] =
   { {"section-start", required_argument, NULL, OPTION_SECTION_START},
     '\0', N_("SECTION=ADDRESS"), N_("Set address of named section"),
     TWO_DASHES },
+  { {"image-base", required_argument, NULL, OPTION_IMAGE_BASE},
+    '\0', N_("ADDRESS"), N_("Set image base address"), TWO_DASHES },
   { {"Tbss", required_argument, NULL, OPTION_TBSS},
     '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH },
   { {"Tdata", required_argument, NULL, OPTION_TDATA},
@@ -1477,6 +1479,9 @@ parse_args (unsigned argc, char **argv)
        case OPTION_TTEXT:
          set_segment_start (".text", optarg);
          break;
+       case OPTION_IMAGE_BASE:
+         /* Unless PE, --image-base and -Ttext-segment behavior is the same
+            PE-specific functionality is implemented in emultempl/{pe, pep, beos}.em  */
        case OPTION_TTEXT_SEGMENT:
          set_segment_start (".text-segment", optarg);
          break;
diff --git a/ld/testsuite/ld-elf/pr25207.d b/ld/testsuite/ld-elf/pr25207.d
new file mode 100644 (file)
index 0000000..edec777
--- /dev/null
@@ -0,0 +1,11 @@
+#source: pr25207.s
+#ld: -z separate-code -Ttext-segment=0x120000 -z max-page-size=0x10000
+#readelf: -l --wide
+#target: *-*-linux* *-*-gnu* arm*-*-uclinuxfdpiceabi
+# changing -Ttext-segment behaviour will break --image-base (pr25207)
+# -Ttext-segment=<ADDR> should set the first segment address,
+# not necessarily the first executable segment.
+
+#...
+  LOAD +0x0+ 0x0*120000 0x0*120000 0x[0-9a-f]+ 0x[0-9a-f]+ R   .*
+#pass
diff --git a/ld/testsuite/ld-elf/pr25207.s b/ld/testsuite/ld-elf/pr25207.s
new file mode 100644 (file)
index 0000000..6cfdfd0
--- /dev/null
@@ -0,0 +1,13 @@
+       .section .text, "ax"
+       .globl  main
+       .globl  start
+       .globl  _start
+       .globl  __start
+main:
+start:
+_start:
+__start:
+       .byte 0
+
+       .section .rodata
+       .byte 0