Index: lib/Target/ARM/ARMTargetObjectFile.cpp =================================================================== --- lib/Target/ARM/ARMTargetObjectFile.cpp +++ lib/Target/ARM/ARMTargetObjectFile.cpp @@ -32,7 +32,7 @@ const TargetMachine &TM) { const ARMBaseTargetMachine &ARM_TM = static_cast(TM); bool isAAPCS_ABI = ARM_TM.TargetABI == ARMBaseTargetMachine::ARMABI::ARM_ABI_AAPCS; - // genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly(); + bool genExecuteOnly = ARM_TM.getMCSubtargetInfo()->hasFeature(ARM::FeatureExecuteOnly); TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(isAAPCS_ABI); @@ -40,6 +40,16 @@ if (isAAPCS_ABI) { LSDASection = nullptr; } + + // 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); + } } const MCExpr *ARMElfTargetObjectFile::getTTypeGlobalReference( Index: test/MC/ARM/elf-execute-only-section.ll =================================================================== --- /dev/null +++ test/MC/ARM/elf-execute-only-section.ll @@ -0,0 +1,13 @@ +; RUN: llc < %s -mtriple=thumbv8m.base-eabi -mattr=+execute-only -filetype=obj %s -o - | \ +; RUN: llvm-readelf -s | FileCheck %s +; RUN: llc < %s -mtriple=thumbv8m.main-eabi -mattr=+execute-only -filetype=obj %s -o - | \ +; RUN: llvm-readelf -s | FileCheck %s +; RUN: llc < %s -mtriple=thumbv7m-eabi -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 +}