diff options
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/Archive.h | 8 | ||||
-rw-r--r-- | include/llvm/Object/Binary.h | 3 | ||||
-rw-r--r-- | include/llvm/Object/COFF.h | 9 | ||||
-rw-r--r-- | include/llvm/Object/COFFYAML.h | 9 | ||||
-rw-r--r-- | include/llvm/Object/ELF.h | 112 | ||||
-rw-r--r-- | include/llvm/Object/ELFObjectFile.h | 25 | ||||
-rw-r--r-- | include/llvm/Object/ELFYAML.h | 47 | ||||
-rw-r--r-- | include/llvm/Object/MachO.h | 6 | ||||
-rw-r--r-- | include/llvm/Object/MachOUniversal.h | 7 | ||||
-rw-r--r-- | include/llvm/Object/ObjectFile.h | 55 | ||||
-rw-r--r-- | include/llvm/Object/StringTableBuilder.h | 59 | ||||
-rw-r--r-- | include/llvm/Object/SymbolicFile.h | 5 | ||||
-rw-r--r-- | include/llvm/Object/YAML.h | 1 |
13 files changed, 212 insertions, 134 deletions
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index 4fae76f..652b659 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -89,21 +89,17 @@ public: return StringRef(Data.data() + StartOfFile, getSize()); } - error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result, - bool FullPath = false) const; error_code getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result, bool FullPath = false) const; - error_code getAsBinary(OwningPtr<Binary> &Result, - LLVMContext *Context = 0) const; error_code getAsBinary(std::unique_ptr<Binary> &Result, - LLVMContext *Context = 0) const; + LLVMContext *Context = nullptr) const; }; class child_iterator { Child child; public: - child_iterator() : child(Child(0, 0)) {} + child_iterator() : child(Child(nullptr, nullptr)) {} child_iterator(const Child &c) : child(c) {} const Child* operator->() const { return &child; diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index b10e40a..8ac84e7 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -128,7 +128,8 @@ public: /// @param Source The data to create the Binary from. Ownership is transferred /// to the Binary if successful. If an error is returned, /// Source is destroyed by createBinary before returning. -ErrorOr<Binary *> createBinary(MemoryBuffer *Source, LLVMContext *Context = 0); +ErrorOr<Binary *> createBinary(MemoryBuffer *Source, + LLVMContext *Context = nullptr); ErrorOr<Binary *> createBinary(StringRef Path); } diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 6e05c2d..bd9c677 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -287,6 +287,10 @@ struct coff_aux_weak_external { char Unused[10]; }; +struct coff_aux_file { + char FileName[18]; +}; + struct coff_aux_section_definition { support::ulittle32_t Length; support::ulittle16_t NumberOfRelocations; @@ -387,7 +391,6 @@ protected: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; - bool section_rel_empty(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; error_code getRelocationAddress(DataRefImpl Rel, @@ -461,7 +464,7 @@ public: // The iterator for the import directory table. class ImportDirectoryEntryRef { public: - ImportDirectoryEntryRef() : OwningObject(0) {} + ImportDirectoryEntryRef() : OwningObject(nullptr) {} ImportDirectoryEntryRef(const import_directory_table_entry *Table, uint32_t I, const COFFObjectFile *Owner) : ImportTable(Table), Index(I), OwningObject(Owner) {} @@ -485,7 +488,7 @@ private: // The iterator for the export directory table entry. class ExportDirectoryEntryRef { public: - ExportDirectoryEntryRef() : OwningObject(0) {} + ExportDirectoryEntryRef() : OwningObject(nullptr) {} ExportDirectoryEntryRef(const export_directory_table_entry *Table, uint32_t I, const COFFObjectFile *Owner) : ExportTable(Table), Index(I), OwningObject(Owner) {} diff --git a/include/llvm/Object/COFFYAML.h b/include/llvm/Object/COFFYAML.h index b5f9ccc..3f48e07 100644 --- a/include/llvm/Object/COFFYAML.h +++ b/include/llvm/Object/COFFYAML.h @@ -121,8 +121,13 @@ struct ScalarEnumerationTraits<COFF::SymbolComplexType> { }; template <> -struct ScalarEnumerationTraits<COFF::RelocationTypeX86> { - static void enumeration(IO &IO, COFF::RelocationTypeX86 &Value); +struct ScalarEnumerationTraits<COFF::RelocationTypeI386> { + static void enumeration(IO &IO, COFF::RelocationTypeI386 &Value); +}; + +template <> +struct ScalarEnumerationTraits<COFF::RelocationTypeAMD64> { + static void enumeration(IO &IO, COFF::RelocationTypeAMD64 &Value); }; template <> diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index 824e06e..ee97d4e 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -60,12 +60,12 @@ public: public: typedef ptrdiff_t difference_type; typedef EntT value_type; - typedef std::random_access_iterator_tag iterator_category; + typedef std::forward_iterator_tag iterator_category; typedef value_type &reference; typedef value_type *pointer; /// \brief Default construct iterator. - ELFEntityIterator() : EntitySize(0), Current(0) {} + ELFEntityIterator() : EntitySize(0), Current(nullptr) {} ELFEntityIterator(uintX_t EntSize, const char *Start) : EntitySize(EntSize), Current(Start) {} @@ -136,6 +136,7 @@ public: typedef ELFEntityIterator<const Elf_Rela> Elf_Rela_Iter; typedef ELFEntityIterator<const Elf_Rel> Elf_Rel_Iter; typedef ELFEntityIterator<const Elf_Shdr> Elf_Shdr_Iter; + typedef iterator_range<Elf_Shdr_Iter> Elf_Shdr_Range; /// \brief Archive files are 2 byte aligned, so we need this for /// PointerIntPair to work. @@ -249,7 +250,7 @@ private: /// \brief Represents a region described by entries in the .dynamic table. struct DynRegionInfo { - DynRegionInfo() : Addr(0), Size(0), EntSize(0) {} + DynRegionInfo() : Addr(nullptr), Size(0), EntSize(0) {} /// \brief Address in current address space. const void *Addr; /// \brief Size in bytes of the region. @@ -273,19 +274,19 @@ private: public: // If the integer is 0, this is an Elf_Verdef*. // If the integer is 1, this is an Elf_Vernaux*. - VersionMapEntry() : PointerIntPair<const void*, 1>(NULL, 0) { } + VersionMapEntry() : PointerIntPair<const void*, 1>(nullptr, 0) { } VersionMapEntry(const Elf_Verdef *verdef) : PointerIntPair<const void*, 1>(verdef, 0) { } VersionMapEntry(const Elf_Vernaux *vernaux) : PointerIntPair<const void*, 1>(vernaux, 1) { } - bool isNull() const { return getPointer() == NULL; } + bool isNull() const { return getPointer() == nullptr; } bool isVerdef() const { return !isNull() && getInt() == 0; } bool isVernaux() const { return !isNull() && getInt() == 1; } const Elf_Verdef *getVerdef() const { - return isVerdef() ? (const Elf_Verdef*)getPointer() : NULL; + return isVerdef() ? (const Elf_Verdef*)getPointer() : nullptr; } const Elf_Vernaux *getVernaux() const { - return isVernaux() ? (const Elf_Vernaux*)getPointer() : NULL; + return isVernaux() ? (const Elf_Vernaux*)getPointer() : nullptr; } }; mutable SmallVector<VersionMapEntry, 16> VersionMap; @@ -317,6 +318,11 @@ public: ELFFile(MemoryBuffer *Object, error_code &ec); + bool isMipsELF64() const { + return Header->e_machine == ELF::EM_MIPS && + Header->getFileClass() == ELF::ELFCLASS64; + } + bool isMips64EL() const { return Header->e_machine == ELF::EM_MIPS && Header->getFileClass() == ELF::ELFCLASS64 && @@ -325,6 +331,9 @@ public: Elf_Shdr_Iter begin_sections() const; Elf_Shdr_Iter end_sections() const; + Elf_Shdr_Range sections() const { + return make_range(begin_sections(), end_sections()); + } Elf_Sym_Iter begin_symbols() const; Elf_Sym_Iter end_symbols() const; @@ -338,7 +347,7 @@ public: if (DynSymRegion.Addr) return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr, true); - return Elf_Sym_Iter(0, 0, true); + return Elf_Sym_Iter(0, nullptr, true); } Elf_Sym_Iter end_dynamic_symbols() const { @@ -346,7 +355,7 @@ public: return Elf_Sym_Iter(DynSymRegion.EntSize, (const char *)DynSymRegion.Addr + DynSymRegion.Size, true); - return Elf_Sym_Iter(0, 0, true); + return Elf_Sym_Iter(0, nullptr, true); } Elf_Rela_Iter begin_rela(const Elf_Shdr *sec) const { @@ -478,7 +487,7 @@ void ELFFile<ELFT>::LoadVersionNeeds(const Elf_Shdr *sec) const { template <class ELFT> void ELFFile<ELFT>::LoadVersionMap() const { // If there is no dynamic symtab or version table, there is nothing to do. - if (DynSymRegion.Addr == NULL || dot_gnu_version_sec == NULL) + if (!DynSymRegion.Addr || !dot_gnu_version_sec) return; // Has the VersionMap already been loaded? @@ -510,7 +519,7 @@ ELFFile<ELFT>::getSection(const Elf_Sym *symb) const { if (symb->st_shndx == ELF::SHN_XINDEX) return getSection(ExtendedSymbolTable.lookup(symb)); if (symb->st_shndx >= ELF::SHN_LORESERVE) - return 0; + return nullptr; return getSection(symb->st_shndx); } @@ -537,10 +546,16 @@ StringRef ELFFile<ELFT>::getRelocationTypeName(uint32_t Type) const { template <class ELFT> void ELFFile<ELFT>::getRelocationTypeName(uint32_t Type, SmallVectorImpl<char> &Result) const { - if (!isMips64EL()) { + if (!isMipsELF64()) { StringRef Name = getRelocationTypeName(Type); Result.append(Name.begin(), Name.end()); } else { + // The Mips N64 ABI allows up to three operations to be specified per + // relocation record. Unfortunately there's no easy way to test for the + // presence of N64 ELFs as they have no special flag that identifies them + // as being N64. We can safely assume at the moment that all Mips + // ELFCLASS64 ELFs are N64. New Mips64 ABIs should provide enough + // information to disambiguate between old vs new ABIs. uint8_t Type1 = (Type >> 0) & 0xFF; uint8_t Type2 = (Type >> 8) & 0xFF; uint8_t Type3 = (Type >> 16) & 0xFF; @@ -565,7 +580,7 @@ std::pair<const typename ELFFile<ELFT>::Elf_Shdr *, const typename ELFFile<ELFT>::Elf_Sym *> ELFFile<ELFT>::getRelocationSymbol(const Elf_Shdr *Sec, const RelT *Rel) const { if (!Sec->sh_link) - return std::make_pair((const Elf_Shdr *)0, (const Elf_Sym *)0); + return std::make_pair(nullptr, nullptr); const Elf_Shdr *SymTable = getSection(Sec->sh_link); return std::make_pair( SymTable, getEntry<Elf_Sym>(SymTable, Rel->getSymbol(isMips64EL()))); @@ -604,15 +619,15 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { template <class ELFT> ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec) : Buf(Object), - SectionHeaderTable(0), - dot_shstrtab_sec(0), - dot_strtab_sec(0), - dot_symtab_sec(0), - SymbolTableSectionHeaderIndex(0), - dot_gnu_version_sec(0), - dot_gnu_version_r_sec(0), - dot_gnu_version_d_sec(0), - dt_soname(0) { + SectionHeaderTable(nullptr), + dot_shstrtab_sec(nullptr), + dot_strtab_sec(nullptr), + dot_symtab_sec(nullptr), + SymbolTableSectionHeaderIndex(nullptr), + dot_gnu_version_sec(nullptr), + dot_gnu_version_r_sec(nullptr), + dot_gnu_version_d_sec(nullptr), + dt_soname(nullptr) { const uint64_t FileSize = Buf->getBufferSize(); if (sizeof(Elf_Ehdr) > FileSize) @@ -641,30 +656,29 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec) // Scan sections for special sections. - for (Elf_Shdr_Iter SecI = begin_sections(), SecE = end_sections(); - SecI != SecE; ++SecI) { - switch (SecI->sh_type) { + for (const Elf_Shdr &Sec : sections()) { + switch (Sec.sh_type) { case ELF::SHT_SYMTAB_SHNDX: if (SymbolTableSectionHeaderIndex) // FIXME: Proper error handling. report_fatal_error("More than one .symtab_shndx!"); - SymbolTableSectionHeaderIndex = &*SecI; + SymbolTableSectionHeaderIndex = &Sec; break; case ELF::SHT_SYMTAB: if (dot_symtab_sec) // FIXME: Proper error handling. report_fatal_error("More than one .symtab!"); - dot_symtab_sec = &*SecI; - dot_strtab_sec = getSection(SecI->sh_link); + dot_symtab_sec = &Sec; + dot_strtab_sec = getSection(Sec.sh_link); break; case ELF::SHT_DYNSYM: { if (DynSymRegion.Addr) // FIXME: Proper error handling. report_fatal_error("More than one .dynsym!"); - DynSymRegion.Addr = base() + SecI->sh_offset; - DynSymRegion.Size = SecI->sh_size; - DynSymRegion.EntSize = SecI->sh_entsize; - const Elf_Shdr *DynStr = getSection(SecI->sh_link); + DynSymRegion.Addr = base() + Sec.sh_offset; + DynSymRegion.Size = Sec.sh_size; + DynSymRegion.EntSize = Sec.sh_entsize; + const Elf_Shdr *DynStr = getSection(Sec.sh_link); DynStrRegion.Addr = base() + DynStr->sh_offset; DynStrRegion.Size = DynStr->sh_size; DynStrRegion.EntSize = DynStr->sh_entsize; @@ -674,27 +688,27 @@ ELFFile<ELFT>::ELFFile(MemoryBuffer *Object, error_code &ec) if (DynamicRegion.Addr) // FIXME: Proper error handling. report_fatal_error("More than one .dynamic!"); - DynamicRegion.Addr = base() + SecI->sh_offset; - DynamicRegion.Size = SecI->sh_size; - DynamicRegion.EntSize = SecI->sh_entsize; + DynamicRegion.Addr = base() + Sec.sh_offset; + DynamicRegion.Size = Sec.sh_size; + DynamicRegion.EntSize = Sec.sh_entsize; break; case ELF::SHT_GNU_versym: - if (dot_gnu_version_sec != NULL) + if (dot_gnu_version_sec != nullptr) // FIXME: Proper error handling. report_fatal_error("More than one .gnu.version section!"); - dot_gnu_version_sec = &*SecI; + dot_gnu_version_sec = &Sec; break; case ELF::SHT_GNU_verdef: - if (dot_gnu_version_d_sec != NULL) + if (dot_gnu_version_d_sec != nullptr) // FIXME: Proper error handling. report_fatal_error("More than one .gnu.version_d section!"); - dot_gnu_version_d_sec = &*SecI; + dot_gnu_version_d_sec = &Sec; break; case ELF::SHT_GNU_verneed: - if (dot_gnu_version_r_sec != NULL) + if (dot_gnu_version_r_sec != nullptr) // FIXME: Proper error handling. report_fatal_error("More than one .gnu.version_r section!"); - dot_gnu_version_r_sec = &*SecI; + dot_gnu_version_r_sec = &Sec; break; } } @@ -761,7 +775,7 @@ typename ELFFile<ELFT>::Elf_Shdr_Iter ELFFile<ELFT>::end_sections() const { template <class ELFT> typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const { if (!dot_symtab_sec) - return Elf_Sym_Iter(0, 0, false); + return Elf_Sym_Iter(0, nullptr, false); return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, (const char *)base() + dot_symtab_sec->sh_offset, false); } @@ -769,7 +783,7 @@ typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::begin_symbols() const { template <class ELFT> typename ELFFile<ELFT>::Elf_Sym_Iter ELFFile<ELFT>::end_symbols() const { if (!dot_symtab_sec) - return Elf_Sym_Iter(0, 0, false); + return Elf_Sym_Iter(0, nullptr, false); return Elf_Sym_Iter(dot_symtab_sec->sh_entsize, (const char *)base() + dot_symtab_sec->sh_offset + dot_symtab_sec->sh_size, @@ -782,14 +796,14 @@ ELFFile<ELFT>::begin_dynamic_table() const { if (DynamicRegion.Addr) return Elf_Dyn_Iter(DynamicRegion.EntSize, (const char *)DynamicRegion.Addr); - return Elf_Dyn_Iter(0, 0); + return Elf_Dyn_Iter(0, nullptr); } template <class ELFT> typename ELFFile<ELFT>::Elf_Dyn_Iter ELFFile<ELFT>::end_dynamic_table(bool NULLEnd) const { if (!DynamicRegion.Addr) - return Elf_Dyn_Iter(0, 0); + return Elf_Dyn_Iter(0, nullptr); Elf_Dyn_Iter Ret(DynamicRegion.EntSize, (const char *)DynamicRegion.Addr + DynamicRegion.Size); @@ -842,7 +856,7 @@ template <class ELFT> const typename ELFFile<ELFT>::Elf_Shdr * ELFFile<ELFT>::getSection(uint32_t index) const { if (index == 0) - return 0; + return nullptr; if (!SectionHeaderTable || index >= getNumSections()) // FIXME: Proper error handling. report_fatal_error("Invalid section index!"); @@ -871,7 +885,7 @@ const char *ELFFile<ELFT>::getString(const Elf_Shdr *section, template <class ELFT> const char *ELFFile<ELFT>::getDynamicString(uintX_t Offset) const { if (!DynStrRegion.Addr || Offset >= DynStrRegion.Size) - return 0; + return nullptr; return (const char *)DynStrRegion.Addr + Offset; } @@ -913,7 +927,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, const Elf_Sym *symb, bool &IsDefault) const { // Handle non-dynamic symbols. - if (section != DynSymRegion.Addr && section != 0) { + if (section != DynSymRegion.Addr && section != nullptr) { // Non-dynamic symbols can have versions in their names // A name of the form 'foo@V1' indicates version 'V1', non-default. // A name of the form 'foo@@V2' indicates version 'V2', default version. @@ -937,7 +951,7 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolVersion(const Elf_Shdr *section, } // This is a dynamic symbol. Look in the GNU symbol version table. - if (dot_gnu_version_sec == NULL) { + if (!dot_gnu_version_sec) { // No version table. IsDefault = false; return StringRef(""); diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 2958067..302caba 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -89,7 +89,6 @@ protected: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; - bool section_rel_empty(DataRefImpl Sec) const override; section_iterator getRelocatedSection(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; @@ -256,8 +255,7 @@ error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, Result = ESym->st_value; // Clear the ARM/Thumb indicator flag. - if (EF.getHeader()->e_machine == ELF::EM_ARM && - ESym->getType() == ELF::STT_FUNC) + if (Header->e_machine == ELF::EM_ARM && ESym->getType() == ELF::STT_FUNC) Result &= ~1; if (Header->e_type == ELF::ET_REL) @@ -497,12 +495,6 @@ ELFObjectFile<ELFT>::section_rel_end(DataRefImpl Sec) const { } template <class ELFT> -bool ELFObjectFile<ELFT>::section_rel_empty(DataRefImpl Sec) const { - const Elf_Shdr *S = reinterpret_cast<const Elf_Shdr *>(Sec.p); - return S->sh_size == 0; -} - -template <class ELFT> section_iterator ELFObjectFile<ELFT>::getRelocatedSection(DataRefImpl Sec) const { if (EF.getHeader()->e_type != ELF::ET_REL) @@ -563,10 +555,17 @@ ELFObjectFile<ELFT>::getRelocationSymbol(DataRefImpl Rel) const { template <class ELFT> error_code ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, uint64_t &Result) const { - assert((EF.getHeader()->e_type == ELF::ET_EXEC || - EF.getHeader()->e_type == ELF::ET_DYN) && - "Only executable and shared objects files have relocation addresses"); - Result = getROffset(Rel); + uint64_t ROffset = getROffset(Rel); + const Elf_Ehdr *Header = EF.getHeader(); + + if (Header->e_type == ELF::ET_REL) { + const Elf_Shdr *RelocationSec = getRelSection(Rel); + const Elf_Shdr *RelocatedSec = EF.getSection(RelocationSec->sh_info); + Result = ROffset + RelocatedSec->sh_addr; + } else { + Result = ROffset; + } + return object_error::success; } diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index 1eba660..524e55b 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -40,6 +40,7 @@ LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) // Just use 64, since it can hold 32-bit values too. LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_EF) LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_REL) // Just use 64, since it can hold 32-bit values too. LLVM_YAML_STRONG_TYPEDEF(uint64_t, ELF_SHF) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_STT) @@ -68,17 +69,42 @@ struct LocalGlobalWeakSymbols { std::vector<Symbol> Weak; }; struct Section { + enum class SectionKind { RawContent, Relocation }; + SectionKind Kind; StringRef Name; ELF_SHT Type; ELF_SHF Flags; llvm::yaml::Hex64 Address; - object::yaml::BinaryRef Content; StringRef Link; + StringRef Info; llvm::yaml::Hex64 AddressAlign; + Section(SectionKind Kind) : Kind(Kind) {} + virtual ~Section(); +}; +struct RawContentSection : Section { + object::yaml::BinaryRef Content; + llvm::yaml::Hex64 Size; + RawContentSection() : Section(SectionKind::RawContent) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::RawContent; + } +}; +struct Relocation { + llvm::yaml::Hex64 Offset; + int64_t Addend; + ELF_REL Type; + StringRef Symbol; +}; +struct RelocationSection : Section { + std::vector<Relocation> Relocations; + RelocationSection() : Section(SectionKind::Relocation) {} + static bool classof(const Section *S) { + return S->Kind == SectionKind::Relocation; + } }; struct Object { FileHeader Header; - std::vector<Section> Sections; + std::vector<std::unique_ptr<Section>> Sections; // Although in reality the symbols reside in a section, it is a lot // cleaner and nicer if we read them from the YAML as a separate // top-level key, which automatically ensures that invariants like there @@ -89,8 +115,9 @@ struct Object { } // end namespace ELFYAML } // end namespace llvm -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section) +LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<llvm::ELFYAML::Section>) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Relocation) namespace llvm { namespace yaml { @@ -141,6 +168,11 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { }; template <> +struct ScalarEnumerationTraits<ELFYAML::ELF_REL> { + static void enumeration(IO &IO, ELFYAML::ELF_REL &Value); +}; + +template <> struct MappingTraits<ELFYAML::FileHeader> { static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); }; @@ -155,9 +187,14 @@ struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> { static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols); }; +template <> struct MappingTraits<ELFYAML::Relocation> { + static void mapping(IO &IO, ELFYAML::Relocation &Rel); +}; + template <> -struct MappingTraits<ELFYAML::Section> { - static void mapping(IO &IO, ELFYAML::Section &Section); +struct MappingTraits<std::unique_ptr<ELFYAML::Section>> { + static void mapping(IO &IO, std::unique_ptr<ELFYAML::Section> &Section); + static StringRef validate(IO &io, std::unique_ptr<ELFYAML::Section> &Section); }; template <> diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index f242611..710ad7e 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -31,7 +31,7 @@ class DiceRef { const ObjectFile *OwningObject; public: - DiceRef() : OwningObject(NULL) { } + DiceRef() : OwningObject(nullptr) { } DiceRef(DataRefImpl DiceP, const ObjectFile *Owner); @@ -88,7 +88,6 @@ public: bool &Result) const override; relocation_iterator section_rel_begin(DataRefImpl Sec) const override; relocation_iterator section_rel_end(DataRefImpl Sec) const override; - bool section_rel_empty(DataRefImpl Sec) const override; void moveRelocationNext(DataRefImpl &Rel) const override; error_code getRelocationAddress(DataRefImpl Rel, @@ -112,6 +111,9 @@ public: basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_end_impl() const override; + // MachO specific. + basic_symbol_iterator getSymbolByIndex(unsigned Index) const; + section_iterator section_begin() const override; section_iterator section_end() const override; diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h index 9b1afd2..d27c824 100644 --- a/include/llvm/Object/MachOUniversal.h +++ b/include/llvm/Object/MachOUniversal.h @@ -17,6 +17,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/Object/Binary.h" +#include "llvm/Object/Archive.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MachO.h" @@ -41,7 +42,7 @@ public: ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index); void clear() { - Parent = 0; + Parent = nullptr; Index = 0; } @@ -53,6 +54,8 @@ public: uint32_t getCPUType() const { return Header.cputype; } error_code getAsObjectFile(std::unique_ptr<ObjectFile> &Result) const; + + error_code getAsArchive(std::unique_ptr<Archive> &Result) const; }; class object_iterator { @@ -83,7 +86,7 @@ public: return ObjectForArch(this, 0); } object_iterator end_objects() const { - return ObjectForArch(0, 0); + return ObjectForArch(nullptr, 0); } uint32_t getNumberOfObjects() const { return NumberOfObjects; } diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 8298b63..10209b9 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -38,7 +38,7 @@ class RelocationRef { const ObjectFile *OwningObject; public: - RelocationRef() : OwningObject(NULL) { } + RelocationRef() : OwningObject(nullptr) { } RelocationRef(DataRefImpl RelocationP, const ObjectFile *Owner); @@ -82,7 +82,7 @@ class SectionRef { const ObjectFile *OwningObject; public: - SectionRef() : OwningObject(NULL) { } + SectionRef() : OwningObject(nullptr) { } SectionRef(DataRefImpl SectionP, const ObjectFile *Owner); @@ -113,11 +113,10 @@ public: relocation_iterator relocation_begin() const; relocation_iterator relocation_end() const; - typedef iterator_range<relocation_iterator> relocation_iterator_range; - relocation_iterator_range relocations() const { - return relocation_iterator_range(relocation_begin(), relocation_end()); + iterator_range<relocation_iterator> relocations() const { + return iterator_range<relocation_iterator>(relocation_begin(), + relocation_end()); } - bool relocation_empty() const; section_iterator getRelocatedSection() const; DataRefImpl getRawDataRefImpl() const; @@ -146,7 +145,6 @@ public: /// Returns the symbol virtual address (i.e. address at which it will be /// mapped). error_code getAddress(uint64_t &Result) const; - error_code getFileOffset(uint64_t &Result) const; /// @brief Get the alignment of this symbol as the actual value (not log 2). error_code getAlignment(uint32_t &Result) const; error_code getSize(uint64_t &Result) const; @@ -185,7 +183,7 @@ class LibraryRef { const ObjectFile *OwningObject; public: - LibraryRef() : OwningObject(NULL) { } + LibraryRef() : OwningObject(nullptr) { } LibraryRef(DataRefImpl LibraryP, const ObjectFile *Owner); @@ -256,7 +254,6 @@ protected: bool &Result) const = 0; virtual relocation_iterator section_rel_begin(DataRefImpl Sec) const = 0; virtual relocation_iterator section_rel_end(DataRefImpl Sec) const = 0; - virtual bool section_rel_empty(DataRefImpl Sec) const = 0; virtual section_iterator getRelocatedSection(DataRefImpl Sec) const; // Same as above for RelocationRef. @@ -350,42 +347,6 @@ inline error_code SymbolRef::getAddress(uint64_t &Result) const { return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); } -inline error_code SymbolRef::getFileOffset(uint64_t &Result) const { - uint64_t Address; - if (error_code EC = getAddress(Address)) - return EC; - if (Address == UnknownAddressOrSize) { - Result = UnknownAddressOrSize; - return object_error::success; - } - - const ObjectFile *Obj = getObject(); - section_iterator SecI(Obj->section_begin()); - if (error_code EC = getSection(SecI)) - return EC; - - if (SecI == Obj->section_end()) { - Result = UnknownAddressOrSize; - return object_error::success; - } - - uint64_t SectionAddress; - if (error_code EC = SecI->getAddress(SectionAddress)) - return EC; - - uint64_t OffsetInSection = Address - SectionAddress; - - StringRef SecContents; - if (error_code EC = SecI->getContents(SecContents)) - return EC; - - // FIXME: this is a hack. - uint64_t SectionOffset = (uint64_t)SecContents.data() - (uint64_t)Obj->base(); - - Result = SectionOffset + OffsetInSection; - return object_error::success; -} - inline error_code SymbolRef::getAlignment(uint32_t &Result) const { return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result); } @@ -491,10 +452,6 @@ inline relocation_iterator SectionRef::relocation_end() const { return OwningObject->section_rel_end(SectionPimpl); } -inline bool SectionRef::relocation_empty() const { - return OwningObject->section_rel_empty(SectionPimpl); -} - inline section_iterator SectionRef::getRelocatedSection() const { return OwningObject->getRelocatedSection(SectionPimpl); } diff --git a/include/llvm/Object/StringTableBuilder.h b/include/llvm/Object/StringTableBuilder.h new file mode 100644 index 0000000..c61e216 --- /dev/null +++ b/include/llvm/Object/StringTableBuilder.h @@ -0,0 +1,59 @@ +//===-- StringTableBuilder.h - String table building utility ------*- C++ -*-=// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_STRINGTABLE_BUILDER_H +#define LLVM_OBJECT_STRINGTABLE_BUILDER_H + +#include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include <cassert> + +namespace llvm { + +/// \brief Utility for building string tables with deduplicated suffixes. +class StringTableBuilder { + SmallString<256> StringTable; + StringMap<size_t> StringIndexMap; + +public: + /// \brief Add a string to the builder. Returns a StringRef to the internal + /// copy of s. Can only be used before the table is finalized. + StringRef add(StringRef s) { + assert(!isFinalized()); + return StringIndexMap.GetOrCreateValue(s, 0).getKey(); + } + + /// \brief Analyze the strings and build the final table. No more strings can + /// be added after this point. + void finalize(); + + /// \brief Retrieve the string table data. Can only be used after the table + /// is finalized. + StringRef data() { + assert(isFinalized()); + return StringTable; + } + + /// \brief Get the offest of a string in the string table. Can only be used + /// after the table is finalized. + size_t getOffset(StringRef s) { + assert(isFinalized()); + assert(StringIndexMap.count(s) && "String is not in table!"); + return StringIndexMap[s]; + } + +private: + bool isFinalized() { + return !StringTable.empty(); + } +}; + +} // end llvm namespace + +#endif diff --git a/include/llvm/Object/SymbolicFile.h b/include/llvm/Object/SymbolicFile.h index bead2c3..28400e1 100644 --- a/include/llvm/Object/SymbolicFile.h +++ b/include/llvm/Object/SymbolicFile.h @@ -90,7 +90,7 @@ public: // (e.g. section symbols) }; - BasicSymbolRef() : OwningObject(NULL) { } + BasicSymbolRef() : OwningObject(nullptr) { } BasicSymbolRef(DataRefImpl SymbolP, const SymbolicFile *Owner); bool operator==(const BasicSymbolRef &Other) const; @@ -147,7 +147,8 @@ public: LLVMContext *Context); static ErrorOr<SymbolicFile *> createSymbolicFile(MemoryBuffer *Object) { - return createSymbolicFile(Object, true, sys::fs::file_magic::unknown, 0); + return createSymbolicFile(Object, true, sys::fs::file_magic::unknown, + nullptr); } static ErrorOr<SymbolicFile *> createSymbolicFile(StringRef ObjectPath); diff --git a/include/llvm/Object/YAML.h b/include/llvm/Object/YAML.h index 89fe504..1792e8b 100644 --- a/include/llvm/Object/YAML.h +++ b/include/llvm/Object/YAML.h @@ -108,6 +108,7 @@ template <> struct ScalarTraits<object::yaml::BinaryRef> { static void output(const object::yaml::BinaryRef &, void *, llvm::raw_ostream &); static StringRef input(StringRef, void *, object::yaml::BinaryRef &); + static bool mustQuote(StringRef S) { return needsQuotes(S); } }; } |