From c68dda815e64fb2fb463318d1eaa304e22199d50 Mon Sep 17 00:00:00 2001 From: Preston Gurd Date: Thu, 12 Apr 2012 20:13:57 +0000 Subject: This patch improves the MCJIT runtime dynamic loader by adding new handling of zero-initialized sections, virtual sections and common symbols and preventing the loading of sections which are not required for execution such as debug information. Patch by Andy Kaylor! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@154610 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Object/COFF.h | 4 ++++ include/llvm/Object/ELF.h | 50 ++++++++++++++++++++++++++++++++++++++++ include/llvm/Object/MachO.h | 4 ++++ include/llvm/Object/ObjectFile.h | 28 ++++++++++++++++++++++ 4 files changed, 86 insertions(+) (limited to 'include/llvm/Object') diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 91971bb01b..68b5ca1bc7 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -126,6 +126,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index cb013b9414..455a67b49f 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -33,6 +33,15 @@ namespace llvm { namespace object { +// Subclasses of ELFObjectFile may need this for template instantiation +inline std::pair +getElfArchType(MemoryBuffer *Object) { + if (Object->getBufferSize() < ELF::EI_NIDENT) + return std::make_pair((uint8_t)ELF::ELFCLASSNONE,(uint8_t)ELF::ELFDATANONE); + return std::make_pair( (uint8_t)Object->getBufferStart()[ELF::EI_CLASS] + , (uint8_t)Object->getBufferStart()[ELF::EI_DATA]); +} + // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. template struct ELFDataTypeTypedefHelperCommon { @@ -540,6 +549,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; @@ -1092,6 +1105,43 @@ error_code ELFObjectFile return object_error::success; } +template +error_code ELFObjectFile + ::isSectionRequiredForExecution(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + if (sec->sh_flags & ELF::SHF_ALLOC) + Result = true; + else + Result = false; + return object_error::success; +} + +template +error_code ELFObjectFile + ::isSectionVirtual(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + if (sec->sh_type == ELF::SHT_NOBITS) + Result = true; + else + Result = false; + return object_error::success; +} + +template +error_code ELFObjectFile::isSectionZeroInit(DataRefImpl Sec, + bool &Result) const { + const Elf_Shdr *sec = reinterpret_cast(Sec.p); + // For ELF, all zero-init sections are virtual (that is, they occupy no space + // in the object image) and vice versa. + if (sec->sh_flags & ELF::SHT_NOBITS) + Result = true; + else + Result = false; + return object_error::success; +} + template error_code ELFObjectFile ::sectionContainsSymbol(DataRefImpl Sec, diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1e409b2856..0b73f94831 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -72,6 +72,10 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const; + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const; virtual error_code sectionContainsSymbol(DataRefImpl DRI, DataRefImpl S, bool &Result) const; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const; diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index d8cda81533..4dd7fb5813 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -158,11 +158,16 @@ public: error_code isText(bool &Result) const; error_code isData(bool &Result) const; error_code isBSS(bool &Result) const; + error_code isRequiredForExecution(bool &Result) const; + error_code isVirtual(bool &Result) const; + error_code isZeroInit(bool &Result) const; error_code containsSymbol(SymbolRef S, bool &Result) const; relocation_iterator begin_relocations() const; relocation_iterator end_relocations() const; + + DataRefImpl getRawDataRefImpl() const; }; typedef content_iterator section_iterator; @@ -217,6 +222,9 @@ public: /// Get symbol flags (bitwise OR of SymbolRef::Flags) error_code getFlags(uint32_t &Result) const; + /// @brief Return true for common symbols such as uninitialized globals + error_code isCommon(bool &Result) const; + /// @brief Get section this symbol is defined in reference to. Result is /// end_sections() if it is undefined or is an absolute symbol. error_code getSection(section_iterator &Result) const; @@ -299,6 +307,11 @@ protected: virtual error_code isSectionText(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionData(DataRefImpl Sec, bool &Res) const = 0; virtual error_code isSectionBSS(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionRequiredForExecution(DataRefImpl Sec, + bool &Res) const = 0; + // A section is 'virtual' if its contents aren't present in the object image. + virtual error_code isSectionVirtual(DataRefImpl Sec, bool &Res) const = 0; + virtual error_code isSectionZeroInit(DataRefImpl Sec, bool &Res) const = 0; virtual error_code sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb, bool &Result) const = 0; virtual relocation_iterator getSectionRelBegin(DataRefImpl Sec) const = 0; @@ -481,6 +494,18 @@ inline error_code SectionRef::isBSS(bool &Result) const { return OwningObject->isSectionBSS(SectionPimpl, Result); } +inline error_code SectionRef::isRequiredForExecution(bool &Result) const { + return OwningObject->isSectionRequiredForExecution(SectionPimpl, Result); +} + +inline error_code SectionRef::isVirtual(bool &Result) const { + return OwningObject->isSectionVirtual(SectionPimpl, Result); +} + +inline error_code SectionRef::isZeroInit(bool &Result) const { + return OwningObject->isSectionZeroInit(SectionPimpl, Result); +} + inline error_code SectionRef::containsSymbol(SymbolRef S, bool &Result) const { return OwningObject->sectionContainsSymbol(SectionPimpl, S.SymbolPimpl, Result); @@ -494,6 +519,9 @@ inline relocation_iterator SectionRef::end_relocations() const { return OwningObject->getSectionRelEnd(SectionPimpl); } +inline DataRefImpl SectionRef::getRawDataRefImpl() const { + return SectionPimpl; +} /// RelocationRef inline RelocationRef::RelocationRef(DataRefImpl RelocationP, -- cgit v1.2.3