diff options
| author | Petr Hosek <phosek@chromium.org> | 2016-07-12 19:37:53 +0000 |
|---|---|---|
| committer | Petr Hosek <phosek@chromium.org> | 2016-07-12 19:37:53 +0000 |
| commit | d7bd2389ceb2c2772d0d74cb092571a84aab3584 (patch) | |
| tree | 33a9ec32b3e1da200723f1b6e357e56961463826 | |
| parent | 9330b7843170d0ca073f47ca096526e4076d26cd (diff) | |
| download | bcm5719-llvm-d7bd2389ceb2c2772d0d74cb092571a84aab3584.tar.gz bcm5719-llvm-d7bd2389ceb2c2772d0d74cb092571a84aab3584.zip | |
[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
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 10 | ||||
| -rw-r--r-- | lld/ELF/Options.td | 2 | ||||
| -rw-r--r-- | lld/ELF/Writer.cpp | 4 | ||||
| -rw-r--r-- | lld/test/ELF/ttext-segment.s | 60 |
5 files changed, 75 insertions, 2 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index abfdc43b74c..8a8cc04b760 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -117,6 +117,7 @@ struct Configuration { ELFKind EKind = ELFNoneKind; uint16_t EMachine = llvm::ELF::EM_NONE; uint64_t EntryAddr = -1; + uint64_t VAStart; unsigned LtoJobs; unsigned LtoO; unsigned Optimize; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 21357fb8654..fd783ccd6b1 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -532,6 +532,16 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { Config->EntrySym = Symtab.addUndefined(S); } + if (auto *Arg = Args.getLastArg(OPT_image_base)) { + StringRef S = Arg->getValue(); + if (S.getAsInteger(0, Config->VAStart)) + error(Arg->getSpelling() + ": number expected, but got " + S); + else if ((Config->VAStart % Target->PageSize) != 0) + warning(Arg->getSpelling() + ": address isn't multiple of page size"); + } else { + Config->VAStart = Target->getVAStart(); + } + for (std::unique_ptr<InputFile> &F : Files) Symtab.addFile(std::move(F)); if (HasError) diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 4d291966380..010f37687f0 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -79,6 +79,8 @@ def help: F<"help">, HelpText<"Print option help">; def icf: F<"icf=all">, HelpText<"Enable identical code folding">; +def image_base : J<"image-base=">, HelpText<"Set the base address">; + def gc_sections: F<"gc-sections">, HelpText<"Enable garbage collection of unused sections">; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 17b10259d8f..1f03df53027 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -1022,7 +1022,7 @@ template <class ELFT> void Writer<ELFT>::fixSectionAlignments() { // sections. These are special, we do not include them into output sections // list, but have them to simplify the code. template <class ELFT> void Writer<ELFT>::fixHeaders() { - uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Target->getVAStart(); + uintX_t BaseVA = ScriptConfig->DoLayout ? 0 : Config->VAStart; Out<ELFT>::ElfHeader->setVA(BaseVA); uintX_t Off = Out<ELFT>::ElfHeader->getSize(); Out<ELFT>::ProgramHeaders->setVA(Off + BaseVA); @@ -1030,7 +1030,7 @@ template <class ELFT> void Writer<ELFT>::fixHeaders() { // Assign VAs (addresses at run-time) to output sections. template <class ELFT> void Writer<ELFT>::assignAddresses() { - uintX_t VA = Target->getVAStart() + Out<ELFT>::ElfHeader->getSize() + + uintX_t VA = Config->VAStart + Out<ELFT>::ElfHeader->getSize() + Out<ELFT>::ProgramHeaders->getSize(); uintX_t ThreadBssOffset = 0; diff --git a/lld/test/ELF/ttext-segment.s b/lld/test/ELF/ttext-segment.s new file mode 100644 index 00000000000..0be5059dcad --- /dev/null +++ b/lld/test/ELF/ttext-segment.s @@ -0,0 +1,60 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t +# RUN: ld.lld -image-base=0x1000000 %t -o %t1 +# RUN: llvm-readobj -program-headers %t1 | FileCheck %s + +.global _start +_start: + nop + +# CHECK: ProgramHeaders [ +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_PHDR (0x6) +# CHECK-NEXT: Offset: 0x40 +# CHECK-NEXT: VirtualAddress: 0x1000040 +# CHECK-NEXT: PhysicalAddress: 0x1000040 +# CHECK-NEXT: FileSize: 224 +# CHECK-NEXT: MemSize: 224 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 8 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x1000000 +# CHECK-NEXT: PhysicalAddress: 0x1000000 +# CHECK-NEXT: FileSize: 288 +# CHECK-NEXT: MemSize: 288 +# CHECK-NEXT: Flags [ (0x4) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_LOAD (0x1) +# CHECK-NEXT: Offset: 0x1000 +# CHECK-NEXT: VirtualAddress: 0x1001000 +# CHECK-NEXT: PhysicalAddress: 0x1001000 +# CHECK-NEXT: FileSize: 1 +# CHECK-NEXT: MemSize: 1 +# CHECK-NEXT: Flags [ (0x5) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_X (0x1) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 4096 +# CHECK-NEXT: } +# CHECK-NEXT: ProgramHeader { +# CHECK-NEXT: Type: PT_GNU_STACK (0x6474E551) +# CHECK-NEXT: Offset: 0x0 +# CHECK-NEXT: VirtualAddress: 0x0 +# CHECK-NEXT: PhysicalAddress: 0x0 +# CHECK-NEXT: FileSize: 0 +# CHECK-NEXT: MemSize: 0 +# CHECK-NEXT: Flags [ (0x6) +# CHECK-NEXT: PF_R (0x4) +# CHECK-NEXT: PF_W (0x2) +# CHECK-NEXT: ] +# CHECK-NEXT: Alignment: 0 +# CHECK-NEXT: } |

