diff options
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/ArchiveWriter.h | 51 | ||||
-rw-r--r-- | include/llvm/Object/COFF.h | 10 | ||||
-rw-r--r-- | include/llvm/Object/ELF.h | 103 | ||||
-rw-r--r-- | include/llvm/Object/ELFObjectFile.h | 148 | ||||
-rw-r--r-- | include/llvm/Object/ELFTypes.h | 206 | ||||
-rw-r--r-- | include/llvm/Object/Error.h | 7 | ||||
-rw-r--r-- | include/llvm/Object/MachO.h | 38 | ||||
-rw-r--r-- | include/llvm/Object/ObjectFile.h | 33 | ||||
-rw-r--r-- | include/llvm/Object/RelocVisitor.h | 31 |
9 files changed, 308 insertions, 319 deletions
diff --git a/include/llvm/Object/ArchiveWriter.h b/include/llvm/Object/ArchiveWriter.h new file mode 100644 index 0000000000000..1616e46d3e6fb --- /dev/null +++ b/include/llvm/Object/ArchiveWriter.h @@ -0,0 +1,51 @@ +//===- ArchiveWriter.h - ar archive file format writer ----------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Declares the writeArchive function for writing an archive file. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_ARCHIVEWRITER_H +#define LLVM_OBJECT_ARCHIVEWRITER_H + +#include "llvm/ADT/StringRef.h" +#include "llvm/Object/Archive.h" +#include "llvm/Support/FileSystem.h" + +namespace llvm { + +class NewArchiveIterator { + bool IsNewMember; + StringRef Name; + + object::Archive::child_iterator OldI; + + StringRef NewFilename; + +public: + NewArchiveIterator(object::Archive::child_iterator I, StringRef Name); + NewArchiveIterator(StringRef I, StringRef Name); + NewArchiveIterator(); + bool isNewMember() const; + StringRef getName() const; + + object::Archive::child_iterator getOld() const; + + StringRef getNew() const; + llvm::ErrorOr<int> getFD(sys::fs::file_status &NewStatus) const; + const sys::fs::file_status &getStatus() const; +}; + +std::pair<StringRef, std::error_code> +writeArchive(StringRef ArcName, std::vector<NewArchiveIterator> &NewMembers, + bool WriteSymtab); + +} + +#endif diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index ccac02036adc7..564eb7a7a9c3c 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -613,7 +613,7 @@ protected: StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; @@ -647,10 +647,6 @@ protected: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; - public: COFFObjectFile(MemoryBufferRef Object, std::error_code &EC); basic_symbol_iterator symbol_begin_impl() const override; @@ -699,7 +695,7 @@ public: return object_error::parse_failed; Res = reinterpret_cast<coff_symbol_type *>(getSymbolTable()) + Index; - return object_error::success; + return std::error_code(); } ErrorOr<COFFSymbolRef> getSymbol(uint32_t index) const { if (SymbolTable16) { @@ -722,7 +718,7 @@ public: if (std::error_code EC = s.getError()) return EC; Res = reinterpret_cast<const T *>(s->getRawPtr()); - return object_error::success; + return std::error_code(); } std::error_code getSymbolName(COFFSymbolRef Symbol, StringRef &Res) const; diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index ddabf59f309e3..e87737dcce7a6 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -318,7 +318,7 @@ public: std::pair<const Elf_Shdr *, const Elf_Sym *> getRelocationSymbol(const Elf_Shdr *RelSec, const RelT *Rel) const; - ELFFile(StringRef Object, std::error_code &ec); + ELFFile(StringRef Object, std::error_code &EC); bool isMipsELF64() const { return Header->e_machine == ELF::EM_MIPS && @@ -423,12 +423,10 @@ public: StringRef getLoadName() const; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFFile<ELFType<support::little, 2, false> > ELF32LEFile; -typedef ELFFile<ELFType<support::little, 2, true> > ELF64LEFile; -typedef ELFFile<ELFType<support::big, 2, false> > ELF32BEFile; -typedef ELFFile<ELFType<support::big, 2, true> > ELF64BEFile; +typedef ELFFile<ELFType<support::little, false>> ELF32LEFile; +typedef ELFFile<ELFType<support::little, true>> ELF64LEFile; +typedef ELFFile<ELFType<support::big, false>> ELF32BEFile; +typedef ELFFile<ELFType<support::big, true>> ELF64BEFile; // Iterate through the version definitions, and place each Elf_Verdef // in the VersionMap according to its index. @@ -622,7 +620,7 @@ typename ELFFile<ELFT>::uintX_t ELFFile<ELFT>::getStringTableIndex() const { } template <class ELFT> -ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) +ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &EC) : Buf(Object), SectionHeaderTable(nullptr), dot_shstrtab_sec(nullptr), dot_strtab_sec(nullptr), dot_symtab_sec(nullptr), SymbolTableSectionHeaderIndex(nullptr), dot_gnu_version_sec(nullptr), @@ -630,9 +628,11 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) dt_soname(nullptr) { const uint64_t FileSize = Buf.size(); - if (sizeof(Elf_Ehdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("File too short!"); + if (sizeof(Elf_Ehdr) > FileSize) { + // File too short! + EC = object_error::parse_failed; + return; + } Header = reinterpret_cast<const Elf_Ehdr *>(base()); @@ -641,40 +641,50 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) const uint64_t SectionTableOffset = Header->e_shoff; - if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section header table goes past end of file!"); + if (SectionTableOffset + sizeof(Elf_Shdr) > FileSize) { + // Section header table goes past end of file! + EC = object_error::parse_failed; + return; + } // The getNumSections() call below depends on SectionHeaderTable being set. SectionHeaderTable = reinterpret_cast<const Elf_Shdr *>(base() + SectionTableOffset); const uint64_t SectionTableSize = getNumSections() * Header->e_shentsize; - if (SectionTableOffset + SectionTableSize > FileSize) - // FIXME: Proper error handling. - report_fatal_error("Section table goes past end of file!"); + if (SectionTableOffset + SectionTableSize > FileSize) { + // Section table goes past end of file! + EC = object_error::parse_failed; + return; + } // Scan sections for special sections. 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!"); + if (SymbolTableSectionHeaderIndex) { + // More than one .symtab_shndx! + EC = object_error::parse_failed; + return; + } SymbolTableSectionHeaderIndex = &Sec; break; case ELF::SHT_SYMTAB: - if (dot_symtab_sec) - // FIXME: Proper error handling. - report_fatal_error("More than one .symtab!"); + if (dot_symtab_sec) { + // More than one .symtab! + EC = object_error::parse_failed; + return; + } 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!"); + if (DynSymRegion.Addr) { + // More than one .dynsym! + EC = object_error::parse_failed; + return; + } DynSymRegion.Addr = base() + Sec.sh_offset; DynSymRegion.Size = Sec.sh_size; DynSymRegion.EntSize = Sec.sh_entsize; @@ -685,29 +695,37 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) break; } case ELF::SHT_DYNAMIC: - if (DynamicRegion.Addr) - // FIXME: Proper error handling. - report_fatal_error("More than one .dynamic!"); + if (DynamicRegion.Addr) { + // More than one .dynamic! + EC = object_error::parse_failed; + return; + } 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 != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version section!"); + if (dot_gnu_version_sec != nullptr) { + // More than one .gnu.version section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_sec = &Sec; break; case ELF::SHT_GNU_verdef: - if (dot_gnu_version_d_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_d section!"); + if (dot_gnu_version_d_sec != nullptr) { + // More than one .gnu.version_d section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_d_sec = &Sec; break; case ELF::SHT_GNU_verneed: - if (dot_gnu_version_r_sec != nullptr) - // FIXME: Proper error handling. - report_fatal_error("More than one .gnu.version_r section!"); + if (dot_gnu_version_r_sec != nullptr) { + // More than one .gnu.version_r section! + EC = object_error::parse_failed; + return; + } dot_gnu_version_r_sec = &Sec; break; } @@ -744,7 +762,7 @@ ELFFile<ELFT>::ELFFile(StringRef Object, std::error_code &ec) } } - ec = std::error_code(); + EC = std::error_code(); } // Get the symbol table index in the symtab section given a symbol @@ -898,11 +916,8 @@ ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(Elf_Sym_Iter Sym) const { template <class ELFT> ErrorOr<StringRef> ELFFile<ELFT>::getSymbolName(const Elf_Shdr *Section, const Elf_Sym *Symb) const { - if (Symb->st_name == 0) { - const Elf_Shdr *ContainingSec = getSection(Symb); - if (ContainingSec) - return getSectionName(ContainingSec); - } + if (Symb->st_name == 0) + return StringRef(""); const Elf_Shdr *StrTab = getSection(Section->sh_link); if (Symb->st_name >= StrTab->sh_size) diff --git a/include/llvm/Object/ELFObjectFile.h b/include/llvm/Object/ELFObjectFile.h index 9bd4c3241118d..78d77be5be8d6 100644 --- a/include/llvm/Object/ELFObjectFile.h +++ b/include/llvm/Object/ELFObjectFile.h @@ -79,9 +79,8 @@ protected: StringRef &Res) const override; std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; std::error_code getSymbolOther(DataRefImpl Symb, uint8_t &Res) const override; std::error_code getSymbolType(DataRefImpl Symb, @@ -119,9 +118,6 @@ protected: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; uint64_t getROffset(DataRefImpl Rel) const; StringRef getRelocationTypeName(uint32_t Type) const; @@ -227,7 +223,7 @@ public: std::error_code getPlatformFlags(unsigned &Result) const override { Result = EF.getHeader()->e_flags; - return object_error::success; + return std::error_code(); } const ELFFile<ELFT> *getELFFile() const { return &EF; } @@ -244,12 +240,10 @@ public: bool isRelocatableObject() const override; }; -// Use an alignment of 2 for the typedefs since that is the worst case for -// ELF files in archives. -typedef ELFObjectFile<ELFType<support::little, 2, false> > ELF32LEObjectFile; -typedef ELFObjectFile<ELFType<support::little, 2, true> > ELF64LEObjectFile; -typedef ELFObjectFile<ELFType<support::big, 2, false> > ELF32BEObjectFile; -typedef ELFObjectFile<ELFType<support::big, 2, true> > ELF64BEObjectFile; +typedef ELFObjectFile<ELFType<support::little, false>> ELF32LEObjectFile; +typedef ELFObjectFile<ELFType<support::little, true>> ELF64LEObjectFile; +typedef ELFObjectFile<ELFType<support::big, false>> ELF32BEObjectFile; +typedef ELFObjectFile<ELFType<support::big, true>> ELF64BEObjectFile; template <class ELFT> void ELFObjectFile<ELFT>::moveSymbolNext(DataRefImpl &Symb) const { @@ -263,7 +257,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolName(DataRefImpl Symb, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -277,7 +271,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolVersion(SymbolRef SymRef, if (!Ver) return Ver.getError(); Version = *Ver; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -300,10 +294,10 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, case ELF::SHN_COMMON: case ELF::SHN_UNDEF: Result = UnknownAddressOrSize; - return object_error::success; + return std::error_code(); case ELF::SHN_ABS: Result = ESym->st_value; - return object_error::success; + return std::error_code(); default: break; } @@ -322,32 +316,27 @@ std::error_code ELFObjectFile<ELFT>::getSymbolAddress(DataRefImpl Symb, Result += Section->sh_addr; } - return object_error::success; + return std::error_code(); } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const { +uint32_t ELFObjectFile<ELFT>::getSymbolAlignment(DataRefImpl Symb) const { Elf_Sym_Iter Sym = toELFSymIter(Symb); if (Sym->st_shndx == ELF::SHN_COMMON) - Res = Sym->st_value; - else - Res = 0; - return object_error::success; + return Sym->st_value; + return 0; } template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb, - uint64_t &Result) const { - Result = toELFSymIter(Symb)->st_size; - return object_error::success; +uint64_t ELFObjectFile<ELFT>::getSymbolSize(DataRefImpl Symb) const { + return toELFSymIter(Symb)->st_size; } template <class ELFT> std::error_code ELFObjectFile<ELFT>::getSymbolOther(DataRefImpl Symb, uint8_t &Result) const { Result = toELFSymIter(Symb)->st_other; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -378,7 +367,7 @@ ELFObjectFile<ELFT>::getSymbolType(DataRefImpl Symb, Result = SymbolRef::ST_Other; break; } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -435,7 +424,7 @@ std::error_code ELFObjectFile<ELFT>::getSymbolSection(DataRefImpl Symb, section_iterator &Res) const { Res = getSymbolSection(getSymbol(Symb)); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -450,7 +439,7 @@ std::error_code ELFObjectFile<ELFT>::getSectionName(DataRefImpl Sec, if (!Name) return Name.getError(); Result = *Name; - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -469,7 +458,7 @@ ELFObjectFile<ELFT>::getSectionContents(DataRefImpl Sec, StringRef &Result) const { Elf_Shdr_Iter EShdr = toELFShdrIter(Sec); Result = StringRef((const char *)base() + EShdr->sh_offset, EShdr->sh_size); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -624,7 +613,7 @@ ELFObjectFile<ELFT>::getRelocationAddress(DataRefImpl Rel, Result = ROffset; } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -634,7 +623,7 @@ ELFObjectFile<ELFT>::getRelocationOffset(DataRefImpl Rel, assert(EF.getHeader()->e_type == ELF::ET_REL && "Only relocatable object files have relocation offsets"); Result = getROffset(Rel); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -666,7 +655,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationType(DataRefImpl Rel, break; } } - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -693,7 +682,7 @@ std::error_code ELFObjectFile<ELFT>::getRelocationTypeName( } EF.getRelocationTypeName(type, Result); - return object_error::success; + return std::error_code(); } template <class ELFT> @@ -706,94 +695,13 @@ ELFObjectFile<ELFT>::getRelocationAddend(DataRefImpl Rel, report_fatal_error("Invalid section type in Rel!"); case ELF::SHT_REL: { Result = 0; - return object_error::success; + return std::error_code(); } case ELF::SHT_RELA: { Result = getRela(Rel)->r_addend; - return object_error::success; - } + return std::error_code(); } -} - -template <class ELFT> -std::error_code ELFObjectFile<ELFT>::getRelocationValueString( - DataRefImpl Rel, SmallVectorImpl<char> &Result) const { - const Elf_Shdr *sec = getRelSection(Rel); - uint8_t type; - StringRef res; - int64_t addend = 0; - uint16_t symbol_index = 0; - switch (sec->sh_type) { - default: - return object_error::parse_failed; - case ELF::SHT_REL: { - type = getRel(Rel)->getType(EF.isMips64EL()); - symbol_index = getRel(Rel)->getSymbol(EF.isMips64EL()); - // TODO: Read implicit addend from section data. - break; - } - case ELF::SHT_RELA: { - type = getRela(Rel)->getType(EF.isMips64EL()); - symbol_index = getRela(Rel)->getSymbol(EF.isMips64EL()); - addend = getRela(Rel)->r_addend; - break; - } - } - const Elf_Sym *symb = - EF.template getEntry<Elf_Sym>(sec->sh_link, symbol_index); - ErrorOr<StringRef> SymName = - EF.getSymbolName(EF.getSection(sec->sh_link), symb); - if (!SymName) - return SymName.getError(); - switch (EF.getHeader()->e_machine) { - case ELF::EM_X86_64: - switch (type) { - case ELF::R_X86_64_PC8: - case ELF::R_X86_64_PC16: - case ELF::R_X86_64_PC32: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend << "-P"; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - case ELF::R_X86_64_8: - case ELF::R_X86_64_16: - case ELF::R_X86_64_32: - case ELF::R_X86_64_32S: - case ELF::R_X86_64_64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - } break; - default: - res = "Unknown"; - } - break; - case ELF::EM_AARCH64: { - std::string fmtbuf; - raw_string_ostream fmt(fmtbuf); - fmt << *SymName; - if (addend != 0) - fmt << (addend < 0 ? "" : "+") << addend; - fmt.flush(); - Result.append(fmtbuf.begin(), fmtbuf.end()); - break; - } - case ELF::EM_386: - case ELF::EM_ARM: - case ELF::EM_HEXAGON: - case ELF::EM_MIPS: - res = *SymName; - break; - default: - res = "Unknown"; } - if (Result.empty()) - Result.append(res.begin(), res.end()); - return object_error::success; } template <class ELFT> diff --git a/include/llvm/Object/ELFTypes.h b/include/llvm/Object/ELFTypes.h index 287d3670678a6..3f323b5b82006 100644 --- a/include/llvm/Object/ELFTypes.h +++ b/include/llvm/Object/ELFTypes.h @@ -10,7 +10,6 @@ #ifndef LLVM_OBJECT_ELFTYPES_H #define LLVM_OBJECT_ELFTYPES_H -#include "llvm/Support/AlignOf.h" #include "llvm/Support/DataTypes.h" #include "llvm/Support/ELF.h" #include "llvm/Support/Endian.h" @@ -20,95 +19,74 @@ namespace object { using support::endianness; -template <endianness target_endianness, std::size_t max_alignment, - bool is64Bits> -struct ELFType { +template <endianness target_endianness, bool is64Bits> struct ELFType { static const endianness TargetEndianness = target_endianness; - static const std::size_t MaxAlignment = max_alignment; static const bool Is64Bits = is64Bits; }; -template <typename T, int max_align> struct MaximumAlignment { - enum { value = AlignOf<T>::Alignment > max_align ? max_align - : AlignOf<T>::Alignment - }; -}; +// Use an alignment of 2 for the typedefs since that is the worst case for +// ELF files in archives. // Templates to choose Elf_Addr and Elf_Off depending on is64Bits. -template <endianness target_endianness, std::size_t max_alignment> -struct ELFDataTypeTypedefHelperCommon { +template <endianness target_endianness> struct ELFDataTypeTypedefHelperCommon { typedef support::detail::packed_endian_specific_integral< - uint16_t, target_endianness, - MaximumAlignment<uint16_t, max_alignment>::value> Elf_Half; + uint16_t, target_endianness, 2> Elf_Half; typedef support::detail::packed_endian_specific_integral< - uint32_t, target_endianness, - MaximumAlignment<uint32_t, max_alignment>::value> Elf_Word; + uint32_t, target_endianness, 2> Elf_Word; typedef support::detail::packed_endian_specific_integral< - int32_t, target_endianness, - MaximumAlignment<int32_t, max_alignment>::value> Elf_Sword; + int32_t, target_endianness, 2> Elf_Sword; typedef support::detail::packed_endian_specific_integral< - uint64_t, target_endianness, - MaximumAlignment<uint64_t, max_alignment>::value> Elf_Xword; + uint64_t, target_endianness, 2> Elf_Xword; typedef support::detail::packed_endian_specific_integral< - int64_t, target_endianness, - MaximumAlignment<int64_t, max_alignment>::value> Elf_Sxword; + int64_t, target_endianness, 2> Elf_Sxword; }; template <class ELFT> struct ELFDataTypeTypedefHelper; /// ELF 32bit types. -template <endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, false> > - : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { +template <endianness TargetEndianness> +struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, false>> + : ELFDataTypeTypedefHelperCommon<TargetEndianness> { typedef uint32_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; /// ELF 64bit types. -template <endianness TargetEndianness, std::size_t MaxAlign> -struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, MaxAlign, true> > - : ELFDataTypeTypedefHelperCommon<TargetEndianness, MaxAlign> { +template <endianness TargetEndianness> +struct ELFDataTypeTypedefHelper<ELFType<TargetEndianness, true>> + : ELFDataTypeTypedefHelperCommon<TargetEndianness> { typedef uint64_t value_type; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Addr; + value_type, TargetEndianness, 2> Elf_Addr; typedef support::detail::packed_endian_specific_integral< - value_type, TargetEndianness, - MaximumAlignment<value_type, MaxAlign>::value> Elf_Off; + value_type, TargetEndianness, 2> Elf_Off; }; // I really don't like doing this, but the alternative is copypasta. -#define LLVM_ELF_IMPORT_TYPES(E, M, W) \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Addr \ - Elf_Addr; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Off \ - Elf_Off; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Half \ - Elf_Half; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Word \ - Elf_Word; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sword \ - Elf_Sword; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Xword \ - Elf_Xword; \ -typedef typename ELFDataTypeTypedefHelper<ELFType<E, M, W> >::Elf_Sxword \ - Elf_Sxword; +#define LLVM_ELF_IMPORT_TYPES(E, W) \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Addr Elf_Addr; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Off Elf_Off; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Half Elf_Half; \ + typedef typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Word Elf_Word; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sword Elf_Sword; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Xword Elf_Xword; \ + typedef \ + typename ELFDataTypeTypedefHelper<ELFType<E, W>>::Elf_Sxword Elf_Sxword; #define LLVM_ELF_IMPORT_TYPES_ELFT(ELFT) \ - LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::MaxAlignment, \ - ELFT::Is64Bits) + LLVM_ELF_IMPORT_TYPES(ELFT::TargetEndianness, ELFT::Is64Bits) // Section header. template <class ELFT> struct Elf_Shdr_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Shdr_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Word sh_flags; // Section flags (SHF_*) @@ -121,9 +99,9 @@ struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Word sh_entsize; // Size of records contained within the section }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Shdr_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Shdr_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word sh_name; // Section name (index into string table) Elf_Word sh_type; // Section type (SHT_*) Elf_Xword sh_flags; // Section flags (SHF_*) @@ -151,9 +129,9 @@ struct Elf_Shdr_Impl : Elf_Shdr_Base<ELFT> { template <class ELFT> struct Elf_Sym_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Sym_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word st_name; // Symbol name (index into string table) Elf_Addr st_value; // Value or address associated with the symbol Elf_Word st_size; // Size of the symbol @@ -162,9 +140,9 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Half st_shndx; // Which section (header table index) it's defined in }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Sym_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word st_name; // Symbol name (index into string table) unsigned char st_info; // Symbol's type and binding attributes unsigned char st_other; // Must be zero; reserved @@ -176,6 +154,7 @@ struct Elf_Sym_Base<ELFType<TargetEndianness, MaxAlign, true> > { template <class ELFT> struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { using Elf_Sym_Base<ELFT>::st_info; + using Elf_Sym_Base<ELFT>::st_shndx; using Elf_Sym_Base<ELFT>::st_other; // These accessors and mutators correspond to the ELF32_ST_BIND, @@ -198,6 +177,25 @@ struct Elf_Sym_Impl : Elf_Sym_Base<ELFT> { assert(v < 4 && "Invalid value for visibility"); st_other = (st_other & ~0x3) | v; } + + bool isAbsolute() const { return st_shndx == ELF::SHN_ABS; } + bool isCommon() const { + return getType() == ELF::STT_COMMON || st_shndx == ELF::SHN_COMMON; + } + bool isDefined() const { + return !isUndefined() && + !(st_shndx >= ELF::SHN_LORESERVE && st_shndx < ELF::SHN_ABS); + } + bool isProcessorSpecific() const { + return st_shndx >= ELF::SHN_LOPROC && st_shndx <= ELF::SHN_HIPROC; + } + bool isOSSpecific() const { + return st_shndx >= ELF::SHN_LOOS && st_shndx <= ELF::SHN_HIOS; + } + bool isReserved() const { + return st_shndx > ELF::SHN_HIOS && st_shndx < ELF::SHN_ABS; + } + bool isUndefined() const { return st_shndx == ELF::SHN_UNDEF; } }; /// Elf_Versym: This is the structure of entries in the SHT_GNU_versym section @@ -267,9 +265,9 @@ struct Elf_Vernaux_Impl { /// table section (.dynamic) look like. template <class ELFT> struct Elf_Dyn_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Dyn_Base<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Sword d_tag; union { Elf_Word d_val; @@ -277,9 +275,9 @@ struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, false> > { } d_un; }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Dyn_Base<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Dyn_Base<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Sxword d_tag; union { Elf_Xword d_val; @@ -300,9 +298,9 @@ struct Elf_Dyn_Impl : Elf_Dyn_Base<ELFT> { // Elf_Rel: Elf Relocation template <class ELFT, bool isRela> struct Elf_Rel_Base; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, false>, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply @@ -316,9 +314,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, false> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, true>, false> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply @@ -341,9 +339,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, false> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, false>, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Word r_info; // Symbol table index and type of relocation to apply Elf_Sword r_addend; // Compute value for relocatable field by adding this @@ -358,9 +356,9 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, false>, true> { } }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Rel_Base<ELFType<TargetEndianness, true>, true> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Addr r_offset; // Location (file byte offset, or program virtual addr) Elf_Xword r_info; // Symbol table index and type of relocation to apply Elf_Sxword r_addend; // Compute value for relocatable field by adding this. @@ -386,11 +384,10 @@ struct Elf_Rel_Base<ELFType<TargetEndianness, MaxAlign, true>, true> { template <class ELFT, bool isRela> struct Elf_Rel_Impl; -template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, - isRela> : Elf_Rel_Base< - ELFType<TargetEndianness, MaxAlign, true>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness, bool isRela> +struct Elf_Rel_Impl<ELFType<TargetEndianness, true>, isRela> + : Elf_Rel_Base<ELFType<TargetEndianness, true>, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) // These accessors and mutators correspond to the ELF64_R_SYM, ELF64_R_TYPE, // and ELF64_R_INFO macros defined in the ELF specification: @@ -411,11 +408,10 @@ struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, true>, } }; -template <endianness TargetEndianness, std::size_t MaxAlign, bool isRela> -struct Elf_Rel_Impl<ELFType<TargetEndianness, MaxAlign, false>, - isRela> : Elf_Rel_Base< - ELFType<TargetEndianness, MaxAlign, false>, isRela> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness, bool isRela> +struct Elf_Rel_Impl<ELFType<TargetEndianness, false>, isRela> + : Elf_Rel_Base<ELFType<TargetEndianness, false>, isRela> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) // These accessors and mutators correspond to the ELF32_R_SYM, ELF32_R_TYPE, // and ELF32_R_INFO macros defined in the ELF specification: @@ -463,9 +459,9 @@ struct Elf_Ehdr_Impl { template <class ELFT> struct Elf_Phdr_Impl; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <endianness TargetEndianness> +struct Elf_Phdr_Impl<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word p_type; // Type of segment Elf_Off p_offset; // FileOffset where segment is located, in bytes Elf_Addr p_vaddr; // Virtual Address of beginning of segment @@ -476,9 +472,9 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, false> > { Elf_Word p_align; // Segment alignment constraint }; -template <endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <endianness TargetEndianness> +struct Elf_Phdr_Impl<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word p_type; // Type of segment Elf_Word p_flags; // Segment flags Elf_Off p_offset; // FileOffset where segment is located, in bytes @@ -493,17 +489,17 @@ struct Elf_Phdr_Impl<ELFType<TargetEndianness, MaxAlign, true> > { template <class ELFT> struct Elf_Mips_RegInfo; -template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, false>> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, false) +template <llvm::support::endianness TargetEndianness> +struct Elf_Mips_RegInfo<ELFType<TargetEndianness, false>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, false) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers Elf_Addr ri_gp_value; // gp register value }; -template <llvm::support::endianness TargetEndianness, std::size_t MaxAlign> -struct Elf_Mips_RegInfo<ELFType<TargetEndianness, MaxAlign, true>> { - LLVM_ELF_IMPORT_TYPES(TargetEndianness, MaxAlign, true) +template <llvm::support::endianness TargetEndianness> +struct Elf_Mips_RegInfo<ELFType<TargetEndianness, true>> { + LLVM_ELF_IMPORT_TYPES(TargetEndianness, true) Elf_Word ri_gprmask; // bit-mask of used general registers Elf_Word ri_pad; // unused padding field Elf_Word ri_cprmask[4]; // bit-mask of used co-processor registers diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h index 90c2bd74b43c5..c9db1b80b9169 100644 --- a/include/llvm/Object/Error.h +++ b/include/llvm/Object/Error.h @@ -22,12 +22,15 @@ namespace object { const std::error_category &object_category(); enum class object_error { - success = 0, - arch_not_found, + // Error code 0 is absent. Use std::error_code() instead. + arch_not_found = 1, invalid_file_type, parse_failed, unexpected_eof, bitcode_section_not_found, + macho_small_load_command, + macho_load_segment_too_many_sections, + macho_load_segment_too_small, }; inline std::error_code make_error_code(object_error e) { diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 0a9b62c9055f7..b163534fd9df4 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -190,6 +190,8 @@ public: const char *Ptr; // Where in memory the load command is. MachO::load_command C; // The command itself. }; + typedef SmallVector<LoadCommandInfo, 4> LoadCommandList; + typedef LoadCommandList::const_iterator load_command_iterator; MachOObjectFile(MemoryBufferRef Object, bool IsLittleEndian, bool Is64Bits, std::error_code &EC); @@ -204,9 +206,8 @@ public: std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const override; - std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const override; - std::error_code getSymbolSize(DataRefImpl Symb, uint64_t &Res) const override; + uint32_t getSymbolAlignment(DataRefImpl Symb) const override; + uint64_t getSymbolSize(DataRefImpl Symb) const override; std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const override; uint32_t getSymbolFlags(DataRefImpl Symb) const override; @@ -241,11 +242,9 @@ public: std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const override; - std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const override; std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const override; + uint8_t getRelocationLength(DataRefImpl Rel) const; // MachO specific. std::error_code getLibraryShortNameByIndex(unsigned Index, StringRef &) const; @@ -273,10 +272,14 @@ public: dice_iterator begin_dices() const; dice_iterator end_dices() const; - + + load_command_iterator begin_load_commands() const; + load_command_iterator end_load_commands() const; + iterator_range<load_command_iterator> load_commands() const; + /// For use iterating over all exported symbols. iterator_range<export_iterator> exports() const; - + /// For use examining a trie not in a MachOObjectFile. static iterator_range<export_iterator> exports(ArrayRef<uint8_t> Trie); @@ -329,10 +332,6 @@ public: unsigned getAnyRelocationType(const MachO::any_relocation_info &RE) const; SectionRef getAnyRelocationSection(const MachO::any_relocation_info &RE) const; - // Walk load commands. - LoadCommandInfo getFirstLoadCommandInfo() const; - LoadCommandInfo getNextLoadCommandInfo(const LoadCommandInfo &L) const; - // MachO specific structures. MachO::section getSection(DataRefImpl DRI) const; MachO::section_64 getSection64(DataRefImpl DRI) const; @@ -386,8 +385,8 @@ public: MachO::any_relocation_info getRelocation(DataRefImpl Rel) const; MachO::data_in_code_entry getDice(DataRefImpl Rel) const; - MachO::mach_header getHeader() const; - MachO::mach_header_64 getHeader64() const; + const MachO::mach_header &getHeader() const; + const MachO::mach_header_64 &getHeader64() const; uint32_t getIndirectSymbolTableEntry(const MachO::dysymtab_command &DLC, unsigned Index) const; @@ -430,10 +429,15 @@ public: } private: + union { + MachO::mach_header_64 Header64; + MachO::mach_header Header; + }; typedef SmallVector<const char*, 1> SectionList; SectionList Sections; typedef SmallVector<const char*, 1> LibraryList; LibraryList Libraries; + LoadCommandList LoadCommands; typedef SmallVector<StringRef, 1> LibraryShortName; mutable LibraryShortName LibrariesShortNames; const char *SymtabLoadCmd; @@ -472,7 +476,7 @@ inline std::error_code DiceRef::getOffset(uint32_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.offset; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getLength(uint16_t &Result) const { @@ -480,7 +484,7 @@ inline std::error_code DiceRef::getLength(uint16_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.length; - return object_error::success; + return std::error_code(); } inline std::error_code DiceRef::getKind(uint16_t &Result) const { @@ -488,7 +492,7 @@ inline std::error_code DiceRef::getKind(uint16_t &Result) const { static_cast<const MachOObjectFile *>(OwningObject); MachO::data_in_code_entry Dice = MachOOF->getDice(DicePimpl); Result = Dice.kind; - return object_error::success; + return std::error_code(); } inline DataRefImpl DiceRef::getRawDataRefImpl() const { diff --git a/include/llvm/Object/ObjectFile.h b/include/llvm/Object/ObjectFile.h index 14cd082870b02..a1ae19ecdfed1 100644 --- a/include/llvm/Object/ObjectFile.h +++ b/include/llvm/Object/ObjectFile.h @@ -66,11 +66,6 @@ public: /// This is for display purposes only. std::error_code getTypeName(SmallVectorImpl<char> &Result) const; - /// @brief Get a string that represents the calculation of the value of this - /// relocation. - /// - /// This is for display purposes only. - std::error_code getValueString(SmallVectorImpl<char> &Result) const; DataRefImpl getRawDataRefImpl() const; const ObjectFile *getObjectFile() const; @@ -146,8 +141,8 @@ public: /// mapped). std::error_code getAddress(uint64_t &Result) const; /// @brief Get the alignment of this symbol as the actual value (not log 2). - std::error_code getAlignment(uint32_t &Result) const; - std::error_code getSize(uint64_t &Result) const; + uint32_t getAlignment() const; + uint64_t getSize() const; std::error_code getType(SymbolRef::Type &Result) const; std::error_code getOther(uint8_t &Result) const; @@ -206,10 +201,8 @@ protected: DataRefImpl Symb) const override; virtual std::error_code getSymbolAddress(DataRefImpl Symb, uint64_t &Res) const = 0; - virtual std::error_code getSymbolAlignment(DataRefImpl Symb, - uint32_t &Res) const; - virtual std::error_code getSymbolSize(DataRefImpl Symb, - uint64_t &Res) const = 0; + virtual uint32_t getSymbolAlignment(DataRefImpl Symb) const; + virtual uint64_t getSymbolSize(DataRefImpl Symb) const = 0; virtual std::error_code getSymbolType(DataRefImpl Symb, SymbolRef::Type &Res) const = 0; virtual std::error_code getSymbolSection(DataRefImpl Symb, @@ -254,13 +247,10 @@ protected: virtual std::error_code getRelocationTypeName(DataRefImpl Rel, SmallVectorImpl<char> &Result) const = 0; - virtual std::error_code - getRelocationValueString(DataRefImpl Rel, - SmallVectorImpl<char> &Result) const = 0; virtual std::error_code getRelocationHidden(DataRefImpl Rel, bool &Result) const { Result = false; - return object_error::success; + return std::error_code(); } public: @@ -334,12 +324,12 @@ inline std::error_code SymbolRef::getAddress(uint64_t &Result) const { return getObject()->getSymbolAddress(getRawDataRefImpl(), Result); } -inline std::error_code SymbolRef::getAlignment(uint32_t &Result) const { - return getObject()->getSymbolAlignment(getRawDataRefImpl(), Result); +inline uint32_t SymbolRef::getAlignment() const { + return getObject()->getSymbolAlignment(getRawDataRefImpl()); } -inline std::error_code SymbolRef::getSize(uint64_t &Result) const { - return getObject()->getSymbolSize(getRawDataRefImpl(), Result); +inline uint64_t SymbolRef::getSize() const { + return getObject()->getSymbolSize(getRawDataRefImpl()); } inline std::error_code SymbolRef::getSection(section_iterator &Result) const { @@ -482,11 +472,6 @@ RelocationRef::getTypeName(SmallVectorImpl<char> &Result) const { return OwningObject->getRelocationTypeName(RelocationPimpl, Result); } -inline std::error_code -RelocationRef::getValueString(SmallVectorImpl<char> &Result) const { - return OwningObject->getRelocationValueString(RelocationPimpl, Result); -} - inline std::error_code RelocationRef::getHidden(bool &Result) const { return OwningObject->getRelocationHidden(RelocationPimpl, Result); } diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 91eafd55ad766..02ffda5642d55 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -19,9 +19,11 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Object/COFF.h" #include "llvm/Object/ELFObjectFile.h" +#include "llvm/Object/MachO.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/Debug.h" #include "llvm/Support/ELF.h" +#include "llvm/Support/MachO.h" #include "llvm/Support/raw_ostream.h" namespace llvm { @@ -52,6 +54,8 @@ public: return visitELF(RelocType, R, Value); if (isa<COFFObjectFile>(ObjToVisit)) return visitCOFF(RelocType, R, Value); + if (isa<MachOObjectFile>(ObjToVisit)) + return visitMachO(RelocType, R, Value); HasError = true; return RelocToApply(); @@ -221,6 +225,20 @@ private: return RelocToApply(); } + RelocToApply visitMachO(uint32_t RelocType, RelocationRef R, uint64_t Value) { + switch (ObjToVisit.getArch()) { + default: break; + case Triple::x86_64: + switch (RelocType) { + default: break; + case MachO::X86_64_RELOC_UNSIGNED: + return visitMACHO_X86_64_UNSIGNED(R, Value); + } + } + HasError = true; + return RelocToApply(); + } + int64_t getELFAddend32LE(RelocationRef R) { const ELF32LEObjectFile *Obj = cast<ELF32LEObjectFile>(R.getObjectFile()); DataRefImpl DRI = R.getRawDataRefImpl(); @@ -252,6 +270,12 @@ private: Obj->getRelocationAddend(DRI, Addend); return Addend; } + + uint8_t getLengthMachO64(RelocationRef R) { + const MachOObjectFile *Obj = cast<MachOObjectFile>(R.getObjectFile()); + return Obj->getRelocationLength(R.getRawDataRefImpl()); + } + /// Operations /// 386-ELF @@ -413,6 +437,13 @@ private: RelocToApply visitCOFF_AMD64_ADDR64(RelocationRef R, uint64_t Value) { return RelocToApply(Value, /*Width=*/8); } + + // X86_64 MachO + RelocToApply visitMACHO_X86_64_UNSIGNED(RelocationRef R, uint64_t Value) { + uint8_t Length = getLengthMachO64(R); + Length = 1<<Length; + return RelocToApply(Value, Length); + } }; } |