Skip to content

Commit d73ef17

Browse files
author
George Rimar
committedSep 14, 2016
[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 llvm-svn: 281458
1 parent ac73ea3 commit d73ef17

File tree

5 files changed

+100
-0
lines changed

5 files changed

+100
-0
lines changed
 

‎lld/ELF/Config.h

+1
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct VersionDefinition {
6565
struct Configuration {
6666
Symbol *EntrySym = nullptr;
6767
InputFile *FirstElf = nullptr;
68+
llvm::StringMap<uint64_t> SectionStartMap;
6869
llvm::StringRef DynamicLinker;
6970
llvm::StringRef Entry;
7071
llvm::StringRef Emulation;

‎lld/ELF/Driver.cpp

+29
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,33 @@ static StripPolicy getStripOption(opt::InputArgList &Args) {
380380
return StripPolicy::None;
381381
}
382382

383+
static uint64_t parseSectionAddress(StringRef S, opt::Arg *Arg) {
384+
uint64_t VA = 0;
385+
if (S.startswith("0x"))
386+
S = S.drop_front(2);
387+
if (S.getAsInteger(16, VA))
388+
error("invalid argument: " + stringize(Arg));
389+
return VA;
390+
}
391+
392+
static StringMap<uint64_t> getSectionStartMap(opt::InputArgList &Args) {
393+
StringMap<uint64_t> Ret;
394+
for (auto *Arg : Args.filtered(OPT_section_start)) {
395+
StringRef Name;
396+
StringRef Addr;
397+
std::tie(Name, Addr) = StringRef(Arg->getValue()).split('=');
398+
Ret[Name] = parseSectionAddress(Addr, Arg);
399+
}
400+
401+
if (auto *Arg = Args.getLastArg(OPT_Ttext))
402+
Ret[".text"] = parseSectionAddress(Arg->getValue(), Arg);
403+
if (auto *Arg = Args.getLastArg(OPT_Tdata))
404+
Ret[".data"] = parseSectionAddress(Arg->getValue(), Arg);
405+
if (auto *Arg = Args.getLastArg(OPT_Tbss))
406+
Ret[".bss"] = parseSectionAddress(Arg->getValue(), Arg);
407+
return Ret;
408+
}
409+
383410
// Initializes Config members by the command line options.
384411
void LinkerDriver::readConfigs(opt::InputArgList &Args) {
385412
for (auto *Arg : Args.filtered(OPT_L))
@@ -391,6 +418,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
391418
if (!RPaths.empty())
392419
Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
393420

421+
Config->SectionStartMap = getSectionStartMap(Args);
422+
394423
if (auto *Arg = Args.getLastArg(OPT_m)) {
395424
// Parse ELF{32,64}{LE,BE} and CPU type.
396425
StringRef S = Arg->getValue();

‎lld/ELF/Options.td

+9
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,12 @@ def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
2727

2828
def O: Joined<["-"], "O">, HelpText<"Optimize output file size">;
2929

30+
def Tbss: J<"Tbss=">, HelpText<"Same as --section-start with .bss as the sectionname">;
31+
32+
def Tdata: J<"Tdata=">, HelpText<"Same as --section-start with .data as the sectionname">;
33+
34+
def Ttext: J<"Ttext=">, HelpText<"Same as --section-start with .text as the sectionname">;
35+
3036
def allow_multiple_definition: F<"allow-multiple-definition">,
3137
HelpText<"Allow multiple definitions">;
3238

@@ -147,6 +153,9 @@ def relocatable: F<"relocatable">, HelpText<"Create relocatable object file">;
147153

148154
def script: S<"script">, HelpText<"Read linker script">;
149155

156+
def section_start: S<"section-start">, MetaVarName<"<address>">,
157+
HelpText<"Set address of section">;
158+
150159
def shared: F<"shared">, HelpText<"Build a shared object">;
151160

152161
def soname: J<"soname=">, HelpText<"Set DT_SONAME">;

‎lld/ELF/Writer.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -1080,6 +1080,10 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
10801080
if (Sec->PageAlign)
10811081
Alignment = std::max<uintX_t>(Alignment, Target->PageSize);
10821082

1083+
auto I = Config->SectionStartMap.find(Sec->getName());
1084+
if (I != Config->SectionStartMap.end())
1085+
VA = I->second;
1086+
10831087
// We only assign VAs to allocated sections.
10841088
if (needsPtLoad(Sec)) {
10851089
VA = alignTo(VA, Alignment);

‎lld/test/ELF/sectionstart.s

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o
3+
# RUN: ld.lld %t.o --section-start .text=0x100000 \
4+
# RUN: --section-start .data=0x110000 --section-start .bss=0x200000 -o %t
5+
# RUN: llvm-objdump -section-headers %t | FileCheck %s
6+
7+
# CHECK: Sections:
8+
# CHECK-NEXT: Idx Name Size Address Type
9+
# CHECK-NEXT: 0 00000000 0000000000000000
10+
# CHECK-NEXT: 1 .text 00000001 0000000000100000 TEXT DATA
11+
# CHECK-NEXT: 2 .data 00000004 0000000000110000 DATA
12+
# CHECK-NEXT: 3 .bss 00000004 0000000000200000 BSS
13+
14+
## The same, but dropped "0x" prefix.
15+
# RUN: ld.lld %t.o --section-start .text=100000 \
16+
# RUN: --section-start .data=110000 --section-start .bss=0x200000 -o %t1
17+
# RUN: llvm-objdump -section-headers %t1 | FileCheck %s
18+
19+
## Use -Ttext, -Tdata, -Tbss as replacement for --section-start:
20+
# RUN: ld.lld %t.o -Ttext=0x100000 -Tdata=0x110000 -Tbss=0x200000 -o %t4
21+
# RUN: llvm-objdump -section-headers %t4 | FileCheck %s
22+
23+
## The same, but dropped "0x" prefix.
24+
# RUN: ld.lld %t.o -Ttext=100000 -Tdata=110000 -Tbss=200000 -o %t5
25+
# RUN: llvm-objdump -section-headers %t5 | FileCheck %s
26+
27+
## Errors:
28+
# RUN: not ld.lld %t.o --section-start .text100000 -o %t2 2>&1 \
29+
# RUN: | FileCheck -check-prefix=ERR1 %s
30+
# ERR1: invalid argument: --section-start .text100000
31+
32+
# RUN: not ld.lld %t.o --section-start .text=1Q0000 -o %t3 2>&1 \
33+
# RUN: | FileCheck -check-prefix=ERR2 %s
34+
# ERR2: invalid argument: --section-start .text=1Q0000
35+
36+
# RUN: not ld.lld %t.o -Ttext=1w0000 -o %t6 2>&1 \
37+
# RUN: | FileCheck -check-prefix=ERR3 %s
38+
# ERR3: invalid argument: -Ttext=1w0000
39+
40+
# RUN: not ld.lld %t.o -Tbss=1w0000 -o %t6 2>&1 \
41+
# RUN: | FileCheck -check-prefix=ERR4 %s
42+
# ERR4: invalid argument: -Tbss=1w0000
43+
44+
# RUN: not ld.lld %t.o -Tdata=1w0000 -o %t6 2>&1 \
45+
# RUN: | FileCheck -check-prefix=ERR5 %s
46+
# ERR5: invalid argument: -Tdata=1w0000
47+
48+
.text
49+
.globl _start
50+
_start:
51+
nop
52+
53+
.data
54+
.long 0
55+
56+
.bss
57+
.zero 4

0 commit comments

Comments
 (0)