Add support for the --noexecstack option.
llvm-svn: 124077
This commit is contained in:
parent
8f01420d9d
commit
b3eca9bb71
|
@ -694,6 +694,7 @@ private:
|
||||||
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
|
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
|
||||||
|
|
||||||
unsigned RelaxAll : 1;
|
unsigned RelaxAll : 1;
|
||||||
|
unsigned NoExecStack : 1;
|
||||||
unsigned SubsectionsViaSymbols : 1;
|
unsigned SubsectionsViaSymbols : 1;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -808,6 +809,9 @@ public:
|
||||||
bool getRelaxAll() const { return RelaxAll; }
|
bool getRelaxAll() const { return RelaxAll; }
|
||||||
void setRelaxAll(bool Value) { RelaxAll = Value; }
|
void setRelaxAll(bool Value) { RelaxAll = Value; }
|
||||||
|
|
||||||
|
bool getNoExecStack() const { return NoExecStack; }
|
||||||
|
void setNoExecStack(bool Value) { NoExecStack = Value; }
|
||||||
|
|
||||||
/// @name Section List Access
|
/// @name Section List Access
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
|
|
|
@ -469,7 +469,7 @@ namespace llvm {
|
||||||
/// ELF format object files.
|
/// ELF format object files.
|
||||||
MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
|
MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
|
||||||
raw_ostream &OS, MCCodeEmitter *CE,
|
raw_ostream &OS, MCCodeEmitter *CE,
|
||||||
bool RelaxAll = false);
|
bool RelaxAll, bool NoExecStack);
|
||||||
|
|
||||||
/// createLoggingStreamer - Create a machine code streamer which just logs the
|
/// createLoggingStreamer - Create a machine code streamer which just logs the
|
||||||
/// API calls and then dispatches to another streamer.
|
/// API calls and then dispatches to another streamer.
|
||||||
|
|
|
@ -104,6 +104,7 @@ protected: // Can only create subclasses.
|
||||||
const MCAsmInfo *AsmInfo;
|
const MCAsmInfo *AsmInfo;
|
||||||
|
|
||||||
unsigned MCRelaxAll : 1;
|
unsigned MCRelaxAll : 1;
|
||||||
|
unsigned MCNoExecStack : 1;
|
||||||
unsigned MCUseLoc : 1;
|
unsigned MCUseLoc : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -170,6 +171,12 @@ public:
|
||||||
/// relaxed.
|
/// relaxed.
|
||||||
void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
|
void setMCRelaxAll(bool Value) { MCRelaxAll = Value; }
|
||||||
|
|
||||||
|
/// hasMCNoExecStack - Check whether an executable stack is not needed.
|
||||||
|
bool hasMCNoExecStack() const { return MCNoExecStack; }
|
||||||
|
|
||||||
|
/// setMCNoExecStack - Set whether an executabel stack is not needed.
|
||||||
|
void setMCNoExecStack(bool Value) { MCNoExecStack = Value; }
|
||||||
|
|
||||||
/// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
|
/// hasMCUseLoc - Check whether we should use dwarf's .loc directive.
|
||||||
bool hasMCUseLoc() const { return MCUseLoc; }
|
bool hasMCUseLoc() const { return MCUseLoc; }
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,8 @@ namespace llvm {
|
||||||
TargetAsmBackend &TAB,
|
TargetAsmBackend &TAB,
|
||||||
raw_ostream &_OS,
|
raw_ostream &_OS,
|
||||||
MCCodeEmitter *_Emitter,
|
MCCodeEmitter *_Emitter,
|
||||||
bool RelaxAll);
|
bool RelaxAll,
|
||||||
|
bool NoExecStack);
|
||||||
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
|
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
|
||||||
formatted_raw_ostream &OS,
|
formatted_raw_ostream &OS,
|
||||||
bool isVerboseAsm,
|
bool isVerboseAsm,
|
||||||
|
@ -308,14 +309,17 @@ namespace llvm {
|
||||||
/// \arg _OS - The stream object.
|
/// \arg _OS - The stream object.
|
||||||
/// \arg _Emitter - The target independent assembler object.Takes ownership.
|
/// \arg _Emitter - The target independent assembler object.Takes ownership.
|
||||||
/// \arg RelaxAll - Relax all fixups?
|
/// \arg RelaxAll - Relax all fixups?
|
||||||
|
/// \arg NoExecStack - Mark file as not needing a executable stack.
|
||||||
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
|
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
|
||||||
TargetAsmBackend &TAB,
|
TargetAsmBackend &TAB,
|
||||||
raw_ostream &_OS,
|
raw_ostream &_OS,
|
||||||
MCCodeEmitter *_Emitter,
|
MCCodeEmitter *_Emitter,
|
||||||
bool RelaxAll) const {
|
bool RelaxAll,
|
||||||
|
bool NoExecStack) const {
|
||||||
if (!ObjectStreamerCtorFn)
|
if (!ObjectStreamerCtorFn)
|
||||||
return 0;
|
return 0;
|
||||||
return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll);
|
return ObjectStreamerCtorFn(*this, TT, Ctx, TAB, _OS, _Emitter, RelaxAll,
|
||||||
|
NoExecStack);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// createAsmStreamer - Create a target specific MCStreamer.
|
/// createAsmStreamer - Create a target specific MCStreamer.
|
||||||
|
|
|
@ -168,7 +168,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
|
||||||
|
|
||||||
AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Context,
|
AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Context,
|
||||||
*TAB, Out, MCE,
|
*TAB, Out, MCE,
|
||||||
hasMCRelaxAll()));
|
hasMCRelaxAll(),
|
||||||
|
hasMCNoExecStack()));
|
||||||
AsmStreamer.get()->InitSections();
|
AsmStreamer.get()->InitSections();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -329,8 +329,11 @@ namespace {
|
||||||
virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
|
virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
|
||||||
const SectionIndexMapTy &SectionIndexMap);
|
const SectionIndexMapTy &SectionIndexMap);
|
||||||
|
|
||||||
virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
|
// Create the sections that show up in the symbol table. Currently
|
||||||
GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
|
// those are the .note.GNU-stack section and the group sections.
|
||||||
|
virtual void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout,
|
||||||
|
GroupMapTy &GroupMap,
|
||||||
|
RevGroupMapTy &RevGroupMap);
|
||||||
|
|
||||||
virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
|
virtual void ExecutePostLayoutBinding(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout);
|
const MCAsmLayout &Layout);
|
||||||
|
@ -1174,10 +1177,19 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
|
||||||
return &SecA == &SecB;
|
return &SecA == &SecB;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
|
void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
|
||||||
MCAsmLayout &Layout,
|
MCAsmLayout &Layout,
|
||||||
GroupMapTy &GroupMap,
|
GroupMapTy &GroupMap,
|
||||||
RevGroupMapTy &RevGroupMap) {
|
RevGroupMapTy &RevGroupMap) {
|
||||||
|
// Create the .note.GNU-stack section if needed.
|
||||||
|
MCContext &Ctx = Asm.getContext();
|
||||||
|
if (Asm.getNoExecStack()) {
|
||||||
|
const MCSectionELF *GnuStackSection =
|
||||||
|
Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0,
|
||||||
|
SectionKind::getReadOnly());
|
||||||
|
Asm.getOrCreateSectionData(*GnuStackSection);
|
||||||
|
}
|
||||||
|
|
||||||
// Build the groups
|
// Build the groups
|
||||||
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
|
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
|
||||||
it != ie; ++it) {
|
it != ie; ++it) {
|
||||||
|
@ -1190,7 +1202,7 @@ void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
|
||||||
Asm.getOrCreateSymbolData(*SignatureSymbol);
|
Asm.getOrCreateSymbolData(*SignatureSymbol);
|
||||||
const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
|
const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
|
||||||
if (!Group) {
|
if (!Group) {
|
||||||
Group = Asm.getContext().CreateELFGroupSection();
|
Group = Ctx.CreateELFGroupSection();
|
||||||
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
|
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
|
||||||
Data.setAlignment(4);
|
Data.setAlignment(4);
|
||||||
MCDataFragment *F = new MCDataFragment(&Data);
|
MCDataFragment *F = new MCDataFragment(&Data);
|
||||||
|
@ -1334,8 +1346,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
|
||||||
const MCAsmLayout &Layout) {
|
const MCAsmLayout &Layout) {
|
||||||
GroupMapTy GroupMap;
|
GroupMapTy GroupMap;
|
||||||
RevGroupMapTy RevGroupMap;
|
RevGroupMapTy RevGroupMap;
|
||||||
CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
|
CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
|
||||||
RevGroupMap);
|
RevGroupMap);
|
||||||
|
|
||||||
SectionIndexMapTy SectionIndexMap;
|
SectionIndexMapTy SectionIndexMap;
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ MCAssembler::MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_,
|
||||||
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
|
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
|
||||||
raw_ostream &OS_)
|
raw_ostream &OS_)
|
||||||
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
|
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
|
||||||
OS(OS_), RelaxAll(false), SubsectionsViaSymbols(false)
|
OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -515,10 +515,12 @@ void MCELFStreamer::Finish() {
|
||||||
}
|
}
|
||||||
|
|
||||||
MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
|
MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
|
||||||
raw_ostream &OS, MCCodeEmitter *CE,
|
raw_ostream &OS, MCCodeEmitter *CE,
|
||||||
bool RelaxAll) {
|
bool RelaxAll, bool NoExecStack) {
|
||||||
MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
|
MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
|
||||||
if (RelaxAll)
|
if (RelaxAll)
|
||||||
S->getAssembler().setRelaxAll(true);
|
S->getAssembler().setRelaxAll(true);
|
||||||
|
if (NoExecStack)
|
||||||
|
S->getAssembler().setNoExecStack(true);
|
||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
MCContext &Ctx, TargetAsmBackend &TAB,
|
MCContext &Ctx, TargetAsmBackend &TAB,
|
||||||
raw_ostream &OS,
|
raw_ostream &OS,
|
||||||
MCCodeEmitter *Emitter,
|
MCCodeEmitter *Emitter,
|
||||||
bool RelaxAll) {
|
bool RelaxAll,
|
||||||
|
bool NoExecStack) {
|
||||||
switch (Triple(TT).getOS()) {
|
switch (Triple(TT).getOS()) {
|
||||||
case Triple::Darwin:
|
case Triple::Darwin:
|
||||||
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
|
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
|
||||||
|
@ -50,7 +51,7 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
llvm_unreachable("ARM does not support Windows COFF format");
|
llvm_unreachable("ARM does not support Windows COFF format");
|
||||||
return NULL;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
|
return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
MCContext &Ctx, TargetAsmBackend &TAB,
|
MCContext &Ctx, TargetAsmBackend &TAB,
|
||||||
raw_ostream &_OS,
|
raw_ostream &_OS,
|
||||||
MCCodeEmitter *_Emitter,
|
MCCodeEmitter *_Emitter,
|
||||||
bool RelaxAll) {
|
bool RelaxAll,
|
||||||
|
bool NoExecStack) {
|
||||||
Triple TheTriple(TT);
|
Triple TheTriple(TT);
|
||||||
switch (TheTriple.getOS()) {
|
switch (TheTriple.getOS()) {
|
||||||
case Triple::Darwin:
|
case Triple::Darwin:
|
||||||
|
@ -46,7 +47,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
llvm_unreachable("MBlaze does not support Windows COFF format");
|
llvm_unreachable("MBlaze does not support Windows COFF format");
|
||||||
return NULL;
|
return NULL;
|
||||||
default:
|
default:
|
||||||
return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
|
return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll,
|
||||||
|
NoExecStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
MCContext &Ctx, TargetAsmBackend &TAB,
|
MCContext &Ctx, TargetAsmBackend &TAB,
|
||||||
raw_ostream &OS,
|
raw_ostream &OS,
|
||||||
MCCodeEmitter *Emitter,
|
MCCodeEmitter *Emitter,
|
||||||
bool RelaxAll) {
|
bool RelaxAll,
|
||||||
|
bool NoExecStack) {
|
||||||
switch (Triple(TT).getOS()) {
|
switch (Triple(TT).getOS()) {
|
||||||
case Triple::Darwin:
|
case Triple::Darwin:
|
||||||
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
|
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
|
||||||
|
|
|
@ -43,7 +43,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
MCContext &Ctx, TargetAsmBackend &TAB,
|
MCContext &Ctx, TargetAsmBackend &TAB,
|
||||||
raw_ostream &_OS,
|
raw_ostream &_OS,
|
||||||
MCCodeEmitter *_Emitter,
|
MCCodeEmitter *_Emitter,
|
||||||
bool RelaxAll) {
|
bool RelaxAll,
|
||||||
|
bool NoExecStack) {
|
||||||
Triple TheTriple(TT);
|
Triple TheTriple(TT);
|
||||||
switch (TheTriple.getOS()) {
|
switch (TheTriple.getOS()) {
|
||||||
case Triple::Darwin:
|
case Triple::Darwin:
|
||||||
|
@ -54,7 +55,7 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
|
||||||
case Triple::Win32:
|
case Triple::Win32:
|
||||||
return createWinCOFFStreamer(Ctx, TAB, *_Emitter, _OS, RelaxAll);
|
return createWinCOFFStreamer(Ctx, TAB, *_Emitter, _OS, RelaxAll);
|
||||||
default:
|
default:
|
||||||
return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
|
return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll, NoExecStack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
// RUN: llvm-mc -mc-no-exec-stack -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump | FileCheck %s
|
||||||
|
|
||||||
|
// CHECK: # Section 0x00000004
|
||||||
|
// CHECK-NEXT: (('sh_name', 0x00000012) # '.note.GNU-stack'
|
||||||
|
// CHECK-NEXT: ('sh_type', 0x00000001)
|
||||||
|
// CHECK-NEXT: ('sh_flags', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_addr', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_offset', 0x00000040)
|
||||||
|
// CHECK-NEXT: ('sh_size', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_link', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_info', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('sh_addralign', 0x00000001)
|
||||||
|
// CHECK-NEXT: ('sh_entsize', 0x00000000)
|
||||||
|
// CHECK-NEXT: ),
|
||||||
|
|
||||||
|
// CHECK: # Symbol 0x00000004
|
||||||
|
// CHECK-NEXT: (('st_name', 0x00000000) # ''
|
||||||
|
// CHECK-NEXT: ('st_bind', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('st_type', 0x00000003)
|
||||||
|
// CHECK-NEXT: ('st_other', 0x00000000)
|
||||||
|
// CHECK-NEXT: ('st_shndx', 0x00000004)
|
||||||
|
// CHECK-NEXT: ('st_value', 0x0000000000000000)
|
||||||
|
// CHECK-NEXT: ('st_size', 0x0000000000000000)
|
||||||
|
// CHECK-NEXT: ),
|
|
@ -68,6 +68,9 @@ OutputAsmVariant("output-asm-variant",
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
RelaxAll("mc-relax-all", cl::desc("Relax all fixups"));
|
RelaxAll("mc-relax-all", cl::desc("Relax all fixups"));
|
||||||
|
|
||||||
|
static cl::opt<bool>
|
||||||
|
NoExecStack("mc-no-exec-stack", cl::desc("File doesn't need an exec stack"));
|
||||||
|
|
||||||
static cl::opt<bool>
|
static cl::opt<bool>
|
||||||
EnableLogging("enable-api-logging", cl::desc("Enable MC API logging"));
|
EnableLogging("enable-api-logging", cl::desc("Enable MC API logging"));
|
||||||
|
|
||||||
|
@ -336,6 +339,7 @@ static int AssembleInput(const char *ProgName) {
|
||||||
TM->getTargetLowering()->getObjFileLowering();
|
TM->getTargetLowering()->getObjFileLowering();
|
||||||
const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
|
const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
|
||||||
|
|
||||||
|
// FIXME: There is a bit of code duplication with addPassesToEmitFile.
|
||||||
if (FileType == OFT_AssemblyFile) {
|
if (FileType == OFT_AssemblyFile) {
|
||||||
MCInstPrinter *IP =
|
MCInstPrinter *IP =
|
||||||
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
|
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
|
||||||
|
@ -355,7 +359,8 @@ static int AssembleInput(const char *ProgName) {
|
||||||
MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
|
MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
|
||||||
TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
|
TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
|
||||||
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
|
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
|
||||||
FOS, CE, RelaxAll));
|
FOS, CE, RelaxAll,
|
||||||
|
NoExecStack));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (EnableLogging) {
|
if (EnableLogging) {
|
||||||
|
|
Loading…
Reference in New Issue