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