diff --git a/llvm/include/llvm/MC/MCAsmInfo.h b/llvm/include/llvm/MC/MCAsmInfo.h index 6c12cd347901a..7a2e9ad154f01 100644 --- a/llvm/include/llvm/MC/MCAsmInfo.h +++ b/llvm/include/llvm/MC/MCAsmInfo.h @@ -464,10 +464,10 @@ class LLVM_ABI MCAsmInfo { const char *getData64bitsDirective() const { return Data64bitsDirective; } bool supportsSignedData() const { return SupportsSignedData; } - /// Targets can implement this method to specify a section to switch to if the - /// translation unit doesn't have any trampolines that require an executable - /// stack. - virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const { + /// Targets can implement this method to specify a section to switch to + /// depending on whether the translation unit has any trampolines that require + /// an executable stack. + virtual MCSection *getStackSection(MCContext &Ctx, bool Exec) const { return nullptr; } diff --git a/llvm/include/llvm/MC/MCAsmInfoELF.h b/llvm/include/llvm/MC/MCAsmInfoELF.h index e0678888d1003..095ee4dabca14 100644 --- a/llvm/include/llvm/MC/MCAsmInfoELF.h +++ b/llvm/include/llvm/MC/MCAsmInfoELF.h @@ -15,7 +15,7 @@ namespace llvm { class MCAsmInfoELF : public MCAsmInfo { virtual void anchor(); - MCSection *getNonexecutableStackSection(MCContext &Ctx) const override; + MCSection *getStackSection(MCContext &Ctx, bool Exec) const override; void printSwitchToSection(const MCSection &, uint32_t, const Triple &, raw_ostream &) const final; bool useCodeAlign(const MCSection &Sec) const final; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 11efe492c57cc..10df9c1f97eae 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -2866,9 +2866,11 @@ bool AsmPrinter::doFinalization(Module &M) { // 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 (MCSection *S = MAI->getNonexecutableStackSection(OutContext)) - OutStreamer->switchSection(S); + bool HasTrampolineUses = + InitTrampolineIntrinsic && !InitTrampolineIntrinsic->use_empty(); + MCSection *S = MAI->getStackSection(OutContext, /*Exec=*/HasTrampolineUses); + if (S) + OutStreamer->switchSection(S); if (TM.Options.EmitAddrsig) { // Emit address-significance attributes for all globals. diff --git a/llvm/lib/MC/MCAsmInfoELF.cpp b/llvm/lib/MC/MCAsmInfoELF.cpp index cdae9d7860f33..98090d34bcbdc 100644 --- a/llvm/lib/MC/MCAsmInfoELF.cpp +++ b/llvm/lib/MC/MCAsmInfoELF.cpp @@ -27,12 +27,13 @@ using namespace llvm; void MCAsmInfoELF::anchor() {} -MCSection *MCAsmInfoELF::getNonexecutableStackSection(MCContext &Ctx) const { +MCSection *MCAsmInfoELF::getStackSection(MCContext &Ctx, bool Exec) const { // Solaris doesn't know/doesn't care about .note.GNU-stack sections, so // don't emit them. if (Ctx.getTargetTriple().isOSSolaris()) return nullptr; - return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0); + return Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, + Exec ? ELF::SHF_EXECINSTR : 0U); } bool MCAsmInfoELF::useCodeAlign(const MCSection &Sec) const { diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 2881d7cfab4ba..1bc1b92610871 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -54,7 +54,7 @@ void MCELFStreamer::initSections(bool NoExecStack, const MCSubtargetInfo &STI) { &STI); if (NoExecStack) - switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); + switchSection(Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false)); } void MCELFStreamer::emitLabel(MCSymbol *S, SMLoc Loc) { diff --git a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h index dfd896fbc735f..8d8066a55b43e 100644 --- a/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h +++ b/llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h @@ -49,7 +49,7 @@ class BPFMCAsmInfo : public MCAsmInfoELF { DwarfUsesRelocationsAcrossSections = enable; } - MCSection *getNonexecutableStackSection(MCContext &Ctx) const override { + MCSection *getStackSection(MCContext &Ctx, bool Exec) const override { return nullptr; } }; diff --git a/llvm/test/CodeGen/AArch64/trampoline.ll b/llvm/test/CodeGen/AArch64/trampoline.ll index 0e682704afbf8..3e933fadc4fa2 100644 --- a/llvm/test/CodeGen/AArch64/trampoline.ll +++ b/llvm/test/CodeGen/AArch64/trampoline.ll @@ -263,3 +263,9 @@ define i64 @func2() { %fp = call ptr @llvm.adjust.trampoline(ptr @trampg) ret i64 0 } + +; Check for the explicitly emitted .note.GNU-stack section (ELF only) in the +; presence of trampolines. +; UTC_ARGS: --disable +; CHECK-LINUX: .section ".note.GNU-stack","x",@progbits +; UTC_ARGS: --enable diff --git a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll index 34d46579518ea..c68fa59cd5780 100644 --- a/llvm/test/CodeGen/RISCV/rv64-trampoline.ll +++ b/llvm/test/CodeGen/RISCV/rv64-trampoline.ll @@ -78,3 +78,10 @@ define i64 @test0(i64 %n, ptr %p) nounwind { ret i64 %ret } + +; Check for the explicitly emitted .note.GNU-stack section (ELF only) in the +; presence of trampolines. +; UTC_ARGS: --disable +; RV64-LINUX: .section ".note.GNU-stack","x",@progbits +; RV64: .section ".note.GNU-stack","x",@progbits +; UTC_ARGS: --enable diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index ba550792cef40..2a89961cd7bbb 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -642,7 +642,8 @@ int main(int argc, char **argv) { : MAB->createObjectWriter(*OS), std::unique_ptr(CE), *STI)); if (NoExecStack) - Str->switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx)); + Str->switchSection( + Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false)); Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr, VersionTuple()); }