forked from OSchip/llvm-project
[ELF] Allow specifying the stack size
This option can be used to specify the stack size of the PT_GNU_STACK segment. Differential Revision: https://reviews.llvm.org/D23538 llvm-svn: 279013
This commit is contained in:
parent
56ee4f1fb7
commit
1fb2ecc903
|
|
@ -121,6 +121,7 @@ struct Configuration {
|
||||||
uint16_t EMachine = llvm::ELF::EM_NONE;
|
uint16_t EMachine = llvm::ELF::EM_NONE;
|
||||||
uint64_t EntryAddr = -1;
|
uint64_t EntryAddr = -1;
|
||||||
uint64_t ImageBase;
|
uint64_t ImageBase;
|
||||||
|
uint64_t ZStackSize = -1;
|
||||||
unsigned LtoJobs;
|
unsigned LtoJobs;
|
||||||
unsigned LtoO;
|
unsigned LtoO;
|
||||||
unsigned Optimize;
|
unsigned Optimize;
|
||||||
|
|
|
||||||
|
|
@ -256,6 +256,17 @@ static bool hasZOption(opt::InputArgList &Args, StringRef Key) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Optional<StringRef>
|
||||||
|
getZOptionValue(opt::InputArgList &Args, StringRef Key) {
|
||||||
|
for (auto *Arg : Args.filtered(OPT_z)) {
|
||||||
|
StringRef Value = Arg->getValue();
|
||||||
|
size_t Pos = Value.find("=");
|
||||||
|
if (Pos != StringRef::npos && Key == Value.substr(0, Pos))
|
||||||
|
return Value.substr(Pos + 1);
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
|
void LinkerDriver::main(ArrayRef<const char *> ArgsArr) {
|
||||||
ELFOptTable Parser;
|
ELFOptTable Parser;
|
||||||
opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
|
opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
|
||||||
|
|
@ -395,6 +406,10 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
|
||||||
Config->ZOrigin = hasZOption(Args, "origin");
|
Config->ZOrigin = hasZOption(Args, "origin");
|
||||||
Config->ZRelro = !hasZOption(Args, "norelro");
|
Config->ZRelro = !hasZOption(Args, "norelro");
|
||||||
|
|
||||||
|
if (Optional<StringRef> Value = getZOptionValue(Args, "stack-size"))
|
||||||
|
if (Value->getAsInteger(0, Config->ZStackSize))
|
||||||
|
error("invalid stack size: " + *Value);
|
||||||
|
|
||||||
if (Config->Relocatable)
|
if (Config->Relocatable)
|
||||||
Config->StripAll = false;
|
Config->StripAll = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1005,8 +1005,11 @@ std::vector<PhdrEntry<ELFT>> Writer<ELFT>::createPhdrs() {
|
||||||
|
|
||||||
// PT_GNU_STACK is a special section to tell the loader to make the
|
// PT_GNU_STACK is a special section to tell the loader to make the
|
||||||
// pages for the stack non-executable.
|
// pages for the stack non-executable.
|
||||||
if (!Config->ZExecStack)
|
if (!Config->ZExecStack) {
|
||||||
AddHdr(PT_GNU_STACK, PF_R | PF_W);
|
Phdr &Hdr = *AddHdr(PT_GNU_STACK, PF_R | PF_W);
|
||||||
|
if (Config->ZStackSize != uint64_t(-1))
|
||||||
|
Hdr.H.p_memsz = Config->ZStackSize;
|
||||||
|
}
|
||||||
|
|
||||||
if (Note.First)
|
if (Note.First)
|
||||||
Ret.push_back(std::move(Note));
|
Ret.push_back(std::move(Note));
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
# REQUIRES: x86
|
||||||
|
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
|
||||||
|
# RUN: ld.lld -z stack-size=0x1000 %t -o %t1
|
||||||
|
# RUN: llvm-readobj -program-headers %t1 | FileCheck %s
|
||||||
|
|
||||||
|
.global _start
|
||||||
|
_start:
|
||||||
|
nop
|
||||||
|
|
||||||
|
# CHECK: Type: PT_GNU_STACK (0x6474E551)
|
||||||
|
# CHECK-NEXT: Offset: 0x0
|
||||||
|
# CHECK-NEXT: VirtualAddress: 0x0
|
||||||
|
# CHECK-NEXT: PhysicalAddress: 0x0
|
||||||
|
# CHECK-NEXT: FileSize: 0
|
||||||
|
# CHECK-NEXT: MemSize: 4096
|
||||||
|
# CHECK-NEXT: Flags [ (0x6)
|
||||||
|
# CHECK-NEXT: PF_R (0x4)
|
||||||
|
# CHECK-NEXT: PF_W (0x2)
|
||||||
|
# CHECK-NEXT: ]
|
||||||
|
# CHECK-NEXT: Alignment: 0
|
||||||
Loading…
Reference in New Issue