uint16_t DefaultSymbolVersion = llvm::ELF::VER_NDX_GLOBAL;
uint16_t EMachine = llvm::ELF::EM_NONE;
uint64_t ErrorLimit = 20;
- uint64_t ImageBase;
+ llvm::Optional<uint64_t> ImageBase;
uint64_t MaxPageSize;
uint64_t ZStackSize;
unsigned LTOPartitions;
}
// Parses -image-base option.
-static uint64_t getImageBase(opt::InputArgList &Args) {
- // Use default if no -image-base option is given.
- // Because we are using "Target" here, this function
- // has to be called after the variable is initialized.
+static Optional<uint64_t> getImageBase(opt::InputArgList &Args) {
+ // Because we are using "Config->MaxPageSize" here, this function has to be
+ // called after the variable is initialized.
auto *Arg = Args.getLastArg(OPT_image_base);
if (!Arg)
- return Config->Pic ? 0 : Target->DefaultImageBase;
+ return None;
StringRef S = Arg->getValue();
uint64_t V;
// script parser.
CurAddressState = State.get();
CurAddressState->OutSec = Aether;
- Dot = 0;
for (size_t I = 0; I < Opt.Commands.size(); ++I) {
// Handle symbol assignments outside of any output section.
StartAddr = std::min(StartAddr, KV.second);
auto Expr = [=] {
- return std::min(StartAddr, Config->ImageBase + elf::getHeaderSize());
+ return std::min(StartAddr, Target->getImageBase() + elf::getHeaderSize());
};
Opt.Commands.insert(Opt.Commands.begin(),
make<SymbolAssignment>(".", Expr, ""));
}
}
+// Assign addresses as instructed by linker script SECTIONS sub-commands.
void LinkerScript::assignAddresses() {
- // Assign addresses as instructed by linker script SECTIONS sub-commands.
- Dot = 0;
+ // By default linker scripts use an initial value of 0 for '.', but prefer
+ // -image-base if set.
+ Dot = Config->ImageBase ? *Config->ImageBase : 0;
auto State = make_unique<AddressState>(Opt);
// CurAddressState captures the local AddressState and makes it accessible
// deliberately. This is needed as there are some cases where we cannot just
if (Config->EMachine == EM_MIPS) {
add({DT_MIPS_RLD_VERSION, 1});
add({DT_MIPS_FLAGS, RHF_NOTPOT});
- add({DT_MIPS_BASE_ADDRESS, Config->ImageBase});
+ add({DT_MIPS_BASE_ADDRESS, Target->getImageBase()});
add({DT_MIPS_SYMTABNO, InX::DynSymTab->getNumSymbols()});
add({DT_MIPS_LOCAL_GOTNO, InX::MipsGot->getLocalEntriesNum()});
if (const SymbolBody *B = InX::MipsGot->getFirstGlobalEntry())
uint64_t Val) const {
llvm_unreachable("Should not have claimed to be relaxable");
}
+
+uint64_t TargetInfo::getImageBase() {
+ // Use -image-base if set. Fall back to the target default if not.
+ if (Config->ImageBase)
+ return *Config->ImageBase;
+ return Config->Pic ? 0 : DefaultImageBase;
+}
unsigned PageSize = 4096;
unsigned DefaultMaxPageSize = 4096;
- // On FreeBSD x86_64 the first page cannot be mmaped.
- // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
- // installs that is 65536, so the first 15 pages cannot be used.
- // Given that, the smallest value that can be used in here is 0x10000.
- uint64_t DefaultImageBase = 0x10000;
+ uint64_t getImageBase();
// Offset of _GLOBAL_OFFSET_TABLE_ from base of .got section. Use -1 for
// end of .got
virtual void relaxTlsGdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
virtual void relaxTlsIeToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
virtual void relaxTlsLdToLe(uint8_t *Loc, uint32_t Type, uint64_t Val) const;
+
+protected:
+ // On FreeBSD x86_64 the first page cannot be mmaped.
+ // On Linux that is controled by vm.mmap_min_addr. At least on some x86_64
+ // installs that is 65536, so the first 15 pages cannot be used.
+ // Given that, the smallest value that can be used in here is 0x10000.
+ uint64_t DefaultImageBase = 0x10000;
};
TargetInfo *getAArch64TargetInfo();
--- /dev/null
+# REQUIRES: x86\r
+\r
+# RUN: llvm-mc -filetype=obj -triple=x86_64-pc-linux %s -o %t.o\r
+# RUN: echo "SECTIONS { mysym = .; }" > %t.script\r
+\r
+# RUN: ld.lld %t.o -o %t-default.elf -T %t.script\r
+# RUN: llvm-readobj --symbols %t-default.elf | FileCheck %s --check-prefix=DEFAULT\r
+# DEFAULT: Name: mysym\r
+# DEFAULT-NEXT: Value: 0x0\r
+\r
+# RUN: ld.lld %t.o -o %t-switch.elf -T %t.script --image-base=0x100000\r
+# RUN: llvm-readobj --symbols %t-switch.elf | FileCheck %s --check-prefix=SWITCH\r
+# SWITCH: Name: mysym\r
+# SWITCH-NEXT: Value: 0x100000\r
+\r
+.global _start\r
+_start:\r
+ nop\r