aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Object
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
committerStephen Hines <srhines@google.com>2013-08-07 15:07:10 -0700
commitfab2daa4a1127ecb217abe2b07c1769122b6fee1 (patch)
tree268ebfd1963fd98ba412e76819afdf95a7d4267b /include/llvm/Object
parent8197ac1c1a0a91baa70c4dea8cb488f254ef974c (diff)
parent10251753b6897adcd22cc981c0cc42f348c109de (diff)
downloadexternal_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.h109
-rw-r--r--include/llvm/Object/Binary.h5
-rw-r--r--include/llvm/Object/COFF.h15
-rw-r--r--include/llvm/Object/ELF.h97
-rw-r--r--include/llvm/Object/ELFYAML.h71
-rw-r--r--include/llvm/Object/Error.h25
-rw-r--r--include/llvm/Object/MachO.h3
-rw-r--r--include/llvm/Object/MachOFormat.h18
-rw-r--r--include/llvm/Object/MachOUniversal.h102
-rw-r--r--include/llvm/Object/RelocVisitor.h6
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) {