diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/MC/ELFObjectWriter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCELFObjectTargetWriter.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 6 | ||||
-rw-r--r-- | llvm/lib/MC/MCSection.cpp | 3 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/ARMTargetObjectFile.cpp | 14 | ||||
-rw-r--r-- | llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp | 18 |
6 files changed, 45 insertions, 2 deletions
diff --git a/llvm/lib/MC/ELFObjectWriter.cpp b/llvm/lib/MC/ELFObjectWriter.cpp index 358c036f2a7..5b8b013ad08 100644 --- a/llvm/lib/MC/ELFObjectWriter.cpp +++ b/llvm/lib/MC/ELFObjectWriter.cpp @@ -29,6 +29,7 @@ #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCFixupKindInfo.h" #include "llvm/MC/MCFragment.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCSection.h" #include "llvm/MC/MCSectionELF.h" @@ -1107,6 +1108,8 @@ uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) { SectionIndexMap[RelSection] = addToSectionTable(RelSection); Relocations.push_back(RelSection); } + + OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section); } MCSectionELF *CGProfileSection = nullptr; diff --git a/llvm/lib/MC/MCELFObjectTargetWriter.cpp b/llvm/lib/MC/MCELFObjectTargetWriter.cpp index 483ee94c0db..ff53dd7299c 100644 --- a/llvm/lib/MC/MCELFObjectTargetWriter.cpp +++ b/llvm/lib/MC/MCELFObjectTargetWriter.cpp @@ -26,3 +26,6 @@ void MCELFObjectTargetWriter::sortRelocs(const MCAssembler &Asm, std::vector<ELFRelocationEntry> &Relocs) { } + +void MCELFObjectTargetWriter::addTargetSectionFlags(MCContext &Ctx, + MCSectionELF &Sec) {} diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 019b9348a4e..8c88db009bd 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -496,6 +496,12 @@ void MCObjectStreamer::EmitBytes(StringRef Data) { MCDataFragment *DF = getOrCreateDataFragment(); flushPendingLabels(DF, DF->getContents().size()); DF->getContents().append(Data.begin(), Data.end()); + + // EmitBytes might not cover all possible ways we emit data (or could be used + // to emit executable code in some cases), but is the best method we have + // right now for checking this. + MCSection *Sec = getCurrentSectionOnly(); + Sec->setHasData(true); } void MCObjectStreamer::EmitValueToAlignment(unsigned ByteAlignment, diff --git a/llvm/lib/MC/MCSection.cpp b/llvm/lib/MC/MCSection.cpp index 97bc65387dd..d4f11d10136 100644 --- a/llvm/lib/MC/MCSection.cpp +++ b/llvm/lib/MC/MCSection.cpp @@ -23,7 +23,8 @@ using namespace llvm; MCSection::MCSection(SectionVariant V, SectionKind K, MCSymbol *Begin) : Begin(Begin), BundleGroupBeforeFirstInst(false), HasInstructions(false), - IsRegistered(false), DummyFragment(this), Variant(V), Kind(K) {} + HasData(false), IsRegistered(false), DummyFragment(this), Variant(V), + Kind(K) {} MCSymbol *MCSection::getEndSymbol(MCContext &Ctx) { if (!End) diff --git a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp index d0620761ea9..9c13359cba7 100644 --- a/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp +++ b/llvm/lib/Target/ARM/ARMTargetObjectFile.cpp @@ -32,7 +32,8 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, const TargetMachine &TM) { const ARMBaseTargetMachine &ARM_TM = static_cast<const ARMBaseTargetMachine &>(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 +41,17 @@ void ARMElfTargetObjectFile::Initialize(MCContext &Ctx, 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( diff --git a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp index 7d04c73fb3f..b8ba7584911 100644 --- a/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp +++ b/llvm/lib/Target/ARM/MCTargetDesc/ARMELFObjectWriter.cpp @@ -14,6 +14,7 @@ #include "llvm/MC/MCELFObjectWriter.h" #include "llvm/MC/MCExpr.h" #include "llvm/MC/MCFixup.h" +#include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCObjectWriter.h" #include "llvm/MC/MCValue.h" #include "llvm/Support/ErrorHandling.h" @@ -40,6 +41,8 @@ namespace { bool needsRelocateWithSymbol(const MCSymbol &Sym, unsigned Type) const override; + + void addTargetSectionFlags(MCContext &Ctx, MCSectionELF &Sec) override; }; } // end anonymous namespace @@ -236,6 +239,21 @@ unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, } } +void ARMELFObjectWriter::addTargetSectionFlags(MCContext &Ctx, + MCSectionELF &Sec) { + // 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. + MCSectionELF *TextSection = + static_cast<MCSectionELF *>(Ctx.getObjectFileInfo()->getTextSection()); + if (Sec.getKind().isExecuteOnly() && !TextSection->hasInstructions() && + !TextSection->hasData()) { + TextSection->setFlags(TextSection->getFlags() | ELF::SHF_ARM_PURECODE); + } +} + std::unique_ptr<MCObjectTargetWriter> llvm::createARMELFObjectWriter(uint8_t OSABI) { return llvm::make_unique<ARMELFObjectWriter>(OSABI); |