Skip to content

Commit d7bd238

Browse files
committedJul 12, 2016
[ELF] Support for setting the base address
The -image-base option allows for overriding the base address. Differential Revision: http://reviews.llvm.org/D22116 llvm-svn: 275206
1 parent 9330b78 commit d7bd238

File tree

5 files changed

+75
-2
lines changed

5 files changed

+75
-2
lines changed
 

‎lld/ELF/Config.h

+1
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,7 @@ struct Configuration {
117117
ELFKind EKind = ELFNoneKind;
118118
uint16_t EMachine = llvm::ELF::EM_NONE;
119119
uint64_t EntryAddr = -1;
120+
uint64_t VAStart;
120121
unsigned LtoJobs;
121122
unsigned LtoO;
122123
unsigned Optimize;

‎lld/ELF/Driver.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,16 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
532532
Config->EntrySym = Symtab.addUndefined(S);
533533
}
534534

535+
if (auto *Arg = Args.getLastArg(OPT_image_base)) {
536+
StringRef S = Arg->getValue();
537+
if (S.getAsInteger(0, Config->VAStart))
538+
error(Arg->getSpelling() + ": number expected, but got " + S);
539+
else if ((Config->VAStart % Target->PageSize) != 0)
540+
warning(Arg->getSpelling() + ": address isn't multiple of page size");
541+
} else {
542+
Config->VAStart = Target->getVAStart();
543+
}
544+
535545
for (std::unique_ptr<InputFile> &F : Files)
536546
Symtab.addFile(std::move(F));
537547
if (HasError)

‎lld/ELF/Options.td

+2
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ def help: F<"help">, HelpText<"Print option help">;
7979

8080
def icf: F<"icf=all">, HelpText<"Enable identical code folding">;
8181

82+
def image_base : J<"image-base=">, HelpText<"Set the base address">;
83+
8284
def gc_sections: F<"gc-sections">,
8385
HelpText<"Enable garbage collection of unused sections">;
8486

‎lld/ELF/Writer.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -1022,15 +1022,15 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() {
10221022
// sections. These are special, we do not include them into output sections
10231023
// list, but have them to simplify the code.
10241024
template <class ELFT> void Writer<ELFT>::fixHeaders() {
1025-
uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Target->getVAStart();
1025+
uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Config->VAStart;
10261026
Out<ELFT>::ElfHeader->setVA(BaseVA);
10271027
uintX_t Off = Out<ELFT>::ElfHeader->getSize();
10281028
Out<ELFT>::ProgramHeaders->setVA(Off + BaseVA);
10291029
}
10301030

10311031
// Assign VAs (addresses at run-time) to output sections.
10321032
template <class ELFT> void Writer<ELFT>::assignAddresses() {
1033-
uintX_t VA = Target->getVAStart() + Out<ELFT>::ElfHeader->getSize() +
1033+
uintX_t VA = Config->VAStart + Out<ELFT>::ElfHeader->getSize() +
10341034
Out<ELFT>::ProgramHeaders->getSize();
10351035

10361036
uintX_t ThreadBssOffset = 0;

‎lld/test/ELF/ttext-segment.s

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# REQUIRES: x86
2+
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
3+
# RUN: ld.lld -image-base=0x1000000 %t -o %t1
4+
# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
5+
6+
.global _start
7+
_start:
8+
nop
9+
10+
# CHECK: ProgramHeaders [
11+
# CHECK-NEXT: ProgramHeader {
12+
# CHECK-NEXT: Type: PT_PHDR (0x6)
13+
# CHECK-NEXT: Offset: 0x40
14+
# CHECK-NEXT: VirtualAddress: 0x1000040
15+
# CHECK-NEXT: PhysicalAddress: 0x1000040
16+
# CHECK-NEXT: FileSize: 224
17+
# CHECK-NEXT: MemSize: 224
18+
# CHECK-NEXT: Flags [ (0x4)
19+
# CHECK-NEXT: PF_R (0x4)
20+
# CHECK-NEXT: ]
21+
# CHECK-NEXT: Alignment: 8
22+
# CHECK-NEXT: }
23+
# CHECK-NEXT: ProgramHeader {
24+
# CHECK-NEXT: Type: PT_LOAD (0x1)
25+
# CHECK-NEXT: Offset: 0x0
26+
# CHECK-NEXT: VirtualAddress: 0x1000000
27+
# CHECK-NEXT: PhysicalAddress: 0x1000000
28+
# CHECK-NEXT: FileSize: 288
29+
# CHECK-NEXT: MemSize: 288
30+
# CHECK-NEXT: Flags [ (0x4)
31+
# CHECK-NEXT: PF_R (0x4)
32+
# CHECK-NEXT: ]
33+
# CHECK-NEXT: Alignment: 4096
34+
# CHECK-NEXT: }
35+
# CHECK-NEXT: ProgramHeader {
36+
# CHECK-NEXT: Type: PT_LOAD (0x1)
37+
# CHECK-NEXT: Offset: 0x1000
38+
# CHECK-NEXT: VirtualAddress: 0x1001000
39+
# CHECK-NEXT: PhysicalAddress: 0x1001000
40+
# CHECK-NEXT: FileSize: 1
41+
# CHECK-NEXT: MemSize: 1
42+
# CHECK-NEXT: Flags [ (0x5)
43+
# CHECK-NEXT: PF_R (0x4)
44+
# CHECK-NEXT: PF_X (0x1)
45+
# CHECK-NEXT: ]
46+
# CHECK-NEXT: Alignment: 4096
47+
# CHECK-NEXT: }
48+
# CHECK-NEXT: ProgramHeader {
49+
# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551)
50+
# CHECK-NEXT: Offset: 0x0
51+
# CHECK-NEXT: VirtualAddress: 0x0
52+
# CHECK-NEXT: PhysicalAddress: 0x0
53+
# CHECK-NEXT: FileSize: 0
54+
# CHECK-NEXT: MemSize: 0
55+
# CHECK-NEXT: Flags [ (0x6)
56+
# CHECK-NEXT: PF_R (0x4)
57+
# CHECK-NEXT: PF_W (0x2)
58+
# CHECK-NEXT: ]
59+
# CHECK-NEXT: Alignment: 0
60+
# CHECK-NEXT: }

0 commit comments

Comments
 (0)
Please sign in to comment.