[AArch64] Always add PURECODE flag to empty .text if "+execute-only" is set by Il-Capitano · Pull Request #132196 · llvm/llvm-project (original) (raw)
@llvm/pr-subscribers-backend-aarch64
Author: Csanád Hajdú (Il-Capitano)
Changes
The previous approach only added the SHF_AARCH64_PURECODE
section flag to the implicitly created .text
section if there was any other section containing the flag already. This doesn't work for the case, where the module doesn't contain any code.
Now, the SHF_AARCH64_PURECODE
is always added if the "+execute-only" target feature is set for the module.
Full diff: https://github.com/llvm/llvm-project/pull/132196.diff
3 Files Affected:
- (modified) llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp (+9)
- (modified) llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp (-18)
- (added) llvm/test/CodeGen/AArch64/execute-only-empty.ll (+13)
diff --git a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp index 434ae32502d48..b662e75741d38 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ b/llvm/lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -16,6 +16,7 @@ #include "llvm/IR/Module.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" +#include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCValue.h" using namespace llvm; @@ -27,6 +28,14 @@ void AArch64_ELFTargetObjectFile::Initialize(MCContext &Ctx, // AARCH64 ELF ABI does not define static relocation type for TLS offset // within a module. Do not generate AT_location for TLS variables. SupportDebugThreadLocalLocation = false; + + // Make sure the implicitly created empty .text section has the + // SHF_AARCH64_PURECODE flag set if the "+execute-only" target feature is + // present. + if (TM.getMCSubtargetInfo()->hasFeature(AArch64::FeatureExecuteOnly)) { + auto *Text = cast(TextSection); + Text->setFlags(Text->getFlags() | ELF::SHF_AARCH64_PURECODE); + } } void AArch64_ELFTargetObjectFile::emitPersonalityValueImpl( diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp index 98bd102d8f4c1..9803129608c4b 100644 --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64ELFStreamer.cpp @@ -27,7 +27,6 @@ #include "llvm/MC/MCELFStreamer.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCInst.h" -#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSectionELF.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -501,23 +500,6 @@ void AArch64TargetELFStreamer::finish() { } } - // The mix of execute-only and non-execute-only at link time is - // non-execute-only. To avoid the empty implicitly created .text - // section from making the whole .text section non-execute-only, we - // mark it execute-only if it is empty and there is at least one - // execute-only section in the object. - if (any_of(Asm, [](const MCSection &Sec) { - return cast(Sec).getFlags() & ELF::SHF_AARCH64_PURECODE; - })) { - auto *Text = - static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection()); - for (auto &F : *Text) - if (auto *DF = dyn_cast(&F)) - if (!DF->getContents().empty()) - return; - Text->setFlags(Text->getFlags() | ELF::SHF_AARCH64_PURECODE); - }
MCSectionELF *MemtagSec = nullptr; for (const MCSymbol &Symbol : Asm.symbols()) { const auto &Sym = cast(Symbol); diff --git a/llvm/test/CodeGen/AArch64/execute-only-empty.ll b/llvm/test/CodeGen/AArch64/execute-only-empty.ll new file mode 100644 index 0000000000000..cdf9b3afe8daf --- /dev/null +++ b/llvm/test/CodeGen/AArch64/execute-only-empty.ll @@ -0,0 +1,13 @@ +; RUN: llc -filetype=obj -mtriple=aarch64 -mattr=+execute-only %s -o %t.o +; RUN: llvm-readobj -S %t.o | FileCheck %s + +; CHECK: Name: .text +; CHECK-NEXT: Type: SHT_PROGBITS +; CHECK-NEXT: Flags [ +; CHECK-NEXT: SHF_AARCH64_PURECODE +; CHECK-NEXT: SHF_ALLOC +; CHECK-NEXT: SHF_EXECINSTR +; CHECK-NEXT: ] +; CHECK-NEXT: Address: +; CHECK-NEXT: Offset: +; CHECK-NEXT: Size: 0