diff options
author | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-12-15 07:59:08 +0000 |
---|---|---|
committer | Prakhar Bahuguna <prakhar.bahuguna@arm.com> | 2016-12-15 07:59:08 +0000 |
commit | 52a7dd7d7825b269ae569db0e2bcb193c7698666 (patch) | |
tree | 7957bd2c8f0c07fbbcfdc331ca848a051dab6613 /llvm/lib/Target/ARM/ARMTargetObjectFile.cpp | |
parent | 342beeb91eb03ce92e598d593325c8475673768e (diff) | |
download | llvm-52a7dd7d7825b269ae569db0e2bcb193c7698666.zip llvm-52a7dd7d7825b269ae569db0e2bcb193c7698666.tar.gz llvm-52a7dd7d7825b269ae569db0e2bcb193c7698666.tar.bz2 |
[ARM] Implement execute-only support in CodeGen
This implements execute-only support for ARM code generation, which
prevents the compiler from generating data accesses to code sections.
The following changes are involved:
* Add the CodeGen option "-arm-execute-only" to the ARM code generator.
* Add the clang flag "-mexecute-only" as well as the GCC-compatible
alias "-mpure-code" to enable this option.
* When enabled, literal pools are replaced with MOVW/MOVT instructions,
with VMOV used in addition for floating-point literals. As the MOVT
instruction is required, execute-only support is only available in
Thumb mode for targets supporting ARMv8-M baseline or Thumb2.
* Jump tables are placed in data sections when in execute-only mode.
* The execute-only text section is assigned section ID 0, and is
marked as unreadable with the SHF_ARM_PURECODE flag with symbol 'y'.
This also overrides selection of ELF sections for globals.
llvm-svn: 289784
Diffstat (limited to 'llvm/lib/Target/ARM/ARMTargetObjectFile.cpp')
-rw-r--r-- | llvm/lib/Target/ARM/ARMTargetObjectFile.cpp | 36 |
1 files changed, 34 insertions, 2 deletions
diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp index ec364e8..625c428 100644 --- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -27,8 +27,10 @@ using namespace dwarf; void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { - bool isAAPCS_ABI = static_cast<const ARMTargetMachine &>(TM).TargetABI == - ARMTargetMachine::ARMABI::ARM_ABI_AAPCS; + const ARMTargetMachine &ARM_TM = static_cast<const ARMTargetMachine &>(TM); + bool isAAPCS_ABI = ARM_TM.TargetABI == ARMTargetMachine::ARMABI::ARM_ABI_AAPCS; + genExecuteOnly = ARM_TM.getSubtargetImpl()->genExecuteOnly(); + TargetLoweringObjectFileELF::Initialize(Ctx, TM); InitializeELF(isAAPCS_ABI); @@ -38,6 +40,16 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, AttributesSection = getContext().getELFSection(".ARM.attributes", ELF::SHT_ARM_ATTRIBUTES, 0); + + // 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( @@ -58,3 +70,23 @@ getDebugThreadLocalSymbol(const MCSymbol *Sym) const { return MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_ARM_TLSLDO, getContext()); } + +MCSection * +ARMElfTargetObjectFile::getExplicitSectionGlobal(const GlobalObject *GO, + SectionKind SK, const TargetMachine &TM) const { + // Set execute-only access for the explicit section + if (genExecuteOnly && SK.isText()) + SK = SectionKind::getExecuteOnly(); + + return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, SK, TM); +} + +MCSection * +ARMElfTargetObjectFile::SelectSectionForGlobal(const GlobalObject *GO, + SectionKind SK, const TargetMachine &TM) const { + // Place the global in the execute-only text section + if (genExecuteOnly && SK.isText()) + SK = SectionKind::getExecuteOnly(); + + return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, SK, TM); +} |