Add support for the --noexecstack option.

llvm-svn: 124077
This commit is contained in:
Rafael Espindola 2011-01-23 17:55:27 +00:00
parent 8f01420d9d
commit b3eca9bb71
14 changed files with 89 additions and 25 deletions

View File

@ -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
/// @{ /// @{

View File

@ -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.

View File

@ -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; }

View File

@ -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.

View File

@ -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;
} }

View File

@ -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;

View File

@ -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)
{ {
} }

View File

@ -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;
} }

View File

@ -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);
} }
} }

View File

@ -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);
} }
} }

View File

@ -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);

View File

@ -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);
} }
} }

24
llvm/test/MC/ELF/noexec.s Normal file
View File

@ -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: ),

View File

@ -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) {