From a779a9899a5e23bd5198973f4709d66cb4bc2e64 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 5 May 2008 00:28:39 +0000 Subject: [PATCH] Add AsmPrinter support for emitting a directive to declare that the code being generated does not require an executable stack. Also, add target-specific code to make use of this on Linux on x86. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@50634 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetAsmInfo.h | 9 +++++++++ lib/CodeGen/AsmPrinter.cpp | 7 +++++++ lib/Target/TargetAsmInfo.cpp | 1 + lib/Target/X86/X86Subtarget.cpp | 5 +++++ lib/Target/X86/X86Subtarget.h | 9 +++++++-- lib/Target/X86/X86TargetAsmInfo.cpp | 5 +++++ test/CodeGen/X86/xor_not.ll | 4 ++-- 7 files changed, 36 insertions(+), 4 deletions(-) diff --git a/include/llvm/Target/TargetAsmInfo.h b/include/llvm/Target/TargetAsmInfo.h index 7fd88b2eae9..b635cb2e3c6 100644 --- a/include/llvm/Target/TargetAsmInfo.h +++ b/include/llvm/Target/TargetAsmInfo.h @@ -61,10 +61,16 @@ namespace llvm { /// Null if this target doesn't support a BSS section. /// const char *TLSBSSSection;// Default to ".section .tbss,"awT",@nobits". + /// ZeroFillDirective - Directive for emitting a global to the ZeroFill /// section on this target. Null if this target doesn't support zerofill. const char *ZeroFillDirective; // Default is null. + /// NonexecutableStackDirective - Directive for declaring to the + /// linker and beyond that the emitted code does not require stack + /// memory to be executable. + const char *NonexecutableStackDirective; // Default is null. + /// NeedsSet - True if target asm treats expressions in data directives /// as linktime-relocatable. For assembly-time computation, we need to /// use a .set. Thus: @@ -440,6 +446,9 @@ namespace llvm { const char *getZeroFillDirective() const { return ZeroFillDirective; } + const char *getNonexecutableStackDirective() const { + return NonexecutableStackDirective; + } bool needsSet() const { return NeedsSet; } diff --git a/lib/CodeGen/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter.cpp index 65b8c436f78..9c4e789251a 100644 --- a/lib/CodeGen/AsmPrinter.cpp +++ b/lib/CodeGen/AsmPrinter.cpp @@ -192,6 +192,13 @@ bool AsmPrinter::doFinalization(Module &M) { E = CMM->begin(); I != E; ) (*--I)->finishAssembly(O, *this, *TAI); + // If we don't have any trampolines, then we don't require stack memory + // to be executable. Some targets have a directive to declare this. + Function* InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline"); + if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty()) + if (TAI->getNonexecutableStackDirective()) + O << TAI->getNonexecutableStackDirective() << "\n"; + delete Mang; Mang = 0; return false; } diff --git a/lib/Target/TargetAsmInfo.cpp b/lib/Target/TargetAsmInfo.cpp index 21699450225..c2504cc5802 100644 --- a/lib/Target/TargetAsmInfo.cpp +++ b/lib/Target/TargetAsmInfo.cpp @@ -26,6 +26,7 @@ TargetAsmInfo::TargetAsmInfo() : TLSDataSection("\t.section .tdata,\"awT\",@progbits"), TLSBSSSection("\t.section .tbss,\"awT\",@nobits"), ZeroFillDirective(0), + NonexecutableStackDirective(0), NeedsSet(false), MaxInstLength(4), PCSymbol("$"), diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp index e0f350c5a1c..e555079738f 100644 --- a/lib/Target/X86/X86Subtarget.cpp +++ b/lib/Target/X86/X86Subtarget.cpp @@ -278,6 +278,8 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) DarwinVers = atoi(&TT[Pos+7]); else DarwinVers = 8; // Minimum supported darwin is Tiger. + } else if (TT.find("linux") != std::string::npos) { + TargetType = isELFLinux; } else if (TT.find("cygwin") != std::string::npos) { TargetType = isCygwin; } else if (TT.find("mingw") != std::string::npos) { @@ -302,6 +304,9 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) #elif defined(_WIN32) || defined(_WIN64) TargetType = isWindows; +#elif defined(__linux__) + // Linux doesn't imply ELF, but we don't currently support anything else. + TargetType = isELFLinux; #endif } diff --git a/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h index c91088dcdf6..1e955cd8687 100644 --- a/lib/Target/X86/X86Subtarget.h +++ b/lib/Target/X86/X86Subtarget.h @@ -84,7 +84,7 @@ private: public: enum { - isELF, isCygwin, isDarwin, isWindows, isMingw + isELF, isELFLinux, isCygwin, isDarwin, isWindows, isMingw } TargetType; /// This constructor initializes the data members to match that @@ -132,7 +132,12 @@ public: bool isFlavorIntel() const { return AsmFlavor == Intel; } bool isTargetDarwin() const { return TargetType == isDarwin; } - bool isTargetELF() const { return TargetType == isELF; } + bool isTargetELF() const { + return TargetType == isELF || TargetType == isELFLinux; + } + bool isTargetLinux() const { + return TargetType == isELFLinux; + } bool isTargetWindows() const { return TargetType == isWindows; } bool isTargetMingw() const { return TargetType == isMingw; } bool isTargetCygMing() const { return (TargetType == isMingw || diff --git a/lib/Target/X86/X86TargetAsmInfo.cpp b/lib/Target/X86/X86TargetAsmInfo.cpp index 7636d77f08e..4aa9d4cfa8b 100644 --- a/lib/Target/X86/X86TargetAsmInfo.cpp +++ b/lib/Target/X86/X86TargetAsmInfo.cpp @@ -128,6 +128,7 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) { break; case X86Subtarget::isELF: + case X86Subtarget::isELFLinux: ReadOnlySection = "\t.section\t.rodata"; FourByteConstantSection = "\t.section\t.rodata.cst4,\"aM\",@progbits,4"; EightByteConstantSection = "\t.section\t.rodata.cst8,\"aM\",@progbits,8"; @@ -229,6 +230,10 @@ X86TargetAsmInfo::X86TargetAsmInfo(const X86TargetMachine &TM) { SectionEndDirectiveSuffix = "\tends\n"; } + // On Linux we must declare when we can use a non-executable stack. + if (Subtarget->isTargetLinux()) + NonexecutableStackDirective = "\t.section\t.note.GNU-stack,\"\",@progbits"; + AssemblerDialect = Subtarget->getAsmFlavor(); } diff --git a/test/CodeGen/X86/xor_not.ll b/test/CodeGen/X86/xor_not.ll index de740cfb837..1e89ca8e053 100644 --- a/test/CodeGen/X86/xor_not.ll +++ b/test/CodeGen/X86/xor_not.ll @@ -1,5 +1,5 @@ -; RUN: llvm-as < %s | llc -march=x86 | grep {not} | count 3 -; RUN: llvm-as < %s | llc -march=x86-64 | grep {not} | count 4 +; RUN: llvm-as < %s | llc -march=x86 | grep {not\[lwb\]} | count 3 +; RUN: llvm-as < %s | llc -march=x86-64 | grep {not\[lwb\]} | count 4 define i32 @test(i32 %a, i32 %b) nounwind { entry: %tmp1not = xor i32 %b, -2