Add support for the --noexecstack option.
authorRafael Espindola <rafael.espindola@gmail.com>
Sun, 23 Jan 2011 17:55:27 +0000 (17:55 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sun, 23 Jan 2011 17:55:27 +0000 (17:55 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@124077 91177308-0d34-0410-b5e6-96231b3b80d8

14 files changed:
include/llvm/MC/MCAssembler.h
include/llvm/MC/MCStreamer.h
include/llvm/Target/TargetMachine.h
include/llvm/Target/TargetRegistry.h
lib/CodeGen/LLVMTargetMachine.cpp
lib/MC/ELFObjectWriter.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCELFStreamer.cpp
lib/Target/ARM/ARMTargetMachine.cpp
lib/Target/MBlaze/MBlazeTargetMachine.cpp
lib/Target/PowerPC/PPCTargetMachine.cpp
lib/Target/X86/X86TargetMachine.cpp
test/MC/ELF/noexec.s [new file with mode: 0644]
tools/llvm-mc/llvm-mc.cpp

index 79d2c8ea41ae4e6f71ed41d0c19d160884eb92ae..30971c62a97e54d2c4870b90fd4e66b8be5c0314 100644 (file)
@@ -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
   /// @{
 
index 7c2de30649fe76e97a0fdec3adba582e8707781c..1be2dc6bb6d7d840090afe73493b0ed2746bf063 100644 (file)
@@ -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.
index c3136cd4875df03554da53ea345a63fc90d3f6f5..030bf5b89f7716c94e9b81205d28e848e7b6073c 100644 (file)
@@ -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; }
 
index 6cdb68f134852ab0600880dbd8992f9f3643e189..f851ad0a9bfb1307ba3babd98f6bbde6ab3e8e0e 100644 (file)
@@ -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.
index 5cff96db736c38e7f22c2da7f9af36d4406fc927..80dfc763af6977c4a7efcb30d370bc11f534942a 100644 (file)
@@ -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;
   }
index 05dd0c76298863c56c0faddb2aae5a72a18736b7..4dbb5387f3dae98da7dec37d2dcb187669c4a8a4 100644 (file)
@@ -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;
 
index 5b291490f71a632da7053bf8ad5d5fd4fc9c7ed9..587068aee5f5de8e15b17f83ca499b33aea2c718 100644 (file)
@@ -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)
 {
 }
 
index 6a6c9338abf3f7510d1baef9e4a40f8877579a70..ac3105706531842e7b03a0da2c8d5c797bc80248 100644 (file)
@@ -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;
 }
index a68fd4945e4d42a341647a53792a19cc181c8cd4..60df718ad21af5205ca221eff6df19c64d1b00b5 100644 (file)
@@ -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);
   }
 }
 
index f53dbb0dd63851e370f2ff56914f31f86693f34f..f83f70b5e1e5926311d273eb22f31870563a1a60 100644 (file)
@@ -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);
   }
 }
 
index ad7c5284e35dca95f5382e53217602210155ca1c..212b450e7db998ecbffbb016701310a58346a157 100644 (file)
@@ -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);
index 2e4bcde07a3127eefaf48d33d28ad32fc3f9b2c4..8de20a366cbd478151e413eddbc6482b08a0a093 100644 (file)
@@ -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 (file)
index 0000000..87b6f3a
--- /dev/null
@@ -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:  ),
index 87082047eef920db56c58bbc713de3f8f43d5f9d..2c22bedf1c2d6ad787b14c5fbc7dddcd8b46d36a 100644 (file)
@@ -68,6 +68,9 @@ OutputAsmVariant("output-asm-variant",
 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"));
 
@@ -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) {