[lld] r281458 - [ELF] - Implemented --section-start, -Ttext, -Tdata, -Tbss options.
George Rimar via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 14 06:07:13 PDT 2016
Author: grimar
Date: Wed Sep 14 08:07:13 2016
New Revision: 281458
URL: http://llvm.org/viewvc/llvm-project?rev=281458&view=rev
Log:
[ELF] - Implemented --section-start, -Ttext, -Tdata, -Tbss options.
--section-start=sectionname=org
Locate a section in the output file at the absolute address given by org.
You may use this option as many times as necessary to locate multiple sections in the command line.
org must be a single hexadecimal integer; for compatibility with other linkers,
you may omit the leading `0x' usually associated with hexadecimal values.
Note: there should be no white space between sectionname, the equals sign (“<=>”), and org.
-Tbss=org
-Tdata=org
-Ttext=org
Same as --section-start, with .bss, .data or .text as the sectionname.
Differential revision: https://reviews.llvm.org/D24294
Added:
lld/trunk/test/ELF/sectionstart.s
Modified:
lld/trunk/ELF/Config.h
lld/trunk/ELF/Driver.cpp
lld/trunk/ELF/Options.td
lld/trunk/ELF/Writer.cpp
Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=281458&r1=281457&r2=281458&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Wed Sep 14 08:07:13 2016
@@ -65,6 +65,7 @@ struct VersionDefinition {
struct Configuration {
Symbol *EntrySym = nullptr;
InputFile *FirstElf = nullptr;
+ llvm::StringMap<uint64_t> SectionStartMap;
llvm::StringRef DynamicLinker;
llvm::StringRef Entry;
llvm::StringRef Emulation;
Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=281458&r1=281457&r2=281458&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Wed Sep 14 08:07:13 2016
@@ -380,6 +380,33 @@ static StripPolicy getStripOption(opt::I
return StripPolicy::None;
}
+static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) {
+ uint64_t VA = 0;
+ if (S.startswith("0x"))
+ S = S.drop_front(2);
+ if (S.getAsInteger(16, VA))
+ error("invalid argument: " + stringize(Arg));
+ return VA;
+}
+
+static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
+ StringMap<uint64_t> Ret;
+ for (auto *Arg : Args.filtered(OPT_section_start)) {
+ StringRef Name;
+ StringRef Addr;
+ std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
+ Ret[Name] = parseSectionAddress(Addr, Arg);
+ }
+
+ if (auto *Arg = Args.getLastArg(OPT_Ttext))
+ Ret[".text"] = parseSectionAddress(Arg->getValue(), Arg);
+ if (auto *Arg = Args.getLastArg(OPT_Tdata))
+ Ret[".data"] = parseSectionAddress(Arg->getValue(), Arg);
+ if (auto *Arg = Args.getLastArg(OPT_Tbss))
+ Ret[".bss"] = parseSectionAddress(Arg->getValue(), Arg);
+ return Ret;
+}
+
// Initializes Config members by the command line options.
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
for (auto *Arg : Args.filtered(OPT_L))
@@ -391,6 +418,8 @@ void LinkerDriver::readConfigs(opt::Inpu
if (!RPaths.empty())
Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
+ Config->SectionStartMap = getSectionStartMap(Args);
+
if (auto *Arg = Args.getLastArg(OPT_m)) {
// Parse ELF{32,64}{LE,BE} and CPU type.
StringRef S = Arg->getValue();
Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=281458&r1=281457&r2=281458&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Wed Sep 14 08:07:13 2016
@@ -27,6 +27,12 @@ def L: JoinedOrSeparate<["-"], "L">, Met
def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
+def Tbss: J<"Tbss=">, HelpText<"Same as --section-start with .bss as the sectionname">;
+
+def Tdata: J<"Tdata=">, HelpText<"Same as --section-start with .data as the sectionname">;
+
+def Ttext: J<"Ttext=">, HelpText<"Same as --section-start with .text as the sectionname">;
+
def allow_multiple_definition: F<"allow-multiple-definition">,
HelpText<"Allow multiple definitions">;
@@ -147,6 +153,9 @@ def relocatable: F<"relocatable">, HelpT
def script: S<"script">, HelpText<"Read linker script">;
+def section_start: S<"section-start">, MetaVarName<"<address>">,
+ HelpText<"Set address of section">;
+
def shared: F<"shared">, HelpText<"Build a shared object">;
def soname: J<"soname=">, HelpText<"Set DT_SONAME">;
Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=281458&r1=281457&r2=281458&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Wed Sep 14 08:07:13 2016
@@ -1080,6 +1080,10 @@ template <class ELFT> void Writer<ELFT>:
if (Sec->PageAlign)
Alignment = std::max<uintX_t>(Alignment, Target->PageSize);
+ auto I = Config->SectionStartMap.find(Sec->getName());
+ if (I != Config->SectionStartMap.end())
+ VA = I->second;
+
// We only assign VAs to allocated sections.
if (needsPtLoad(Sec)) {
VA = alignTo(VA, Alignment);
Added: lld/trunk/test/ELF/sectionstart.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/sectionstart.s?rev=281458&view=auto
==============================================================================
--- lld/trunk/test/ELF/sectionstart.s (added)
+++ lld/trunk/test/ELF/sectionstart.s Wed Sep 14 08:07:13 2016
@@ -0,0 +1,57 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
+# RUN: ld.lld %t.o --section-start .text=0x100000 \
+# RUN: --section-start .data=0x110000 --section-start .bss=0x200000 -o %t
+# RUN: llvm-objdump -section-headers %t | FileCheck %s
+
+# CHECK: Sections:
+# CHECK-NEXT: Idx Name Size Address Type
+# CHECK-NEXT: 0 00000000 0000000000000000
+# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT DATA
+# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
+# CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS
+
+## The same, but dropped "0x" prefix.
+# RUN: ld.lld %t.o --section-start .text=100000 \
+# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1
+# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
+
+## Use -Ttext, -Tdata, -Tbss as replacement for --section-start:
+# RUN: ld.lld %t.o -Ttext=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
+
+## Errors:
+# RUN: not ld.lld %t.o --section-start .text100000 -o %t2 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR1 %s
+# ERR1: invalid argument: --section-start .text100000
+
+# RUN: not ld.lld %t.o --section-start .text=1Q0000 -o %t3 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR2 %s
+# ERR2: invalid argument: --section-start .text=1Q0000
+
+# RUN: not ld.lld %t.o -Ttext=1w0000 -o %t6 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR3 %s
+# ERR3: invalid argument: -Ttext=1w0000
+
+# RUN: not ld.lld %t.o -Tbss=1w0000 -o %t6 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR4 %s
+# ERR4: invalid argument: -Tbss=1w0000
+
+# RUN: not ld.lld %t.o -Tdata=1w0000 -o %t6 2>&1 \
+# RUN: | FileCheck -check-prefix=ERR5 %s
+# ERR5: invalid argument: -Tdata=1w0000
+
+.text
+.globl _start
+_start:
+ nop
+
+.data
+.long 0
+
+.bss
+.zero 4
More information about the llvm-commits
mailing list