mirror of
https://github.com/intel/llvm.git
synced 2026-01-19 17:45:07 +08:00
[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
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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">;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
60
lld/test/ELF/ttext-segment.s
Normal file
60
lld/test/ELF/ttext-segment.s
Normal file
@@ -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: }
|
||||
Reference in New Issue
Block a user