diff options
author | Stephen Hines <srhines@google.com> | 2013-08-07 15:07:10 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2013-08-07 15:07:10 -0700 |
commit | fab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch) | |
tree | 268ebfd1963fd98ba412e76819afdf95a7d4267b /include/llvm/Object | |
parent | 8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff) | |
parent | 10251753b6897adcd22cc981c0cc42f348c109de (diff) | |
download | external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.zip external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.gz external_llvm-fab2daa4a1127ecb217abe2b07c1769122b6fee1.tar.bz2 |
Merge commit '10251753b6897adcd22cc981c0cc42f348c109de' into merge-20130807
Conflicts:
lib/Archive/ArchiveReader.cpp
lib/Support/Unix/PathV2.inc
Change-Id: I29d8c1e321a4a380b6013f00bac6a8e4b593cc4e
Diffstat (limited to 'include/llvm/Object')
-rw-r--r-- | include/llvm/Object/Archive.h | 109 | ||||
-rw-r--r-- | include/llvm/Object/Binary.h | 5 | ||||
-rw-r--r-- | include/llvm/Object/COFF.h | 15 | ||||
-rw-r--r-- | include/llvm/Object/ELF.h | 97 | ||||
-rw-r--r-- | include/llvm/Object/ELFYAML.h | 71 | ||||
-rw-r--r-- | include/llvm/Object/Error.h | 25 | ||||
-rw-r--r-- | include/llvm/Object/MachO.h | 3 | ||||
-rw-r--r-- | include/llvm/Object/MachOFormat.h | 18 | ||||
-rw-r--r-- | include/llvm/Object/MachOUniversal.h | 102 | ||||
-rw-r--r-- | include/llvm/Object/RelocVisitor.h | 6 |
10 files changed, 359 insertions, 92 deletions
diff --git a/include/llvm/Object/Archive.h b/include/llvm/Object/Archive.h index e2478f6..1cba519 100644 --- a/include/llvm/Object/Archive.h +++ b/include/llvm/Object/Archive.h @@ -14,12 +14,10 @@ #ifndef LLVM_OBJECT_ARCHIVE_H #define LLVM_OBJECT_ARCHIVE_H -#include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/Twine.h" #include "llvm/Object/Binary.h" -#include "llvm/Support/DataTypes.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" namespace llvm { @@ -33,33 +31,17 @@ struct ArchiveMemberHeader { char Size[10]; ///< Size of data, not including header or padding. char Terminator[2]; - ///! Get the name without looking up long names. - llvm::StringRef getName() const { - char EndCond; - if (Name[0] == '/' || Name[0] == '#') - EndCond = ' '; - else - EndCond = '/'; - llvm::StringRef::size_type end = - llvm::StringRef(Name, sizeof(Name)).find(EndCond); - if (end == llvm::StringRef::npos) - end = sizeof(Name); - assert(end <= sizeof(Name) && end > 0); - // Don't include the EndCond if there is one. - return llvm::StringRef(Name, end); - } + /// Get the name without looking up long names. + llvm::StringRef getName() const; - uint64_t getSize() const { - uint64_t ret; - if (llvm::StringRef(Size, sizeof(Size)).rtrim(" ").getAsInteger(10, ret)) - llvm_unreachable("Size is not an integer."); - return ret; - } -}; + /// Members are not larger than 4GB. + uint32_t getSize() const; -static const ArchiveMemberHeader *ToHeader(const char *base) { - return reinterpret_cast<const ArchiveMemberHeader *>(base); -} + sys::fs::perms getAccessMode() const; + sys::TimeValue getLastModified() const; + unsigned getUID() const; + unsigned getGID() const; +}; class Archive : public Binary { virtual void anchor(); @@ -71,53 +53,34 @@ public: /// \brief Offset from Data to the start of the file. uint16_t StartOfFile; - public: - Child(const Archive *p, StringRef d) : Parent(p), Data(d) { - if (!p || d.empty()) - return; - // Setup StartOfFile and PaddingBytes. - StartOfFile = sizeof(ArchiveMemberHeader); - // Don't include attached name. - StringRef Name = ToHeader(Data.data())->getName(); - if (Name.startswith("#1/")) { - uint64_t NameSize; - if (Name.substr(3).rtrim(" ").getAsInteger(10, NameSize)) - llvm_unreachable("Long name length is not an integer"); - StartOfFile += NameSize; - } + const ArchiveMemberHeader *getHeader() const { + return reinterpret_cast<const ArchiveMemberHeader *>(Data.data()); } + public: + Child(const Archive *Parent, const char *Start); + bool operator ==(const Child &other) const { - return (Parent == other.Parent) && (Data.begin() == other.Data.begin()); + assert(Parent == other.Parent); + return Data.begin() == other.Data.begin(); } bool operator <(const Child &other) const { return Data.begin() < other.Data.begin(); } - Child getNext() const { - size_t SpaceToSkip = Data.size(); - // If it's odd, add 1 to make it even. - if (SpaceToSkip & 1) - ++SpaceToSkip; - - const char *NextLoc = Data.data() + SpaceToSkip; - - // Check to see if this is past the end of the archive. - if (NextLoc >= Parent->Data->getBufferEnd()) - return Child(Parent, StringRef(0, 0)); - - size_t NextSize = - sizeof(ArchiveMemberHeader) + ToHeader(NextLoc)->getSize(); - - return Child(Parent, StringRef(NextLoc, NextSize)); - } + Child getNext() const; error_code getName(StringRef &Result) const; - int getLastModified() const; - int getUID() const; - int getGID() const; - int getAccessMode() const; + StringRef getRawName() const { return getHeader()->getName(); } + sys::TimeValue getLastModified() const { + return getHeader()->getLastModified(); + } + unsigned getUID() const { return getHeader()->getUID(); } + unsigned getGID() const { return getHeader()->getGID(); } + sys::fs::perms getAccessMode() const { + return getHeader()->getAccessMode(); + } /// \return the size of the archive member without the header or padding. uint64_t getSize() const { return Data.size() - StartOfFile; } @@ -126,16 +89,7 @@ public: } error_code getMemoryBuffer(OwningPtr<MemoryBuffer> &Result, - bool FullPath = false) const { - StringRef Name; - if (error_code ec = getName(Name)) - return ec; - SmallString<128> Path; - Result.reset(MemoryBuffer::getMemBuffer( - getBuffer(), FullPath ? (Twine(Parent->getFileName()) + "(" + Name + - ")").toStringRef(Path) : Name, false)); - return error_code::success(); - } + bool FullPath = false) const; error_code getAsBinary(OwningPtr<Binary> &Result) const; }; @@ -143,7 +97,7 @@ public: class child_iterator { Child child; public: - child_iterator() : child(Child(0, StringRef())) {} + child_iterator() : child(Child(0, 0)) {} child_iterator(const Child &c) : child(c) {} const Child* operator->() const { return &child; @@ -220,7 +174,7 @@ public: return Format; } - child_iterator begin_children(bool skip_internal = true) const; + child_iterator begin_children(bool SkipInternal = true) const; child_iterator end_children() const; symbol_iterator begin_symbols() const; @@ -234,9 +188,12 @@ public: // check if a symbol is in the archive child_iterator findSym(StringRef name) const; + bool hasSymbolTable() const; + private: child_iterator SymbolTable; child_iterator StringTable; + child_iterator FirstRegular; Kind Format; }; diff --git a/include/llvm/Object/Binary.h b/include/llvm/Object/Binary.h index 78fcf6f..a3f5625 100644 --- a/include/llvm/Object/Binary.h +++ b/include/llvm/Object/Binary.h @@ -38,6 +38,7 @@ protected: enum { ID_Archive, + ID_MachOUniversalBinary, // Object and children. ID_StartObjects, ID_COFF, @@ -87,6 +88,10 @@ public: return TypeID == ID_Archive; } + bool isMachOUniversalBinary() const { + return TypeID == ID_MachOUniversalBinary; + } + bool isELF() const { return TypeID >= ID_ELF32L && TypeID <= ID_ELF64B; } diff --git a/include/llvm/Object/COFF.h b/include/llvm/Object/COFF.h index 209aa76..2190067 100644 --- a/include/llvm/Object/COFF.h +++ b/include/llvm/Object/COFF.h @@ -129,6 +129,14 @@ struct data_directory { support::ulittle32_t Size; }; +struct import_directory_table_entry { + support::ulittle32_t ImportLookupTableRVA; + support::ulittle32_t TimeDateStamp; + support::ulittle32_t ForwarderChain; + support::ulittle32_t NameRVA; + support::ulittle32_t ImportAddressTableRVA; +}; + struct coff_symbol { struct StringTableOffset { support::ulittle32_t Zeroes; @@ -188,7 +196,9 @@ struct coff_aux_section_definition { class COFFObjectFile : public ObjectFile { private: - const coff_file_header *Header; + const coff_file_header *COFFHeader; + const pe32_header *PE32Header; + const data_directory *DataDirectory; const coff_section *SectionTable; const coff_symbol *SymbolTable; const char *StringTable; @@ -272,6 +282,9 @@ public: virtual StringRef getLoadName() const; error_code getHeader(const coff_file_header *&Res) const; + error_code getCOFFHeader(const coff_file_header *&Res) const; + error_code getPE32Header(const pe32_header *&Res) const; + error_code getDataDirectory(uint32_t index, const data_directory *&Res) const; error_code getSection(int32_t index, const coff_section *&Res) const; error_code getSymbol(uint32_t index, const coff_symbol *&Res) const; template <typename T> diff --git a/include/llvm/Object/ELF.h b/include/llvm/Object/ELF.h index eb8e22e..2063809 100644 --- a/include/llvm/Object/ELF.h +++ b/include/llvm/Object/ELF.h @@ -1234,7 +1234,8 @@ error_code ELFObjectFile<ELFT>::getSymbolFlags(DataRefImpl Symb, Result |= SymbolRef::SF_Absolute; if (symb->getType() == ELF::STT_FILE || - symb->getType() == ELF::STT_SECTION) + symb->getType() == ELF::STT_SECTION || + Symb == begin_symbols()->getRawDataRefImpl()) Result |= SymbolRef::SF_FormatSpecific; if (getSymbolTableIndex(symb) == ELF::SHN_UNDEF) @@ -1667,6 +1668,8 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_CALL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_UNUSED1); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_UNUSED2); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT5); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_SHIFT6); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_64); @@ -2030,9 +2033,45 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRTAKEN); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL14_BRNTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT16_HA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPMOD32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_DTPREL32); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSGD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TLSLD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_GOT_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLSGD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_TLSLD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC_REL16_HA); default: break; } break; @@ -2052,32 +2091,74 @@ StringRef ELFObjectFile<ELFT>::getRelocationTypeName(uint32_t Type) const { LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14_BRTAKEN); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL14_BRNTAKEN); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_HA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL32); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHERA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_HIGHESTA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL64); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_HA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_ADDR16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT16_LO_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TOC16_LO_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPMOD64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL64); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSGD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TLSLD16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_DS); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HI); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_TPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_GOT_DTPREL16_HA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHERA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TPREL16_HIGHESTA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_LO_DS); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHER); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHERA); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHEST); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_DTPREL16_HIGHESTA); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSGD); LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_TLSLD); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_LO); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HI); + LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_PPC64_REL16_HA); default: break; } break; @@ -2272,7 +2353,16 @@ error_code ELFObjectFile<ELFT>::getRelocationValueString( res = "Unknown"; } break; - case ELF::EM_AARCH64: + 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_ARM: case ELF::EM_HEXAGON: res = symname; @@ -2708,7 +2798,8 @@ unsigned ELFObjectFile<ELFT>::getArch() const { return (ELFT::TargetEndianness == support::little) ? Triple::mipsel : Triple::mips; case ELF::EM_PPC64: - return Triple::ppc64; + return (ELFT::TargetEndianness == support::little) ? + Triple::ppc64le : Triple::ppc64; case ELF::EM_S390: return Triple::systemz; default: diff --git a/include/llvm/Object/ELFYAML.h b/include/llvm/Object/ELFYAML.h index 029a8ab..fca965f 100644 --- a/include/llvm/Object/ELFYAML.h +++ b/include/llvm/Object/ELFYAML.h @@ -36,23 +36,59 @@ LLVM_YAML_STRONG_TYPEDEF(uint16_t, ELF_ET) LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_EM) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFCLASS) LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFDATA) +LLVM_YAML_STRONG_TYPEDEF(uint8_t, ELF_ELFOSABI) +LLVM_YAML_STRONG_TYPEDEF(uint32_t, ELF_SHT) +// 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) // For now, hardcode 64 bits everywhere that 32 or 64 would be needed // since 64-bit can hold 32-bit values too. struct FileHeader { ELF_ELFCLASS Class; ELF_ELFDATA Data; + ELF_ELFOSABI OSABI; ELF_ET Type; ELF_EM Machine; llvm::yaml::Hex64 Entry; }; +struct Symbol { + StringRef Name; + ELF_STT Type; + StringRef Section; + llvm::yaml::Hex64 Value; + llvm::yaml::Hex64 Size; +}; +struct LocalGlobalWeakSymbols { + std::vector<Symbol> Local; + std::vector<Symbol> Global; + std::vector<Symbol> Weak; +}; +struct Section { + StringRef Name; + ELF_SHT Type; + ELF_SHF Flags; + llvm::yaml::Hex64 Address; + object::yaml::BinaryRef Content; + StringRef Link; + llvm::yaml::Hex64 AddressAlign; +}; struct Object { FileHeader Header; + std::vector<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 + // being a single SHT_SYMTAB section are upheld. + LocalGlobalWeakSymbols Symbols; }; } // end namespace ELFYAML } // end namespace llvm +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Section) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::ELFYAML::Symbol) + namespace llvm { namespace yaml { @@ -77,11 +113,46 @@ struct ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA> { }; template <> +struct ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI> { + static void enumeration(IO &IO, ELFYAML::ELF_ELFOSABI &Value); +}; + +template <> +struct ScalarEnumerationTraits<ELFYAML::ELF_SHT> { + static void enumeration(IO &IO, ELFYAML::ELF_SHT &Value); +}; + +template <> +struct ScalarBitSetTraits<ELFYAML::ELF_SHF> { + static void bitset(IO &IO, ELFYAML::ELF_SHF &Value); +}; + +template <> +struct ScalarEnumerationTraits<ELFYAML::ELF_STT> { + static void enumeration(IO &IO, ELFYAML::ELF_STT &Value); +}; + +template <> struct MappingTraits<ELFYAML::FileHeader> { static void mapping(IO &IO, ELFYAML::FileHeader &FileHdr); }; template <> +struct MappingTraits<ELFYAML::Symbol> { + static void mapping(IO &IO, ELFYAML::Symbol &Symbol); +}; + +template <> +struct MappingTraits<ELFYAML::LocalGlobalWeakSymbols> { + static void mapping(IO &IO, ELFYAML::LocalGlobalWeakSymbols &Symbols); +}; + +template <> +struct MappingTraits<ELFYAML::Section> { + static void mapping(IO &IO, ELFYAML::Section &Section); +}; + +template <> struct MappingTraits<ELFYAML::Object> { static void mapping(IO &IO, ELFYAML::Object &Object); }; diff --git a/include/llvm/Object/Error.h b/include/llvm/Object/Error.h index fbaf71c..8b0570b 100644 --- a/include/llvm/Object/Error.h +++ b/include/llvm/Object/Error.h @@ -22,17 +22,17 @@ namespace object { const error_category &object_category(); struct object_error { -enum _ { - success = 0, - invalid_file_type, - parse_failed, - unexpected_eof -}; - _ v_; - - object_error(_ v) : v_(v) {} - explicit object_error(int v) : v_(_(v)) {} - operator int() const {return v_;} + enum Impl { + success = 0, + arch_not_found, + invalid_file_type, + parse_failed, + unexpected_eof + }; + Impl V; + + object_error(Impl V) : V(V) {} + operator Impl() const { return V; } }; inline error_code make_error_code(object_error e) { @@ -43,7 +43,8 @@ inline error_code make_error_code(object_error e) { template <> struct is_error_code_enum<object::object_error> : true_type { }; -template <> struct is_error_code_enum<object::object_error::_> : true_type { }; +template <> struct is_error_code_enum<object::object_error::Impl> : true_type { +}; } // end namespace llvm. diff --git a/include/llvm/Object/MachO.h b/include/llvm/Object/MachO.h index 1b9faaa..50435d6 100644 --- a/include/llvm/Object/MachO.h +++ b/include/llvm/Object/MachO.h @@ -17,6 +17,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/Triple.h" #include "llvm/Object/MachOFormat.h" #include "llvm/Object/ObjectFile.h" #include "llvm/Support/MachO.h" @@ -196,6 +197,8 @@ public: bool is64Bit() const; void ReadULEB128s(uint64_t Index, SmallVectorImpl<uint64_t> &Out) const; + static Triple::ArchType getArch(uint32_t CPUType); + static bool classof(const Binary *v) { return v->isMachO(); } diff --git a/include/llvm/Object/MachOFormat.h b/include/llvm/Object/MachOFormat.h index ffca391..96ee8a7 100644 --- a/include/llvm/Object/MachOFormat.h +++ b/include/llvm/Object/MachOFormat.h @@ -95,6 +95,8 @@ namespace macho { enum StructureSizes { Header32Size = 28, Header64Size = 32, + FatHeaderSize = 8, + FatArchHeaderSize = 20, SegmentLoadCommand32Size = 56, SegmentLoadCommand64Size = 72, Section32Size = 68, @@ -130,6 +132,22 @@ namespace macho { uint32_t Reserved; }; + /// \brief Header for universal object files. + struct FatHeader { + uint32_t Magic; + uint32_t NumFatArch; + }; + + /// \brief Header for a single-architecture object file in a + /// universal binary. + struct FatArchHeader { + uint32_t CPUType; + uint32_t CPUSubtype; + uint32_t Offset; + uint32_t Size; + uint32_t Align; + }; + // See <mach-o/loader.h>. enum HeaderFileType { HFT_Object = 0x1 diff --git a/include/llvm/Object/MachOUniversal.h b/include/llvm/Object/MachOUniversal.h new file mode 100644 index 0000000..5743282 --- /dev/null +++ b/include/llvm/Object/MachOUniversal.h @@ -0,0 +1,102 @@ +//===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file declares Mach-O fat/universal binaries. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H +#define LLVM_OBJECT_MACHOUNIVERSAL_H + +#include "llvm/ADT/OwningPtr.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Object/Binary.h" +#include "llvm/Object/MachOFormat.h" + +namespace llvm { +namespace object { + +class ObjectFile; + +class MachOUniversalBinary : public Binary { + virtual void anchor(); + + uint32_t NumberOfObjects; +public: + class ObjectForArch { + const MachOUniversalBinary *Parent; + /// \brief Index of object in the universal binary. + uint32_t Index; + /// \brief Descriptor of the object. + macho::FatArchHeader Header; + + public: + ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index); + + void clear() { + Parent = 0; + Index = 0; + } + + bool operator==(const ObjectForArch &Other) const { + return (Parent == Other.Parent) && (Index == Other.Index); + } + + ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); } + uint32_t getCPUType() const { return Header.CPUType; } + + error_code getAsObjectFile(OwningPtr<ObjectFile> &Result) const; + }; + + class object_iterator { + ObjectForArch Obj; + public: + object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} + const ObjectForArch* operator->() const { + return &Obj; + } + + bool operator==(const object_iterator &Other) const { + return Obj == Other.Obj; + } + bool operator!=(const object_iterator &Other) const { + return !(*this == Other); + } + + object_iterator& operator++() { // Preincrement + Obj = Obj.getNext(); + return *this; + } + }; + + MachOUniversalBinary(MemoryBuffer *Source, error_code &ec); + + object_iterator begin_objects() const { + return ObjectForArch(this, 0); + } + object_iterator end_objects() const { + return ObjectForArch(0, 0); + } + + uint32_t getNumberOfObjects() const { return NumberOfObjects; } + + // Cast methods. + static inline bool classof(Binary const *V) { + return V->isMachOUniversalBinary(); + } + + error_code getObjectForArch(Triple::ArchType Arch, + OwningPtr<ObjectFile> &Result) const; +}; + +} +} + +#endif diff --git a/include/llvm/Object/RelocVisitor.h b/include/llvm/Object/RelocVisitor.h index 52e4d6f..b1eb4e6 100644 --- a/include/llvm/Object/RelocVisitor.h +++ b/include/llvm/Object/RelocVisitor.h @@ -81,6 +81,8 @@ public: switch (RelocType) { case llvm::ELF::R_PPC64_ADDR32: return visitELF_PPC64_ADDR32(R, Value); + case llvm::ELF::R_PPC64_ADDR64: + return visitELF_PPC64_ADDR64(R, Value); default: HasError = true; return RelocToApply(); @@ -217,6 +219,10 @@ private: uint32_t Res = (Value + Addend) & 0xFFFFFFFF; return RelocToApply(Res, 4); } + RelocToApply visitELF_PPC64_ADDR64(RelocationRef R, uint64_t Value) { + int64_t Addend = getAddend64BE(R); + return RelocToApply(Value + Addend, 8); + } /// PPC32 ELF RelocToApply visitELF_PPC_ADDR32(RelocationRef R, uint64_t Value) { |