[lld] 4dc2fb1 - [ELF] Error if -Ttext-segment is specified

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Thu Nov 21 09:42:53 PST 2019


Author: Fangrui Song
Date: 2019-11-21T09:41:55-08:00
New Revision: 4dc2fb123dcfe9a97ad6f3a1135053b74efd0bc9

URL: https://github.com/llvm/llvm-project/commit/4dc2fb123dcfe9a97ad6f3a1135053b74efd0bc9
DIFF: https://github.com/llvm/llvm-project/commit/4dc2fb123dcfe9a97ad6f3a1135053b74efd0bc9.diff

LOG: [ELF] Error if -Ttext-segment is specified

In GNU ld, -Ttext sets the address of the .text section and -Ttext-segment sets the address of the text segment (RX).

gold only supports the -Ttext-segment semantic and treats -Ttext as an alias for -Ttext-segment.

lld only supports the -Ttext semantic and treats -Ttext-segment as an
alias for -Ttext.  The text segment will be assigned to an address less
than the specified -Ttext-segment value.

This patch drops the -Ttext-segment alias.

The text segment is traditionally the first segment. Users who specify
-Ttext-segment may actually want to specify --image-base, the lld way to
express this. Unfortunately currently this is supported by GNU ld's
COFF port but not by its ELF port. gold does not support this option.
With -z separate-code, the behavior of GNU ld -Ttext-segment is weird (see https://sourceware.org/bugzilla/show_bug.cgi?id=25207)

rL289827 introduced the alias for linking qemu's non-pie user mode
binaries. As explained previously, this actually assigns the text
segment to an address less than 0x60000000. I feel that a better fix is
on the qemu side:
https://lists.nongnu.org/archive/html/qemu-devel/2019-11/msg02480.html

Reviewed By: grimar, ruiu

Differential Revision: https://reviews.llvm.org/D70468

Added: 
    lld/test/ELF/ttext-segment.s

Modified: 
    lld/ELF/Driver.cpp
    lld/ELF/Options.td
    lld/test/ELF/sectionstart.s

Removed: 
    


################################################################################
diff  --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index f7ce7358bb78..ca1a9ed92130 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1012,6 +1012,14 @@ static void readConfigs(opt::InputArgList &args) {
   if (config->splitStackAdjustSize < 0)
     error("--split-stack-adjust-size: size must be >= 0");
 
+  // The text segment is traditionally the first segment, whose address equals
+  // the base address. However, lld places the R PT_LOAD first. -Ttext-segment
+  // is an old-fashioned option that does not play well with lld's layout.
+  // Suggest --image-base as a likely alternative.
+  if (args.hasArg(OPT_Ttext_segment))
+    error("-Ttext-segment is not supported. Use --image-base if you "
+          "intend to set the base address");
+
   // Parse ELF{32,64}{LE,BE} and CPU type.
   if (auto *arg = args.getLastArg(OPT_m)) {
     StringRef s = arg->getValue();

diff  --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index c6773d0122e0..101fc438f703 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -59,6 +59,8 @@ defm Tdata: Eq<"Tdata", "Same as --section-start with .data as the sectionname">
 
 defm Ttext: Eq<"Ttext", "Same as --section-start with .text as the sectionname">;
 
+def Ttext_segment: Separate<["-", "--"], "Ttext-segment">;
+
 defm allow_multiple_definition: B<"allow-multiple-definition",
     "Allow multiple definitions",
     "Do not allow multiple definitions (default)">;
@@ -462,9 +464,8 @@ def: Flag<["-"], "(">, Alias<start_group>, HelpText<"Alias for --start-group">;
 def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
 def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
 def: Flag<["-"], "t">, Alias<trace>, HelpText<"Alias for --trace">;
+def: Joined<["-", "--"], "Ttext-segment=">, Alias<Ttext_segment>;
 def: JoinedOrSeparate<["-"], "y">, Alias<trace_symbol>, HelpText<"Alias for --trace-symbol">;
-def: Separate<["-", "--"], "Ttext-segment">, Alias<Ttext>, HelpText<"Alias for --Ttext">;
-def: Joined<["-", "--"], "Ttext-segment=">, Alias<Ttext>, HelpText<"Alias for --Ttext">;
 def: JoinedOrSeparate<["-"], "u">, Alias<undefined>, HelpText<"Alias for --undefined">;
 def: Flag<["-"], "V">, Alias<version>, HelpText<"Alias for --version">;
 

diff  --git a/lld/test/ELF/sectionstart.s b/lld/test/ELF/sectionstart.s
index 771d28e04592..f404a92f6f1a 100644
--- a/lld/test/ELF/sectionstart.s
+++ b/lld/test/ELF/sectionstart.s
@@ -20,12 +20,6 @@
 # RUN: ld.lld %t.o -Ttext=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
 # RUN: llvm-objdump -section-headers %t4 | FileCheck %s
 
-## Check Ttext-segment X and Ttext-segment=X forms.
-# RUN: ld.lld %t.o -Ttext-segment=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
-# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
-# RUN: ld.lld %t.o -Ttext-segment 0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
-# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
-
 ## The same, but dropped "0x" prefix.
 # RUN: ld.lld %t.o -Ttext=100000 -Tdata=110000 -Tbss=200000 -o %t5
 # RUN: llvm-objdump -section-headers %t5 | FileCheck %s

diff  --git a/lld/test/ELF/ttext-segment.s b/lld/test/ELF/ttext-segment.s
new file mode 100644
index 000000000000..4d7d6905e853
--- /dev/null
+++ b/lld/test/ELF/ttext-segment.s
@@ -0,0 +1,8 @@
+# REQUIRES: x86
+## Check that we emit an error for -Ttext-segment.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 /dev/null -o %t.o
+# RUN: not ld.lld %t.o -Ttext-segment=0x100000 -o /dev/null 2>&1 | FileCheck %s
+# RUN: not ld.lld %t.o -Ttext-segment 0x100000 -o /dev/null 2>&1 | FileCheck %s
+
+# CHECK: error: -Ttext-segment is not supported. Use --image-base if you intend to set the base address


        


More information about the llvm-commits mailing list