summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2011-01-23 17:55:27 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2011-01-23 17:55:27 +0000
commit96aa78c8c5ef1a5f268539c9edc86569b436d573 (patch)
treee664056c0f0a8ce32c72d19cf0f0ae1e8eefd038
parent584520e8e2c1f8cc04bc8dd4dc4ea6c390627317 (diff)
downloadllvm-96aa78c8c5ef1a5f268539c9edc86569b436d573.tar.gz
llvm-96aa78c8c5ef1a5f268539c9edc86569b436d573.tar.bz2
llvm-96aa78c8c5ef1a5f268539c9edc86569b436d573.tar.xz
Add support for the --noexecstack option.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124077 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/MC/MCAssembler.h4
-rw-r--r--include/llvm/MC/MCStreamer.h2
-rw-r--r--include/llvm/Target/TargetMachine.h7
-rw-r--r--include/llvm/Target/TargetRegistry.h10
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp3
-rw-r--r--lib/MC/ELFObjectWriter.cpp30
-rw-r--r--lib/MC/MCAssembler.cpp2
-rw-r--r--lib/MC/MCELFStreamer.cpp6
-rw-r--r--lib/Target/ARM/ARMTargetMachine.cpp5
-rw-r--r--lib/Target/MBlaze/MBlazeTargetMachine.cpp6
-rw-r--r--lib/Target/PowerPC/PPCTargetMachine.cpp3
-rw-r--r--lib/Target/X86/X86TargetMachine.cpp5
-rw-r--r--test/MC/ELF/noexec.s24
-rw-r--r--tools/llvm-mc/llvm-mc.cpp7
14 files changed, 89 insertions, 25 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h
index 79d2c8ea41..30971c62a9 100644
--- a/include/llvm/MC/MCAssembler.h
+++ b/include/llvm/MC/MCAssembler.h
@@ -694,6 +694,7 @@ private:
SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
unsigned RelaxAll : 1;
+ unsigned NoExecStack : 1;
unsigned SubsectionsViaSymbols : 1;
private:
@@ -808,6 +809,9 @@ public:
bool getRelaxAll() const { return RelaxAll; }
void setRelaxAll(bool Value) { RelaxAll = Value; }
+ bool getNoExecStack() const { return NoExecStack; }
+ void setNoExecStack(bool Value) { NoExecStack = Value; }
+
/// @name Section List Access
/// @{
diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h
index 7c2de30649..1be2dc6bb6 100644
--- a/include/llvm/MC/MCStreamer.h
+++ b/include/llvm/MC/MCStreamer.h
@@ -469,7 +469,7 @@ namespace llvm {
/// ELF format object files.
MCStreamer *createELFStreamer(MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll = false);
+ bool RelaxAll, bool NoExecStack);
/// createLoggingStreamer - Create a machine code streamer which just logs the
/// API calls and then dispatches to another streamer.
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index c3136cd487..030bf5b89f 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -104,6 +104,7 @@ protected: // Can only create subclasses.
const MCAsmInfo *AsmInfo;
unsigned MCRelaxAll : 1;
+ unsigned MCNoExecStack : 1;
unsigned MCUseLoc : 1;
public:
@@ -170,6 +171,12 @@ public:
/// relaxed.
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.
bool hasMCUseLoc() const { return MCUseLoc; }
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index 6cdb68f134..f851ad0a9b 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -89,7 +89,8 @@ namespace llvm {
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll);
+ bool RelaxAll,
+ bool NoExecStack);
typedef MCStreamer *(*AsmStreamerCtorTy)(MCContext &Ctx,
formatted_raw_ostream &OS,
bool isVerboseAsm,
@@ -308,14 +309,17 @@ namespace llvm {
/// \arg _OS - The stream object.
/// \arg _Emitter - The target independent assembler object.Takes ownership.
/// \arg RelaxAll - Relax all fixups?
+ /// \arg NoExecStack - Mark file as not needing a executable stack.
MCStreamer *createObjectStreamer(const std::string &TT, MCContext &Ctx,
TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll) const {
+ bool RelaxAll,
+ bool NoExecStack) const {
if (!ObjectStreamerCtorFn)
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.
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 5cff96db73..80dfc763af 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -168,7 +168,8 @@ bool LLVMTargetMachine::addPassesToEmitFile(PassManagerBase &PM,
AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Context,
*TAB, Out, MCE,
- hasMCRelaxAll()));
+ hasMCRelaxAll(),
+ hasMCNoExecStack()));
AsmStreamer.get()->InitSections();
break;
}
diff --git a/lib/MC/ELFObjectWriter.cpp b/lib/MC/ELFObjectWriter.cpp
index 05dd0c7629..4dbb5387f3 100644
--- a/lib/MC/ELFObjectWriter.cpp
+++ b/lib/MC/ELFObjectWriter.cpp
@@ -329,8 +329,11 @@ namespace {
virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout,
const SectionIndexMapTy &SectionIndexMap);
- virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout,
- GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap);
+ // Create the sections that show up in the symbol table. Currently
+ // 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,
const MCAsmLayout &Layout);
@@ -1174,10 +1177,19 @@ ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
return &SecA == &SecB;
}
-void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
- MCAsmLayout &Layout,
- GroupMapTy &GroupMap,
- RevGroupMapTy &RevGroupMap) {
+void ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm,
+ MCAsmLayout &Layout,
+ GroupMapTy &GroupMap,
+ 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
for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end();
it != ie; ++it) {
@@ -1190,7 +1202,7 @@ void ELFObjectWriter::CreateGroupSections(MCAssembler &Asm,
Asm.getOrCreateSymbolData(*SignatureSymbol);
const MCSectionELF *&Group = RevGroupMap[SignatureSymbol];
if (!Group) {
- Group = Asm.getContext().CreateELFGroupSection();
+ Group = Ctx.CreateELFGroupSection();
MCSectionData &Data = Asm.getOrCreateSectionData(*Group);
Data.setAlignment(4);
MCDataFragment *F = new MCDataFragment(&Data);
@@ -1334,8 +1346,8 @@ void ELFObjectWriter::WriteObject(MCAssembler &Asm,
const MCAsmLayout &Layout) {
GroupMapTy GroupMap;
RevGroupMapTy RevGroupMap;
- CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
- RevGroupMap);
+ CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap,
+ RevGroupMap);
SectionIndexMapTy SectionIndexMap;
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index 5b291490f7..587068aee5 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -172,7 +172,7 @@ MCAssembler::MCAssembler(MCContext &Context_, TargetAsmBackend &Backend_,
MCCodeEmitter &Emitter_, MCObjectWriter &Writer_,
raw_ostream &OS_)
: Context(Context_), Backend(Backend_), Emitter(Emitter_), Writer(Writer_),
- OS(OS_), RelaxAll(false), SubsectionsViaSymbols(false)
+ OS(OS_), RelaxAll(false), NoExecStack(false), SubsectionsViaSymbols(false)
{
}
diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp
index 6a6c9338ab..ac31057065 100644
--- a/lib/MC/MCELFStreamer.cpp
+++ b/lib/MC/MCELFStreamer.cpp
@@ -515,10 +515,12 @@ void MCELFStreamer::Finish() {
}
MCStreamer *llvm::createELFStreamer(MCContext &Context, TargetAsmBackend &TAB,
- raw_ostream &OS, MCCodeEmitter *CE,
- bool RelaxAll) {
+ raw_ostream &OS, MCCodeEmitter *CE,
+ bool RelaxAll, bool NoExecStack) {
MCELFStreamer *S = new MCELFStreamer(Context, TAB, OS, CE);
if (RelaxAll)
S->getAssembler().setRelaxAll(true);
+ if (NoExecStack)
+ S->getAssembler().setNoExecStack(true);
return S;
}
diff --git a/lib/Target/ARM/ARMTargetMachine.cpp b/lib/Target/ARM/ARMTargetMachine.cpp
index a68fd4945e..60df718ad2 100644
--- a/lib/Target/ARM/ARMTargetMachine.cpp
+++ b/lib/Target/ARM/ARMTargetMachine.cpp
@@ -39,7 +39,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &OS,
MCCodeEmitter *Emitter,
- bool RelaxAll) {
+ bool RelaxAll,
+ bool NoExecStack) {
switch (Triple(TT).getOS()) {
case Triple::Darwin:
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");
return NULL;
default:
- return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
+ return createELFStreamer(Ctx, TAB, OS, Emitter, RelaxAll, NoExecStack);
}
}
diff --git a/lib/Target/MBlaze/MBlazeTargetMachine.cpp b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
index f53dbb0dd6..f83f70b5e1 100644
--- a/lib/Target/MBlaze/MBlazeTargetMachine.cpp
+++ b/lib/Target/MBlaze/MBlazeTargetMachine.cpp
@@ -33,7 +33,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll) {
+ bool RelaxAll,
+ bool NoExecStack) {
Triple TheTriple(TT);
switch (TheTriple.getOS()) {
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");
return NULL;
default:
- return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
+ return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll,
+ NoExecStack);
}
}
diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp
index ad7c5284e3..212b450e7d 100644
--- a/lib/Target/PowerPC/PPCTargetMachine.cpp
+++ b/lib/Target/PowerPC/PPCTargetMachine.cpp
@@ -35,7 +35,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &OS,
MCCodeEmitter *Emitter,
- bool RelaxAll) {
+ bool RelaxAll,
+ bool NoExecStack) {
switch (Triple(TT).getOS()) {
case Triple::Darwin:
return createMachOStreamer(Ctx, TAB, OS, Emitter, RelaxAll);
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 2e4bcde07a..8de20a366c 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -43,7 +43,8 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
MCContext &Ctx, TargetAsmBackend &TAB,
raw_ostream &_OS,
MCCodeEmitter *_Emitter,
- bool RelaxAll) {
+ bool RelaxAll,
+ bool NoExecStack) {
Triple TheTriple(TT);
switch (TheTriple.getOS()) {
case Triple::Darwin:
@@ -54,7 +55,7 @@ static MCStreamer *createMCStreamer(const Target &T, const std::string &TT,
case Triple::Win32:
return createWinCOFFStreamer(Ctx, TAB, *_Emitter, _OS, RelaxAll);
default:
- return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll);
+ return createELFStreamer(Ctx, TAB, _OS, _Emitter, RelaxAll, NoExecStack);
}
}
diff --git a/test/MC/ELF/noexec.s b/test/MC/ELF/noexec.s
new file mode 100644
index 0000000000..87b6f3aa85
--- /dev/null
+++ b/test/MC/ELF/noexec.s
@@ -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: ),
diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index 87082047ee..2c22bedf1c 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -69,6 +69,9 @@ static cl::opt<bool>
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>
EnableLogging("enable-api-logging", cl::desc("Enable MC API logging"));
enum OutputFileType {
@@ -336,6 +339,7 @@ static int AssembleInput(const char *ProgName) {
TM->getTargetLowering()->getObjFileLowering();
const_cast<TargetLoweringObjectFile&>(TLOF).Initialize(Ctx, *TM);
+ // FIXME: There is a bit of code duplication with addPassesToEmitFile.
if (FileType == OFT_AssemblyFile) {
MCInstPrinter *IP =
TheTarget->createMCInstPrinter(OutputAsmVariant, *MAI);
@@ -355,7 +359,8 @@ static int AssembleInput(const char *ProgName) {
MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx);
TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName);
Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB,
- FOS, CE, RelaxAll));
+ FOS, CE, RelaxAll,
+ NoExecStack));
}
if (EnableLogging) {