Index: lib/Target/AArch64/AArch64TargetObjectFile.cpp =================================================================== --- lib/Target/AArch64/AArch64TargetObjectFile.cpp +++ lib/Target/AArch64/AArch64TargetObjectFile.cpp @@ -10,6 +10,7 @@ #include "AArch64TargetObjectFile.h" #include "AArch64TargetMachine.h" #include "llvm/BinaryFormat/Dwarf.h" +#include "llvm/BinaryFormat/ELF.h" #include "llvm/IR/Mangler.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCExpr.h" @@ -23,6 +24,18 @@ const TargetMachine &TM) { TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(TM.Options.UseInitArray); + + bool genExecuteOnly = TM.getMCSubtargetInfo()->hasFeature(AArch64::FeatureExecuteOnly); + + // Make code section unreadable when in execute-only mode + if (genExecuteOnly) { + unsigned Type = ELF::SHT_PROGBITS; + unsigned Flags = ELF::SHF_EXECINSTR | ELF::SHF_ALLOC | ELF::SHF_ARM_PURECODE; + // Since we cannot modify flags for an existing section, we create a new + // section with the right flags, and use 0 as the unique ID for + // execute-only text + TextSection = Ctx.getELFSection(".text", Type, Flags, 0, "", 0U); + } } AArch64_MachoTargetObjectFile::AArch64_MachoTargetObjectFile() Index: test/MC/AArch64/elf-execute-only-section.ll =================================================================== --- /dev/null +++ test/MC/AArch64/elf-execute-only-section.ll @@ -0,0 +1,9 @@ +; RUN: llc < %s -mtriple=aarch64 -mattr=+execute-only -filetype=obj %s -o - |\ +; RUN: llvm-readelf -s | FileCheck %s + +; CHECK-NOT: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AX[^p]}} +; CHECK: {{.text[ ]+PROGBITS[ ]+[0-9]+ [0-9]+ [0-9]+ [0-9]+ AXp}} +define void @test_func() { +entry: + ret void +}