[llvm] 24c1bb6 - [MC] Make .note.GNU-stack explicit for the trampoline case (#151754)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 4 15:22:59 PDT 2025
Author: ssijaric-nv
Date: 2025-10-04T15:22:54-07:00
New Revision: 24c1bb60e321c16cb8247b45b080b2d5e02a2b31
URL: https://github.com/llvm/llvm-project/commit/24c1bb60e321c16cb8247b45b080b2d5e02a2b31
DIFF: https://github.com/llvm/llvm-project/commit/24c1bb60e321c16cb8247b45b080b2d5e02a2b31.diff
LOG: [MC] Make .note.GNU-stack explicit for the trampoline case (#151754)
In the presence of trampolines, the .note.GNU-stack section is not emitted. The
absence of .note.GNU-stack results in the stack marked executable by some
linkers. But others require an explict .note.GNU-stack section.
The GNU ld 2.43 on x86 machines, for example, issues the following:
missing .note.GNU-stack section implies executable stack
NOTE: This behaviour is deprecated and will be removed in a future version of the linker
On one of the ARM machines, the absence of .note.GNU-stack results in the stack
marked as non-executable:
STACK off 0x0000000000000000 vaddr 0x0000000000000000 paddr 0x0000000000000000 align 2**4
filesz 0x0000000000000000 memsz 0x0000000000000000 flags rw-
This change just emits the explicit .note.GNU-stack and marks it executable if required.
Added:
Modified:
llvm/include/llvm/MC/MCAsmInfo.h
llvm/include/llvm/MC/MCAsmInfoELF.h
llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/lib/MC/MCAsmInfoELF.cpp
llvm/lib/MC/MCELFStreamer.cpp
llvm/lib/Target/BPF/MCTargetDesc/BPFMCAsmInfo.h
llvm/test/CodeGen/AArch64/trampoline.ll
llvm/test/CodeGen/RISCV/rv64-trampoline.ll
llvm/tools/llvm-mc/llvm-mc.cpp
Removed:
################################################################################
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", at 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", at progbits
+; RV64: .section ".note.GNU-stack","x", at 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<MCCodeEmitter>(CE), *STI));
if (NoExecStack)
- Str->switchSection(Ctx.getAsmInfo()->getNonexecutableStackSection(Ctx));
+ Str->switchSection(
+ Ctx.getAsmInfo()->getStackSection(Ctx, /*Exec=*/false));
Str->emitVersionForTarget(TheTriple, VersionTuple(), nullptr,
VersionTuple());
}
More information about the llvm-commits
mailing list