From c0e334099ca404d254d8a80600795496501862ff Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 10 Dec 2014 20:46:55 +0000 Subject: [PATCH] Move three methods only used by MCJIT to MCJIT. These methods are only used by MCJIT and are very specific to it. In fact, they are also fairly specific to the fact that we have a dynamic linker of relocatable objects. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223964 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/COFF.h | 3 -- include/llvm/Object/ELFObjectFile.h | 37 +++++++++-------- include/llvm/Object/MachO.h | 4 +- include/llvm/Object/ObjectFile.h | 23 +++-------- .../RuntimeDyld/RuntimeDyld.cpp | 40 ++++++++++++++++--- lib/Object/COFFObjectFile.cpp | 28 ------------- lib/Object/MachOObjectFile.cpp | 27 +++---------- 7 files changed, 64 insertions(+), 98 deletions(-) diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 3368d68b8d1..520c1a5dbc6 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -593,9 +593,6 @@ protected: bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool isSectionZeroInit(DataRefImpl Sec) const override; - bool isSectionReadOnlyData(DataRefImpl Sec) const override; - bool isSectionRequiredForExecution(DataRefImpl Sec) const override; bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index c3e3da7074b..c2d6438f45b 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -48,6 +48,9 @@ public: virtual std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, bool &IsDefault) const = 0; + virtual uint64_t getSectionFlags(SectionRef Sec) const = 0; + virtual uint32_t getSectionType(SectionRef Sec) const = 0; + static inline bool classof(const Binary *v) { return v->isELF(); } }; @@ -97,10 +100,7 @@ protected: bool isSectionText(DataRefImpl Sec) const override; bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; - bool isSectionRequiredForExecution(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool isSectionZeroInit(DataRefImpl Sec) const override; - bool isSectionReadOnlyData(DataRefImpl Sec) const override; bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; @@ -201,6 +201,9 @@ public: std::error_code getSymbolVersion(SymbolRef Symb, StringRef &Version, bool &IsDefault) const override; + uint64_t getSectionFlags(SectionRef Sec) const override; + uint32_t getSectionType(SectionRef Sec) const override; + uint8_t getBytesInAddress() const override; StringRef getFileFormatName() const override; unsigned getArch() const override; @@ -261,6 +264,18 @@ std::error_code ELFObjectFile::getSymbolVersion(SymbolRef SymRef, return object_error::success; } +template +uint64_t ELFObjectFile::getSectionFlags(SectionRef Sec) const { + DataRefImpl DRI = Sec.getRawDataRefImpl(); + return toELFShdrIter(DRI)->sh_flags; +} + +template +uint32_t ELFObjectFile::getSectionType(SectionRef Sec) const { + DataRefImpl DRI = Sec.getRawDataRefImpl(); + return toELFShdrIter(DRI)->sh_type; +} + template std::error_code ELFObjectFile::getSymbolAddress(DataRefImpl Symb, uint64_t &Result) const { @@ -451,27 +466,11 @@ bool ELFObjectFile::isSectionBSS(DataRefImpl Sec) const { EShdr->sh_type == ELF::SHT_NOBITS; } -template -bool ELFObjectFile::isSectionRequiredForExecution(DataRefImpl Sec) const { - return toELFShdrIter(Sec)->sh_flags & ELF::SHF_ALLOC; -} - template bool ELFObjectFile::isSectionVirtual(DataRefImpl Sec) const { return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; } -template -bool ELFObjectFile::isSectionZeroInit(DataRefImpl Sec) const { - return toELFShdrIter(Sec)->sh_type == ELF::SHT_NOBITS; -} - -template -bool ELFObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const { - Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); - return !(EShdr->sh_flags & (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); -} - template bool ELFObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const { diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 94a4d0442f3..b3fbf46d0b1 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -200,6 +200,7 @@ public: // MachO specific. std::error_code getIndirectName(DataRefImpl Symb, StringRef &Res) const; + unsigned getSectionType(SectionRef Sec) const; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; @@ -223,10 +224,7 @@ public: bool isSectionText(DataRefImpl Sec) const override; bool isSectionData(DataRefImpl Sec) const override; bool isSectionBSS(DataRefImpl Sec) const override; - bool isSectionRequiredForExecution(DataRefImpl Sec) const override; bool isSectionVirtual(DataRefImpl Sec) const override; - bool isSectionZeroInit(DataRefImpl Sec) const override; - bool isSectionReadOnlyData(DataRefImpl Sec) const override; bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 68b873a8246..6aa985d7e67 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -105,10 +105,7 @@ public: bool isText() const; bool isData() const; bool isBSS() const; - bool isRequiredForExecution() const; bool isVirtual() const; - bool isZeroInit() const; - bool isReadOnlyData() const; bool containsSymbol(SymbolRef S) const; @@ -121,6 +118,7 @@ public: section_iterator getRelocatedSection() const; DataRefImpl getRawDataRefImpl() const; + const ObjectFile *getObject() const; }; /// SymbolRef - This is a value type class that represents a single symbol in @@ -233,11 +231,8 @@ protected: virtual bool isSectionText(DataRefImpl Sec) const = 0; virtual bool isSectionData(DataRefImpl Sec) const = 0; virtual bool isSectionBSS(DataRefImpl Sec) const = 0; - virtual bool isSectionRequiredForExecution(DataRefImpl Sec) const = 0; // A section is 'virtual' if its contents aren't present in the object image. virtual bool isSectionVirtual(DataRefImpl Sec) const = 0; - virtual bool isSectionZeroInit(DataRefImpl Sec) const = 0; - virtual bool isSectionReadOnlyData(DataRefImpl Sec) const = 0; virtual bool sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const = 0; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; @@ -417,22 +412,10 @@ inline bool SectionRef::isBSS() const { return OwningObject->isSectionBSS(SectionPimpl); } -inline bool SectionRef::isRequiredForExecution() const { - return OwningObject->isSectionRequiredForExecution(SectionPimpl); -} - inline bool SectionRef::isVirtual() const { return OwningObject->isSectionVirtual(SectionPimpl); } -inline bool SectionRef::isZeroInit() const { - return OwningObject->isSectionZeroInit(SectionPimpl); -} - -inline bool SectionRef::isReadOnlyData() const { - return OwningObject->isSectionReadOnlyData(SectionPimpl); -} - inline bool SectionRef::containsSymbol(SymbolRef S) const { return OwningObject->sectionContainsSymbol(SectionPimpl, S.getRawDataRefImpl()); @@ -454,6 +437,10 @@ inline DataRefImpl SectionRef::getRawDataRefImpl() const { return SectionPimpl; } +inline const ObjectFile *SectionRef::getObject() const { + return OwningObject; +} + /// RelocationRef inline RelocationRef::RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner) diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 00ac8695306..304014edb24 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -16,7 +16,7 @@ #include "RuntimeDyldELF.h" #include "RuntimeDyldImpl.h" #include "RuntimeDyldMachO.h" -#include "llvm/Object/ELF.h" +#include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MutexGuard.h" @@ -263,6 +263,34 @@ computeAllocationSizeForSections(std::vector &SectionSizes, return TotalSize; } +static bool isRequiredForExecution(const SectionRef &Section) { + const ObjectFile *Obj = Section.getObject(); + if (auto *ELFObj = dyn_cast(Obj)) + return ELFObj->getSectionFlags(Section) & ELF::SHF_ALLOC; + assert(isa(Obj)); + return true; + } + +static bool isReadOnlyData(const SectionRef &Section) { + const ObjectFile *Obj = Section.getObject(); + if (auto *ELFObj = dyn_cast(Obj)) + return !(ELFObj->getSectionFlags(Section) & + (ELF::SHF_WRITE | ELF::SHF_EXECINSTR)); + assert(isa(Obj)); + return false; +} + +static bool isZeroInit(const SectionRef &Section) { + const ObjectFile *Obj = Section.getObject(); + if (auto *ELFObj = dyn_cast(Obj)) + return ELFObj->getSectionType(Section) == ELF::SHT_NOBITS; + + auto *MachO = cast(Obj); + unsigned SectionType = MachO->getSectionType(Section); + return SectionType == MachO::S_ZEROFILL || + SectionType == MachO::S_GB_ZEROFILL; +} + // Compute an upper bound of the memory size that is required to load all // sections void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, @@ -281,7 +309,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, SI != SE; ++SI) { const SectionRef &Section = *SI; - bool IsRequired = Section.isRequiredForExecution(); + bool IsRequired = isRequiredForExecution(Section); // Consider only the sections that are required to be loaded for execution if (IsRequired) { @@ -289,7 +317,7 @@ void RuntimeDyldImpl::computeTotalAllocSize(const ObjectFile &Obj, uint64_t DataSize = Section.getSize(); uint64_t Alignment64 = Section.getAlignment(); bool IsCode = Section.isText(); - bool IsReadOnly = Section.isReadOnlyData(); + bool IsReadOnly = isReadOnlyData(Section); Check(Section.getName(Name)); unsigned Alignment = (unsigned)Alignment64 & 0xffffffffL; @@ -462,10 +490,10 @@ unsigned RuntimeDyldImpl::emitSection(const ObjectFile &Obj, unsigned PaddingSize = 0; unsigned StubBufSize = 0; StringRef Name; - bool IsRequired = Section.isRequiredForExecution(); + bool IsRequired = isRequiredForExecution(Section); bool IsVirtual = Section.isVirtual(); - bool IsZeroInit = Section.isZeroInit(); - bool IsReadOnly = Section.isReadOnlyData(); + bool IsZeroInit = isZeroInit(Section); + bool IsReadOnly = isReadOnlyData(Section); uint64_t DataSize = Section.getSize(); Check(Section.getName(Name)); diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 92f920da1fa..cde6fdc5f88 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -362,39 +362,11 @@ bool COFFObjectFile::isSectionBSS(DataRefImpl Ref) const { return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; } -bool COFFObjectFile::isSectionRequiredForExecution(DataRefImpl Ref) const { - // Sections marked 'Info', 'Remove', or 'Discardable' aren't required for - // execution. - const coff_section *Sec = toSec(Ref); - return !(Sec->Characteristics & - (COFF::IMAGE_SCN_LNK_INFO | COFF::IMAGE_SCN_LNK_REMOVE | - COFF::IMAGE_SCN_MEM_DISCARDABLE)); -} - bool COFFObjectFile::isSectionVirtual(DataRefImpl Ref) const { const coff_section *Sec = toSec(Ref); return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; } -bool COFFObjectFile::isSectionZeroInit(DataRefImpl Ref) const { - const coff_section *Sec = toSec(Ref); - return Sec->Characteristics & COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA; -} - -bool COFFObjectFile::isSectionReadOnlyData(DataRefImpl Ref) const { - const coff_section *Sec = toSec(Ref); - // Check if it's any sort of data section. - if (!(Sec->Characteristics & (COFF::IMAGE_SCN_CNT_UNINITIALIZED_DATA | - COFF::IMAGE_SCN_CNT_INITIALIZED_DATA))) - return false; - // If it's writable or executable or contains code, it isn't read-only data. - if (Sec->Characteristics & - (COFF::IMAGE_SCN_CNT_CODE | COFF::IMAGE_SCN_MEM_EXECUTE | - COFF::IMAGE_SCN_MEM_WRITE)) - return false; - return true; -} - bool COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef, DataRefImpl SymbRef) const { const coff_section *Sec = toSec(SecRef); diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index c6fb0874842..0c5b180941e 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -316,6 +316,12 @@ std::error_code MachOObjectFile::getSymbolName(DataRefImpl Symb, return object_error::success; } +unsigned MachOObjectFile::getSectionType(SectionRef Sec) const { + DataRefImpl DRI = Sec.getRawDataRefImpl(); + uint32_t Flags = getSectionFlags(this, DRI); + return Flags & MachO::SECTION_TYPE; +} + // getIndirectName() returns the name of the alias'ed symbol who's string table // index is in the n_value field. std::error_code MachOObjectFile::getIndirectName(DataRefImpl Symb, @@ -575,32 +581,11 @@ bool MachOObjectFile::isSectionBSS(DataRefImpl Sec) const { SectionType == MachO::S_GB_ZEROFILL); } -bool MachOObjectFile::isSectionRequiredForExecution(DataRefImpl Sect) const { - // FIXME: Unimplemented. - return true; -} - bool MachOObjectFile::isSectionVirtual(DataRefImpl Sec) const { // FIXME: Unimplemented. return false; } -bool MachOObjectFile::isSectionZeroInit(DataRefImpl Sec) const { - uint32_t Flags = getSectionFlags(this, Sec); - unsigned SectionType = Flags & MachO::SECTION_TYPE; - return SectionType == MachO::S_ZEROFILL || - SectionType == MachO::S_GB_ZEROFILL; -} - -bool MachOObjectFile::isSectionReadOnlyData(DataRefImpl Sec) const { - // Consider using the code from isSectionText to look for __const sections. - // Alternately, emit S_ATTR_PURE_INSTRUCTIONS and/or S_ATTR_SOME_INSTRUCTIONS - // to use section attributes to distinguish code from data. - - // FIXME: Unimplemented. - return false; -} - bool MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb) const { SymbolRef::Type ST; -- 2.34.1