aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Object
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
committerStephen Hines <srhines@google.com>2014-05-29 02:49:00 -0700
commitdce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch)
treedcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/Object
parent220b921aed042f9e520c26cffd8282a94c66c3d5 (diff)
downloadexternal_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.zip
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.gz
external_llvm-dce4a407a24b04eebc6a376f8e62b41aaa7b071f.tar.bz2
Update LLVM for 3.5 rebase (r209712).
Change-Id: I149556c940fb7dc92d075273c87ff584f400941f
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Android.mk1
-rw-r--r--lib/Object/Archive.cpp21
-rw-r--r--lib/Object/CMakeLists.txt1
-rw-r--r--lib/Object/COFFObjectFile.cpp55
-rw-r--r--lib/Object/COFFYAML.cpp33
-rw-r--r--lib/Object/ELF.cpp10
-rw-r--r--lib/Object/ELFYAML.cpp429
-rw-r--r--lib/Object/LLVMBuild.txt2
-rw-r--r--lib/Object/MachOObjectFile.cpp135
-rw-r--r--lib/Object/MachOUniversal.cpp22
-rw-r--r--lib/Object/Object.cpp9
-rw-r--r--lib/Object/StringTableBuilder.cpp51
12 files changed, 619 insertions, 150 deletions
diff --git a/lib/Object/Android.mk b/lib/Object/Android.mk
index 7dfa44f..bd9659c 100644
--- a/lib/Object/Android.mk
+++ b/lib/Object/Android.mk
@@ -12,6 +12,7 @@ object_SRC_FILES := \
MachOUniversal.cpp \
Object.cpp \
ObjectFile.cpp \
+ StringTableBuilder.cpp \
SymbolicFile.cpp
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp
index 999bf28..304ca47 100644
--- a/lib/Object/Archive.cpp
+++ b/lib/Object/Archive.cpp
@@ -13,7 +13,6 @@
#include "llvm/Object/Archive.h"
#include "llvm/ADT/APInt.h"
-#include "llvm/ADT/OwningPtr.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Endian.h"
@@ -111,7 +110,7 @@ Archive::Child Archive::Child::getNext() const {
// Check to see if this is past the end of the archive.
if (NextLoc >= Parent->Data->getBufferEnd())
- return Child(Parent, NULL);
+ return Child(Parent, nullptr);
return Child(Parent, NextLoc);
}
@@ -183,14 +182,6 @@ error_code Archive::Child::getMemoryBuffer(std::unique_ptr<MemoryBuffer> &Result
return error_code::success();
}
-error_code Archive::Child::getMemoryBuffer(OwningPtr<MemoryBuffer> &Result,
- bool FullPath) const {
- std::unique_ptr<MemoryBuffer> MB;
- error_code ec = getMemoryBuffer(MB, FullPath);
- Result = std::move(MB);
- return ec;
-}
-
error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
LLVMContext *Context) const {
std::unique_ptr<Binary> ret;
@@ -204,14 +195,6 @@ error_code Archive::Child::getAsBinary(std::unique_ptr<Binary> &Result,
return object_error::success;
}
-error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result,
- LLVMContext *Context) const {
- std::unique_ptr<Binary> B;
- error_code ec = getAsBinary(B, Context);
- Result = std::move(B);
- return ec;
-}
-
ErrorOr<Archive*> Archive::create(MemoryBuffer *Source) {
error_code EC;
std::unique_ptr<Archive> Ret(new Archive(Source, EC));
@@ -349,7 +332,7 @@ Archive::child_iterator Archive::child_begin(bool SkipInternal) const {
}
Archive::child_iterator Archive::child_end() const {
- return Child(this, NULL);
+ return Child(this, nullptr);
}
error_code Archive::Symbol::getName(StringRef &Result) const {
diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt
index dc18296..cd8c9ef 100644
--- a/lib/Object/CMakeLists.txt
+++ b/lib/Object/CMakeLists.txt
@@ -12,6 +12,7 @@ add_llvm_library(LLVMObject
MachOUniversal.cpp
Object.cpp
ObjectFile.cpp
+ StringTableBuilder.cpp
SymbolicFile.cpp
YAML.cpp
)
diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp
index a75ebbf..262c040 100644
--- a/lib/Object/COFFObjectFile.cpp
+++ b/lib/Object/COFFObjectFile.cpp
@@ -138,7 +138,7 @@ error_code COFFObjectFile::getSymbolName(DataRefImpl Ref,
error_code COFFObjectFile::getSymbolAddress(DataRefImpl Ref,
uint64_t &Result) const {
const coff_symbol *Symb = toSymb(Ref);
- const coff_section *Section = NULL;
+ const coff_section *Section = nullptr;
if (error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
@@ -163,7 +163,7 @@ error_code COFFObjectFile::getSymbolType(DataRefImpl Ref,
} else {
uint32_t Characteristics = 0;
if (!COFF::isReservedSectionNumber(Symb->SectionNumber)) {
- const coff_section *Section = NULL;
+ const coff_section *Section = nullptr;
if (error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
Characteristics = Section->Characteristics;
@@ -208,7 +208,7 @@ error_code COFFObjectFile::getSymbolSize(DataRefImpl Ref,
// in the same section as this symbol, and looking for either the next
// symbol, or the end of the section.
const coff_symbol *Symb = toSymb(Ref);
- const coff_section *Section = NULL;
+ const coff_section *Section = nullptr;
if (error_code EC = getSection(Symb->SectionNumber, Section))
return EC;
@@ -227,7 +227,7 @@ error_code COFFObjectFile::getSymbolSection(DataRefImpl Ref,
if (COFF::isReservedSectionNumber(Symb->SectionNumber)) {
Result = section_end();
} else {
- const coff_section *Sec = 0;
+ const coff_section *Sec = nullptr;
if (error_code EC = getSection(Symb->SectionNumber, Sec)) return EC;
DataRefImpl Ref;
Ref.p = reinterpret_cast<uintptr_t>(Sec);
@@ -334,7 +334,7 @@ error_code COFFObjectFile::sectionContainsSymbol(DataRefImpl SecRef,
bool &Result) const {
const coff_section *Sec = toSec(SecRef);
const coff_symbol *Symb = toSymb(SymbRef);
- const coff_section *SymbSec = 0;
+ const coff_section *SymbSec = nullptr;
if (error_code EC = getSection(Symb->SectionNumber, SymbSec)) return EC;
if (SymbSec == Sec)
Result = true;
@@ -389,11 +389,6 @@ relocation_iterator COFFObjectFile::section_rel_end(DataRefImpl Ref) const {
return relocation_iterator(RelocationRef(Ret, this));
}
-bool COFFObjectFile::section_rel_empty(DataRefImpl Ref) const {
- const coff_section *Sec = toSec(Ref);
- return Sec->NumberOfRelocations == 0;
-}
-
// Initialize the pointer to the symbol table.
error_code COFFObjectFile::initSymbolTablePtr() {
if (error_code EC = getObject(
@@ -512,10 +507,11 @@ error_code COFFObjectFile::initExportTablePtr() {
COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC,
bool BufferOwned)
- : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(0),
- PE32Header(0), PE32PlusHeader(0), DataDirectory(0), SectionTable(0),
- SymbolTable(0), StringTable(0), StringTableSize(0), ImportDirectory(0),
- NumberOfImportDirectory(0), ExportDirectory(0) {
+ : ObjectFile(Binary::ID_COFF, Object, BufferOwned), COFFHeader(nullptr),
+ PE32Header(nullptr), PE32PlusHeader(nullptr), DataDirectory(nullptr),
+ SectionTable(nullptr), SymbolTable(nullptr), StringTable(nullptr),
+ StringTableSize(0), ImportDirectory(nullptr), NumberOfImportDirectory(0),
+ ExportDirectory(nullptr) {
// Check that we at least have enough room for a header.
if (!checkSize(Data, EC, sizeof(coff_file_header))) return;
@@ -637,8 +633,8 @@ export_directory_iterator COFFObjectFile::export_directory_begin() const {
}
export_directory_iterator COFFObjectFile::export_directory_end() const {
- if (ExportDirectory == 0)
- return export_directory_iterator(ExportDirectoryEntryRef(0, 0, this));
+ if (!ExportDirectory)
+ return export_directory_iterator(ExportDirectoryEntryRef(nullptr, 0, this));
ExportDirectoryEntryRef Ref(ExportDirectory,
ExportDirectory->AddressTableEntries, this);
return export_directory_iterator(Ref);
@@ -728,7 +724,7 @@ error_code COFFObjectFile::getSection(int32_t Index,
const coff_section *&Result) const {
// Check for special index values.
if (COFF::isReservedSectionNumber(Index))
- Result = NULL;
+ Result = nullptr;
else if (Index > 0 && Index <= COFFHeader->NumberOfSections)
// We already verified the section table data, so no need to check again.
Result = SectionTable + (Index - 1);
@@ -778,7 +774,7 @@ error_code COFFObjectFile::getSymbolName(const coff_symbol *Symbol,
ArrayRef<uint8_t> COFFObjectFile::getSymbolAuxData(
const coff_symbol *Symbol) const {
- const uint8_t *Aux = NULL;
+ const uint8_t *Aux = nullptr;
if (Symbol->NumberOfAuxSymbols > 0) {
// AUX data comes immediately after the symbol in COFF
@@ -923,6 +919,27 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
Res = "Unknown";
}
break;
+ case COFF::IMAGE_FILE_MACHINE_ARMNT:
+ switch (Reloc->Type) {
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ABSOLUTE);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_ADDR32NB);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH11);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_TOKEN);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX24);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX11);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECTION);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_SECREL);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32A);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_MOV32T);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH20T);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BRANCH24T);
+ LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_ARM_BLX23T);
+ default:
+ Res = "Unknown";
+ }
+ break;
case COFF::IMAGE_FILE_MACHINE_I386:
switch (Reloc->Type) {
LLVM_COFF_SWITCH_RELOC_TYPE_NAME(IMAGE_REL_I386_ABSOLUTE);
@@ -952,7 +969,7 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel,
error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel,
SmallVectorImpl<char> &Result) const {
const coff_relocation *Reloc = toRel(Rel);
- const coff_symbol *Symb = 0;
+ const coff_symbol *Symb = nullptr;
if (error_code EC = getSymbol(Reloc->SymbolTableIndex, Symb)) return EC;
DataRefImpl Sym;
Sym.p = reinterpret_cast<uintptr_t>(Symb);
diff --git a/lib/Object/COFFYAML.cpp b/lib/Object/COFFYAML.cpp
index 94b72ff..49c5dda 100644
--- a/lib/Object/COFFYAML.cpp
+++ b/lib/Object/COFFYAML.cpp
@@ -38,6 +38,7 @@ void ScalarEnumerationTraits<COFFYAML::COMDATType>::enumeration(
void
ScalarEnumerationTraits<COFFYAML::WeakExternalCharacteristics>::enumeration(
IO &IO, COFFYAML::WeakExternalCharacteristics &Value) {
+ IO.enumCase(Value, "0", 0);
ECase(IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY);
ECase(IMAGE_WEAK_EXTERN_SEARCH_LIBRARY);
ECase(IMAGE_WEAK_EXTERN_SEARCH_ALIAS);
@@ -132,8 +133,8 @@ void ScalarEnumerationTraits<COFF::SymbolComplexType>::enumeration(
ECase(IMAGE_SYM_DTYPE_ARRAY);
}
-void ScalarEnumerationTraits<COFF::RelocationTypeX86>::enumeration(
- IO &IO, COFF::RelocationTypeX86 &Value) {
+void ScalarEnumerationTraits<COFF::RelocationTypeI386>::enumeration(
+ IO &IO, COFF::RelocationTypeI386 &Value) {
ECase(IMAGE_REL_I386_ABSOLUTE);
ECase(IMAGE_REL_I386_DIR16);
ECase(IMAGE_REL_I386_REL16);
@@ -145,6 +146,10 @@ void ScalarEnumerationTraits<COFF::RelocationTypeX86>::enumeration(
ECase(IMAGE_REL_I386_TOKEN);
ECase(IMAGE_REL_I386_SECREL7);
ECase(IMAGE_REL_I386_REL32);
+}
+
+void ScalarEnumerationTraits<COFF::RelocationTypeAMD64>::enumeration(
+ IO &IO, COFF::RelocationTypeAMD64 &Value) {
ECase(IMAGE_REL_AMD64_ABSOLUTE);
ECase(IMAGE_REL_AMD64_ADDR64);
ECase(IMAGE_REL_AMD64_ADDR32);
@@ -272,22 +277,33 @@ struct NHeaderCharacteristics {
COFF::Characteristics Characteristics;
};
+template <typename RelocType>
struct NType {
- NType(IO &) : Type(COFF::RelocationTypeX86(0)) {}
- NType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) {}
+ NType(IO &) : Type(RelocType(0)) {}
+ NType(IO &, uint16_t T) : Type(RelocType(T)) {}
uint16_t denormalize(IO &) { return Type; }
- COFF::RelocationTypeX86 Type;
+ RelocType Type;
};
}
void MappingTraits<COFFYAML::Relocation>::mapping(IO &IO,
COFFYAML::Relocation &Rel) {
- MappingNormalization<NType, uint16_t> NT(IO, Rel.Type);
-
IO.mapRequired("VirtualAddress", Rel.VirtualAddress);
IO.mapRequired("SymbolName", Rel.SymbolName);
- IO.mapRequired("Type", NT->Type);
+
+ COFF::header &H = *static_cast<COFF::header *>(IO.getContext());
+ if (H.Machine == COFF::IMAGE_FILE_MACHINE_I386) {
+ MappingNormalization<NType<COFF::RelocationTypeI386>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else if (H.Machine == COFF::IMAGE_FILE_MACHINE_AMD64) {
+ MappingNormalization<NType<COFF::RelocationTypeAMD64>, uint16_t> NT(
+ IO, Rel.Type);
+ IO.mapRequired("Type", NT->Type);
+ } else {
+ IO.mapRequired("Type", Rel.Type);
+ }
}
void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
@@ -297,6 +313,7 @@ void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) {
IO.mapRequired("Machine", NM->Machine);
IO.mapOptional("Characteristics", NC->Characteristics);
+ IO.setContext(static_cast<void *>(&H));
}
void MappingTraits<COFF::AuxiliaryFunctionDefinition>::mapping(
diff --git a/lib/Object/ELF.cpp b/lib/Object/ELF.cpp
index e9a88bf..df4dd5e 100644
--- a/lib/Object/ELF.cpp
+++ b/lib/Object/ELF.cpp
@@ -159,6 +159,15 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_HI16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_TLS_TPREL_LO16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_GLOB_DAT);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC21_S2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC26_S2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC18_S3);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC19_S2);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PCHI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PCLO16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS16_GOT16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS16_HI16);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS16_LO16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_COPY);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_JUMP_SLOT);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_26_S1);
@@ -177,6 +186,7 @@ StringRef getELFRelocationTypeName(uint32_t Machine, uint32_t Type) {
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_TPREL_HI16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MICROMIPS_TLS_TPREL_LO16);
LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_NUM);
+ LLVM_ELF_SWITCH_RELOC_TYPE_NAME(R_MIPS_PC32);
default:
break;
}
diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp
index d513670..7d50f23 100644
--- a/lib/Object/ELFYAML.cpp
+++ b/lib/Object/ELFYAML.cpp
@@ -12,8 +12,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/Object/ELFYAML.h"
+#include "llvm/Support/Casting.h"
namespace llvm {
+
+ELFYAML::Section::~Section() {}
+
namespace yaml {
void
@@ -239,44 +243,57 @@ void ScalarEnumerationTraits<ELFYAML::ELF_ELFOSABI>::enumeration(
void ScalarBitSetTraits<ELFYAML::ELF_EF>::bitset(IO &IO,
ELFYAML::ELF_EF &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
#define BCase(X) IO.bitSetCase(Value, #X, ELF::X);
- BCase(EF_ARM_SOFT_FLOAT)
- BCase(EF_ARM_VFP_FLOAT)
- BCase(EF_ARM_EABI_UNKNOWN)
- BCase(EF_ARM_EABI_VER1)
- BCase(EF_ARM_EABI_VER2)
- BCase(EF_ARM_EABI_VER3)
- BCase(EF_ARM_EABI_VER4)
- BCase(EF_ARM_EABI_VER5)
- BCase(EF_ARM_EABIMASK)
- BCase(EF_MIPS_NOREORDER)
- BCase(EF_MIPS_PIC)
- BCase(EF_MIPS_CPIC)
- BCase(EF_MIPS_ABI2)
- BCase(EF_MIPS_32BITMODE)
- BCase(EF_MIPS_ABI_O32)
- BCase(EF_MIPS_MICROMIPS)
- BCase(EF_MIPS_ARCH_ASE_M16)
- BCase(EF_MIPS_ARCH_1)
- BCase(EF_MIPS_ARCH_2)
- BCase(EF_MIPS_ARCH_3)
- BCase(EF_MIPS_ARCH_4)
- BCase(EF_MIPS_ARCH_5)
- BCase(EF_MIPS_ARCH_32)
- BCase(EF_MIPS_ARCH_64)
- BCase(EF_MIPS_ARCH_32R2)
- BCase(EF_MIPS_ARCH_64R2)
- BCase(EF_MIPS_ARCH)
- BCase(EF_HEXAGON_MACH_V2)
- BCase(EF_HEXAGON_MACH_V3)
- BCase(EF_HEXAGON_MACH_V4)
- BCase(EF_HEXAGON_MACH_V5)
- BCase(EF_HEXAGON_ISA_MACH)
- BCase(EF_HEXAGON_ISA_V2)
- BCase(EF_HEXAGON_ISA_V3)
- BCase(EF_HEXAGON_ISA_V4)
- BCase(EF_HEXAGON_ISA_V5)
+#define BCaseMask(X, M) IO.maskedBitSetCase(Value, #X, ELF::X, ELF::M);
+ switch (Object->Header.Machine) {
+ case ELF::EM_ARM:
+ BCase(EF_ARM_SOFT_FLOAT)
+ BCase(EF_ARM_VFP_FLOAT)
+ BCaseMask(EF_ARM_EABI_UNKNOWN, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER1, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER2, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER3, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER4, EF_ARM_EABIMASK)
+ BCaseMask(EF_ARM_EABI_VER5, EF_ARM_EABIMASK)
+ break;
+ case ELF::EM_MIPS:
+ BCase(EF_MIPS_NOREORDER)
+ BCase(EF_MIPS_PIC)
+ BCase(EF_MIPS_CPIC)
+ BCase(EF_MIPS_ABI2)
+ BCase(EF_MIPS_32BITMODE)
+ BCase(EF_MIPS_ABI_O32)
+ BCase(EF_MIPS_MICROMIPS)
+ BCase(EF_MIPS_ARCH_ASE_M16)
+ BCaseMask(EF_MIPS_ARCH_1, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_3, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_4, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_5, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32R2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64R2, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_32R6, EF_MIPS_ARCH)
+ BCaseMask(EF_MIPS_ARCH_64R6, EF_MIPS_ARCH)
+ break;
+ case ELF::EM_HEXAGON:
+ BCase(EF_HEXAGON_MACH_V2)
+ BCase(EF_HEXAGON_MACH_V3)
+ BCase(EF_HEXAGON_MACH_V4)
+ BCase(EF_HEXAGON_MACH_V5)
+ BCase(EF_HEXAGON_ISA_V2)
+ BCase(EF_HEXAGON_ISA_V3)
+ BCase(EF_HEXAGON_ISA_V4)
+ BCase(EF_HEXAGON_ISA_V5)
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
#undef BCase
+#undef BCaseMask
}
void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
@@ -300,6 +317,23 @@ void ScalarEnumerationTraits<ELFYAML::ELF_SHT>::enumeration(
ECase(SHT_PREINIT_ARRAY)
ECase(SHT_GROUP)
ECase(SHT_SYMTAB_SHNDX)
+ ECase(SHT_LOOS)
+ ECase(SHT_GNU_ATTRIBUTES)
+ ECase(SHT_GNU_HASH)
+ ECase(SHT_GNU_verdef)
+ ECase(SHT_GNU_verneed)
+ ECase(SHT_GNU_versym)
+ ECase(SHT_HIOS)
+ ECase(SHT_LOPROC)
+ ECase(SHT_ARM_EXIDX)
+ ECase(SHT_ARM_PREEMPTMAP)
+ ECase(SHT_ARM_ATTRIBUTES)
+ ECase(SHT_ARM_DEBUGOVERLAY)
+ ECase(SHT_ARM_OVERLAYSECTION)
+ ECase(SHT_HEX_ORDERED)
+ ECase(SHT_X86_64_UNWIND)
+ ECase(SHT_MIPS_REGINFO)
+ ECase(SHT_MIPS_OPTIONS)
#undef ECase
}
@@ -334,6 +368,270 @@ void ScalarEnumerationTraits<ELFYAML::ELF_STT>::enumeration(
#undef ECase
}
+void ScalarEnumerationTraits<ELFYAML::ELF_REL>::enumeration(
+ IO &IO, ELFYAML::ELF_REL &Value) {
+ const auto *Object = static_cast<ELFYAML::Object *>(IO.getContext());
+ assert(Object && "The IO context is not initialized");
+#define ECase(X) IO.enumCase(Value, #X, ELF::X);
+ switch (Object->Header.Machine) {
+ case ELF::EM_X86_64:
+ ECase(R_X86_64_NONE)
+ ECase(R_X86_64_64)
+ ECase(R_X86_64_PC32)
+ ECase(R_X86_64_GOT32)
+ ECase(R_X86_64_PLT32)
+ ECase(R_X86_64_COPY)
+ ECase(R_X86_64_GLOB_DAT)
+ ECase(R_X86_64_JUMP_SLOT)
+ ECase(R_X86_64_RELATIVE)
+ ECase(R_X86_64_GOTPCREL)
+ ECase(R_X86_64_32)
+ ECase(R_X86_64_32S)
+ ECase(R_X86_64_16)
+ ECase(R_X86_64_PC16)
+ ECase(R_X86_64_8)
+ ECase(R_X86_64_PC8)
+ ECase(R_X86_64_DTPMOD64)
+ ECase(R_X86_64_DTPOFF64)
+ ECase(R_X86_64_TPOFF64)
+ ECase(R_X86_64_TLSGD)
+ ECase(R_X86_64_TLSLD)
+ ECase(R_X86_64_DTPOFF32)
+ ECase(R_X86_64_GOTTPOFF)
+ ECase(R_X86_64_TPOFF32)
+ ECase(R_X86_64_PC64)
+ ECase(R_X86_64_GOTOFF64)
+ ECase(R_X86_64_GOTPC32)
+ ECase(R_X86_64_GOT64)
+ ECase(R_X86_64_GOTPCREL64)
+ ECase(R_X86_64_GOTPC64)
+ ECase(R_X86_64_GOTPLT64)
+ ECase(R_X86_64_PLTOFF64)
+ ECase(R_X86_64_SIZE32)
+ ECase(R_X86_64_SIZE64)
+ ECase(R_X86_64_GOTPC32_TLSDESC)
+ ECase(R_X86_64_TLSDESC_CALL)
+ ECase(R_X86_64_TLSDESC)
+ ECase(R_X86_64_IRELATIVE)
+ break;
+ case ELF::EM_MIPS:
+ ECase(R_MIPS_NONE)
+ ECase(R_MIPS_16)
+ ECase(R_MIPS_32)
+ ECase(R_MIPS_REL32)
+ ECase(R_MIPS_26)
+ ECase(R_MIPS_HI16)
+ ECase(R_MIPS_LO16)
+ ECase(R_MIPS_GPREL16)
+ ECase(R_MIPS_LITERAL)
+ ECase(R_MIPS_GOT16)
+ ECase(R_MIPS_PC16)
+ ECase(R_MIPS_CALL16)
+ ECase(R_MIPS_GPREL32)
+ ECase(R_MIPS_UNUSED1)
+ ECase(R_MIPS_UNUSED2)
+ ECase(R_MIPS_SHIFT5)
+ ECase(R_MIPS_SHIFT6)
+ ECase(R_MIPS_64)
+ ECase(R_MIPS_GOT_DISP)
+ ECase(R_MIPS_GOT_PAGE)
+ ECase(R_MIPS_GOT_OFST)
+ ECase(R_MIPS_GOT_HI16)
+ ECase(R_MIPS_GOT_LO16)
+ ECase(R_MIPS_SUB)
+ ECase(R_MIPS_INSERT_A)
+ ECase(R_MIPS_INSERT_B)
+ ECase(R_MIPS_DELETE)
+ ECase(R_MIPS_HIGHER)
+ ECase(R_MIPS_HIGHEST)
+ ECase(R_MIPS_CALL_HI16)
+ ECase(R_MIPS_CALL_LO16)
+ ECase(R_MIPS_SCN_DISP)
+ ECase(R_MIPS_REL16)
+ ECase(R_MIPS_ADD_IMMEDIATE)
+ ECase(R_MIPS_PJUMP)
+ ECase(R_MIPS_RELGOT)
+ ECase(R_MIPS_JALR)
+ ECase(R_MIPS_TLS_DTPMOD32)
+ ECase(R_MIPS_TLS_DTPREL32)
+ ECase(R_MIPS_TLS_DTPMOD64)
+ ECase(R_MIPS_TLS_DTPREL64)
+ ECase(R_MIPS_TLS_GD)
+ ECase(R_MIPS_TLS_LDM)
+ ECase(R_MIPS_TLS_DTPREL_HI16)
+ ECase(R_MIPS_TLS_DTPREL_LO16)
+ ECase(R_MIPS_TLS_GOTTPREL)
+ ECase(R_MIPS_TLS_TPREL32)
+ ECase(R_MIPS_TLS_TPREL64)
+ ECase(R_MIPS_TLS_TPREL_HI16)
+ ECase(R_MIPS_TLS_TPREL_LO16)
+ ECase(R_MIPS_GLOB_DAT)
+ ECase(R_MIPS_PC21_S2)
+ ECase(R_MIPS_PC26_S2)
+ ECase(R_MIPS_PC18_S3)
+ ECase(R_MIPS_PC19_S2)
+ ECase(R_MIPS_PCHI16)
+ ECase(R_MIPS_PCLO16)
+ ECase(R_MIPS16_GOT16)
+ ECase(R_MIPS16_HI16)
+ ECase(R_MIPS16_LO16)
+ ECase(R_MIPS_COPY)
+ ECase(R_MIPS_JUMP_SLOT)
+ ECase(R_MICROMIPS_26_S1)
+ ECase(R_MICROMIPS_HI16)
+ ECase(R_MICROMIPS_LO16)
+ ECase(R_MICROMIPS_GOT16)
+ ECase(R_MICROMIPS_PC16_S1)
+ ECase(R_MICROMIPS_CALL16)
+ ECase(R_MICROMIPS_GOT_DISP)
+ ECase(R_MICROMIPS_GOT_PAGE)
+ ECase(R_MICROMIPS_GOT_OFST)
+ ECase(R_MICROMIPS_TLS_GD)
+ ECase(R_MICROMIPS_TLS_LDM)
+ ECase(R_MICROMIPS_TLS_DTPREL_HI16)
+ ECase(R_MICROMIPS_TLS_DTPREL_LO16)
+ ECase(R_MICROMIPS_TLS_TPREL_HI16)
+ ECase(R_MICROMIPS_TLS_TPREL_LO16)
+ ECase(R_MIPS_NUM)
+ ECase(R_MIPS_PC32)
+ break;
+ case ELF::EM_HEXAGON:
+ ECase(R_HEX_NONE)
+ ECase(R_HEX_B22_PCREL)
+ ECase(R_HEX_B15_PCREL)
+ ECase(R_HEX_B7_PCREL)
+ ECase(R_HEX_LO16)
+ ECase(R_HEX_HI16)
+ ECase(R_HEX_32)
+ ECase(R_HEX_16)
+ ECase(R_HEX_8)
+ ECase(R_HEX_GPREL16_0)
+ ECase(R_HEX_GPREL16_1)
+ ECase(R_HEX_GPREL16_2)
+ ECase(R_HEX_GPREL16_3)
+ ECase(R_HEX_HL16)
+ ECase(R_HEX_B13_PCREL)
+ ECase(R_HEX_B9_PCREL)
+ ECase(R_HEX_B32_PCREL_X)
+ ECase(R_HEX_32_6_X)
+ ECase(R_HEX_B22_PCREL_X)
+ ECase(R_HEX_B15_PCREL_X)
+ ECase(R_HEX_B13_PCREL_X)
+ ECase(R_HEX_B9_PCREL_X)
+ ECase(R_HEX_B7_PCREL_X)
+ ECase(R_HEX_16_X)
+ ECase(R_HEX_12_X)
+ ECase(R_HEX_11_X)
+ ECase(R_HEX_10_X)
+ ECase(R_HEX_9_X)
+ ECase(R_HEX_8_X)
+ ECase(R_HEX_7_X)
+ ECase(R_HEX_6_X)
+ ECase(R_HEX_32_PCREL)
+ ECase(R_HEX_COPY)
+ ECase(R_HEX_GLOB_DAT)
+ ECase(R_HEX_JMP_SLOT)
+ ECase(R_HEX_RELATIVE)
+ ECase(R_HEX_PLT_B22_PCREL)
+ ECase(R_HEX_GOTREL_LO16)
+ ECase(R_HEX_GOTREL_HI16)
+ ECase(R_HEX_GOTREL_32)
+ ECase(R_HEX_GOT_LO16)
+ ECase(R_HEX_GOT_HI16)
+ ECase(R_HEX_GOT_32)
+ ECase(R_HEX_GOT_16)
+ ECase(R_HEX_DTPMOD_32)
+ ECase(R_HEX_DTPREL_LO16)
+ ECase(R_HEX_DTPREL_HI16)
+ ECase(R_HEX_DTPREL_32)
+ ECase(R_HEX_DTPREL_16)
+ ECase(R_HEX_GD_PLT_B22_PCREL)
+ ECase(R_HEX_GD_GOT_LO16)
+ ECase(R_HEX_GD_GOT_HI16)
+ ECase(R_HEX_GD_GOT_32)
+ ECase(R_HEX_GD_GOT_16)
+ ECase(R_HEX_IE_LO16)
+ ECase(R_HEX_IE_HI16)
+ ECase(R_HEX_IE_32)
+ ECase(R_HEX_IE_GOT_LO16)
+ ECase(R_HEX_IE_GOT_HI16)
+ ECase(R_HEX_IE_GOT_32)
+ ECase(R_HEX_IE_GOT_16)
+ ECase(R_HEX_TPREL_LO16)
+ ECase(R_HEX_TPREL_HI16)
+ ECase(R_HEX_TPREL_32)
+ ECase(R_HEX_TPREL_16)
+ ECase(R_HEX_6_PCREL_X)
+ ECase(R_HEX_GOTREL_32_6_X)
+ ECase(R_HEX_GOTREL_16_X)
+ ECase(R_HEX_GOTREL_11_X)
+ ECase(R_HEX_GOT_32_6_X)
+ ECase(R_HEX_GOT_16_X)
+ ECase(R_HEX_GOT_11_X)
+ ECase(R_HEX_DTPREL_32_6_X)
+ ECase(R_HEX_DTPREL_16_X)
+ ECase(R_HEX_DTPREL_11_X)
+ ECase(R_HEX_GD_GOT_32_6_X)
+ ECase(R_HEX_GD_GOT_16_X)
+ ECase(R_HEX_GD_GOT_11_X)
+ ECase(R_HEX_IE_32_6_X)
+ ECase(R_HEX_IE_16_X)
+ ECase(R_HEX_IE_GOT_32_6_X)
+ ECase(R_HEX_IE_GOT_16_X)
+ ECase(R_HEX_IE_GOT_11_X)
+ ECase(R_HEX_TPREL_32_6_X)
+ ECase(R_HEX_TPREL_16_X)
+ ECase(R_HEX_TPREL_11_X)
+ break;
+ case ELF::EM_386:
+ ECase(R_386_NONE)
+ ECase(R_386_32)
+ ECase(R_386_PC32)
+ ECase(R_386_GOT32)
+ ECase(R_386_PLT32)
+ ECase(R_386_COPY)
+ ECase(R_386_GLOB_DAT)
+ ECase(R_386_JUMP_SLOT)
+ ECase(R_386_RELATIVE)
+ ECase(R_386_GOTOFF)
+ ECase(R_386_GOTPC)
+ ECase(R_386_32PLT)
+ ECase(R_386_TLS_TPOFF)
+ ECase(R_386_TLS_IE)
+ ECase(R_386_TLS_GOTIE)
+ ECase(R_386_TLS_LE)
+ ECase(R_386_TLS_GD)
+ ECase(R_386_TLS_LDM)
+ ECase(R_386_16)
+ ECase(R_386_PC16)
+ ECase(R_386_8)
+ ECase(R_386_PC8)
+ ECase(R_386_TLS_GD_32)
+ ECase(R_386_TLS_GD_PUSH)
+ ECase(R_386_TLS_GD_CALL)
+ ECase(R_386_TLS_GD_POP)
+ ECase(R_386_TLS_LDM_32)
+ ECase(R_386_TLS_LDM_PUSH)
+ ECase(R_386_TLS_LDM_CALL)
+ ECase(R_386_TLS_LDM_POP)
+ ECase(R_386_TLS_LDO_32)
+ ECase(R_386_TLS_IE_32)
+ ECase(R_386_TLS_LE_32)
+ ECase(R_386_TLS_DTPMOD32)
+ ECase(R_386_TLS_DTPOFF32)
+ ECase(R_386_TLS_TPOFF32)
+ ECase(R_386_TLS_GOTDESC)
+ ECase(R_386_TLS_DESC_CALL)
+ ECase(R_386_TLS_DESC)
+ ECase(R_386_IRELATIVE)
+ ECase(R_386_NUM)
+ break;
+ default:
+ llvm_unreachable("Unsupported architecture");
+ }
+#undef ECase
+}
+
void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO,
ELFYAML::FileHeader &FileHdr) {
IO.mapRequired("Class", FileHdr.Class);
@@ -360,21 +658,72 @@ void MappingTraits<ELFYAML::LocalGlobalWeakSymbols>::mapping(
IO.mapOptional("Weak", Symbols.Weak);
}
-void MappingTraits<ELFYAML::Section>::mapping(IO &IO,
- ELFYAML::Section &Section) {
+static void commonSectionMapping(IO &IO, ELFYAML::Section &Section) {
IO.mapOptional("Name", Section.Name, StringRef());
IO.mapRequired("Type", Section.Type);
IO.mapOptional("Flags", Section.Flags, ELFYAML::ELF_SHF(0));
IO.mapOptional("Address", Section.Address, Hex64(0));
- IO.mapOptional("Content", Section.Content);
- IO.mapOptional("Link", Section.Link);
+ IO.mapOptional("Link", Section.Link, StringRef());
+ IO.mapOptional("Info", Section.Info, StringRef());
IO.mapOptional("AddressAlign", Section.AddressAlign, Hex64(0));
}
+static void sectionMapping(IO &IO, ELFYAML::RawContentSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Content", Section.Content);
+ IO.mapOptional("Size", Section.Size, Hex64(Section.Content.binary_size()));
+}
+
+static void sectionMapping(IO &IO, ELFYAML::RelocationSection &Section) {
+ commonSectionMapping(IO, Section);
+ IO.mapOptional("Relocations", Section.Relocations);
+}
+
+void MappingTraits<std::unique_ptr<ELFYAML::Section>>::mapping(
+ IO &IO, std::unique_ptr<ELFYAML::Section> &Section) {
+ ELFYAML::ELF_SHT sectionType;
+ if (IO.outputting())
+ sectionType = Section->Type;
+ else
+ IO.mapRequired("Type", sectionType);
+
+ switch (sectionType) {
+ case ELF::SHT_REL:
+ case ELF::SHT_RELA:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RelocationSection());
+ sectionMapping(IO, *cast<ELFYAML::RelocationSection>(Section.get()));
+ break;
+ default:
+ if (!IO.outputting())
+ Section.reset(new ELFYAML::RawContentSection());
+ sectionMapping(IO, *cast<ELFYAML::RawContentSection>(Section.get()));
+ }
+}
+
+StringRef MappingTraits<std::unique_ptr<ELFYAML::Section>>::validate(
+ IO &io, std::unique_ptr<ELFYAML::Section> &Section) {
+ const auto *RawSection = dyn_cast<ELFYAML::RawContentSection>(Section.get());
+ if (!RawSection || RawSection->Size >= RawSection->Content.binary_size())
+ return StringRef();
+ return "Section size must be greater or equal to the content size";
+}
+
+void MappingTraits<ELFYAML::Relocation>::mapping(IO &IO,
+ ELFYAML::Relocation &Rel) {
+ IO.mapRequired("Offset", Rel.Offset);
+ IO.mapRequired("Symbol", Rel.Symbol);
+ IO.mapRequired("Type", Rel.Type);
+ IO.mapOptional("Addend", Rel.Addend);
+}
+
void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) {
+ assert(!IO.getContext() && "The IO context is initialized already");
+ IO.setContext(&Object);
IO.mapRequired("FileHeader", Object.Header);
IO.mapOptional("Sections", Object.Sections);
IO.mapOptional("Symbols", Object.Symbols);
+ IO.setContext(nullptr);
}
} // end namespace yaml
diff --git a/lib/Object/LLVMBuild.txt b/lib/Object/LLVMBuild.txt
index a87da6e..7813832 100644
--- a/lib/Object/LLVMBuild.txt
+++ b/lib/Object/LLVMBuild.txt
@@ -19,4 +19,4 @@
type = Library
name = Object
parent = Libraries
-required_libraries = Support BitReader
+required_libraries = BitReader Core Support
diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp
index 12132a4..c6bab03 100644
--- a/lib/Object/MachOObjectFile.cpp
+++ b/lib/Object/MachOObjectFile.cpp
@@ -420,7 +420,8 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian,
bool Is64bits, error_code &EC,
bool BufferOwned)
: ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object, BufferOwned),
- SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) {
+ SymtabLoadCmd(nullptr), DysymtabLoadCmd(nullptr),
+ DataInCodeLoadCmd(nullptr) {
uint32_t LoadCommandCount = this->getHeader().ncmds;
MachO::LoadCommandType SegmentLoadType = is64Bit() ?
MachO::LC_SEGMENT_64 : MachO::LC_SEGMENT;
@@ -471,10 +472,18 @@ error_code MachOObjectFile::getSymbolAddress(DataRefImpl Symb,
uint64_t &Res) const {
if (is64Bit()) {
MachO::nlist_64 Entry = getSymbol64TableEntry(Symb);
- Res = Entry.n_value;
+ if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
+ Entry.n_value == 0)
+ Res = UnknownAddressOrSize;
+ else
+ Res = Entry.n_value;
} else {
MachO::nlist Entry = getSymbolTableEntry(Symb);
- Res = Entry.n_value;
+ if ((Entry.n_type & MachO::N_TYPE) == MachO::N_UNDF &&
+ Entry.n_value == 0)
+ Res = UnknownAddressOrSize;
+ else
+ Res = Entry.n_value;
}
return object_error::success;
}
@@ -500,6 +509,10 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
nlist_base Entry = getSymbolTableEntryBase(this, DRI);
uint64_t Value;
getSymbolAddress(DRI, Value);
+ if (Value == UnknownAddressOrSize) {
+ Result = UnknownAddressOrSize;
+ return object_error::success;
+ }
BeginOffset = Value;
@@ -518,6 +531,8 @@ error_code MachOObjectFile::getSymbolSize(DataRefImpl DRI,
DataRefImpl DRI = Symbol.getRawDataRefImpl();
Entry = getSymbolTableEntryBase(this, DRI);
getSymbolAddress(DRI, Value);
+ if (Value == UnknownAddressOrSize)
+ continue;
if (Entry.n_sect == SectionIndex && Value > BeginOffset)
if (!EndOffset || Value < EndOffset)
EndOffset = Value;
@@ -577,7 +592,7 @@ uint32_t MachOObjectFile::getSymbolFlags(DataRefImpl DRI) const {
if ((MachOType & MachO::N_TYPE) == MachO::N_UNDF) {
uint64_t Value;
getSymbolAddress(DRI, Value);
- if (Value)
+ if (Value && Value != UnknownAddressOrSize)
Result |= SymbolRef::SF_Common;
}
}
@@ -685,15 +700,21 @@ MachOObjectFile::isSectionText(DataRefImpl Sec, bool &Res) const {
return object_error::success;
}
-error_code MachOObjectFile::isSectionData(DataRefImpl DRI, bool &Result) const {
- // FIXME: Unimplemented.
- Result = false;
+error_code MachOObjectFile::isSectionData(DataRefImpl Sec, bool &Result) const {
+ uint32_t Flags = getSectionFlags(this, Sec);
+ unsigned SectionType = Flags & MachO::SECTION_TYPE;
+ Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
+ !(SectionType == MachO::S_ZEROFILL ||
+ SectionType == MachO::S_GB_ZEROFILL);
return object_error::success;
}
-error_code MachOObjectFile::isSectionBSS(DataRefImpl DRI, bool &Result) const {
- // FIXME: Unimplemented.
- Result = false;
+error_code MachOObjectFile::isSectionBSS(DataRefImpl Sec, bool &Result) const {
+ uint32_t Flags = getSectionFlags(this, Sec);
+ unsigned SectionType = Flags & MachO::SECTION_TYPE;
+ Result = !(Flags & MachO::S_ATTR_PURE_INSTRUCTIONS) &&
+ (SectionType == MachO::S_ZEROFILL ||
+ SectionType == MachO::S_GB_ZEROFILL);
return object_error::success;
}
@@ -755,65 +776,50 @@ MachOObjectFile::sectionContainsSymbol(DataRefImpl Sec, DataRefImpl Symb,
}
relocation_iterator MachOObjectFile::section_rel_begin(DataRefImpl Sec) const {
- uint32_t Offset;
- if (is64Bit()) {
- MachO::section_64 Sect = getSection64(Sec);
- Offset = Sect.reloff;
- } else {
- MachO::section Sect = getSection(Sec);
- Offset = Sect.reloff;
- }
-
DataRefImpl Ret;
- Ret.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset));
+ Ret.d.a = Sec.d.a;
+ Ret.d.b = 0;
return relocation_iterator(RelocationRef(Ret, this));
}
relocation_iterator
MachOObjectFile::section_rel_end(DataRefImpl Sec) const {
- uint32_t Offset;
uint32_t Num;
if (is64Bit()) {
MachO::section_64 Sect = getSection64(Sec);
- Offset = Sect.reloff;
Num = Sect.nreloc;
} else {
MachO::section Sect = getSection(Sec);
- Offset = Sect.reloff;
Num = Sect.nreloc;
}
- const MachO::any_relocation_info *P =
- reinterpret_cast<const MachO::any_relocation_info *>(getPtr(this, Offset));
-
DataRefImpl Ret;
- Ret.p = reinterpret_cast<uintptr_t>(P + Num);
+ Ret.d.a = Sec.d.a;
+ Ret.d.b = Num;
return relocation_iterator(RelocationRef(Ret, this));
}
-bool MachOObjectFile::section_rel_empty(DataRefImpl Sec) const {
- if (is64Bit()) {
- MachO::section_64 Sect = getSection64(Sec);
- return Sect.nreloc == 0;
- } else {
- MachO::section Sect = getSection(Sec);
- return Sect.nreloc == 0;
- }
-}
-
void MachOObjectFile::moveRelocationNext(DataRefImpl &Rel) const {
- const MachO::any_relocation_info *P =
- reinterpret_cast<const MachO::any_relocation_info *>(Rel.p);
- Rel.p = reinterpret_cast<uintptr_t>(P + 1);
+ ++Rel.d.b;
}
error_code
MachOObjectFile::getRelocationAddress(DataRefImpl Rel, uint64_t &Res) const {
- report_fatal_error("getRelocationAddress not implemented in MachOObjectFile");
+ uint64_t Offset;
+ getRelocationOffset(Rel, Offset);
+
+ DataRefImpl Sec;
+ Sec.d.a = Rel.d.a;
+ uint64_t SecAddress;
+ getSectionAddress(Sec, SecAddress);
+ Res = SecAddress + Offset;
+ return object_error::success;
}
error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel,
uint64_t &Res) const {
+ assert(getHeader().filetype == MachO::MH_OBJECT &&
+ "Only implemented for MH_OBJECT");
MachO::any_relocation_info RE = getRelocation(Rel);
Res = getAnyRelocationAddress(RE);
return object_error::success;
@@ -986,7 +992,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
}
case MachO::X86_64_RELOC_SUBTRACTOR: {
DataRefImpl RelNext = Rel;
- RelNext.d.a++;
+ moveRelocationNext(RelNext);
MachO::any_relocation_info RENext = getRelocation(RelNext);
// X86_64_RELOC_SUBTRACTOR must be followed by a relocation of type
@@ -1034,7 +1040,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
return object_error::success;
case MachO::GENERIC_RELOC_SECTDIFF: {
DataRefImpl RelNext = Rel;
- RelNext.d.a++;
+ moveRelocationNext(RelNext);
MachO::any_relocation_info RENext = getRelocation(RelNext);
// X86 sect diff's must be followed by a relocation of type
@@ -1056,7 +1062,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
switch (Type) {
case MachO::GENERIC_RELOC_LOCAL_SECTDIFF: {
DataRefImpl RelNext = Rel;
- RelNext.d.a++;
+ moveRelocationNext(RelNext);
MachO::any_relocation_info RENext = getRelocation(RelNext);
// X86 sect diff's must be followed by a relocation of type
@@ -1095,7 +1101,7 @@ MachOObjectFile::getRelocationValueString(DataRefImpl Rel,
printRelocationTargetName(this, RE, fmt);
DataRefImpl RelNext = Rel;
- RelNext.d.a++;
+ moveRelocationNext(RelNext);
MachO::any_relocation_info RENext = getRelocation(RelNext);
// ARM half relocs must be followed by a relocation of type
@@ -1172,13 +1178,7 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData,
}
basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const {
- DataRefImpl DRI;
- if (!SymtabLoadCmd)
- return basic_symbol_iterator(SymbolRef(DRI, this));
-
- MachO::symtab_command Symtab = getSymtabLoadCommand();
- DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
- return basic_symbol_iterator(SymbolRef(DRI, this));
+ return getSymbolByIndex(0);
}
basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
@@ -1196,6 +1196,20 @@ basic_symbol_iterator MachOObjectFile::symbol_end_impl() const {
return basic_symbol_iterator(SymbolRef(DRI, this));
}
+basic_symbol_iterator MachOObjectFile::getSymbolByIndex(unsigned Index) const {
+ DataRefImpl DRI;
+ if (!SymtabLoadCmd)
+ return basic_symbol_iterator(SymbolRef(DRI, this));
+
+ MachO::symtab_command Symtab = getSymtabLoadCommand();
+ assert(Index < Symtab.nsyms && "Requested symbol index is out of range.");
+ unsigned SymbolTableEntrySize =
+ is64Bit() ? sizeof(MachO::nlist_64) : sizeof(MachO::nlist);
+ DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff));
+ DRI.p += Index * SymbolTableEntrySize;
+ return basic_symbol_iterator(SymbolRef(DRI, this));
+}
+
section_iterator MachOObjectFile::section_begin() const {
DataRefImpl DRI;
return section_iterator(SectionRef(DRI, this));
@@ -1486,8 +1500,21 @@ MachOObjectFile::getVersionMinLoadCommand(const LoadCommandInfo &L) const {
MachO::any_relocation_info
MachOObjectFile::getRelocation(DataRefImpl Rel) const {
- const char *P = reinterpret_cast<const char *>(Rel.p);
- return getStruct<MachO::any_relocation_info>(this, P);
+ DataRefImpl Sec;
+ Sec.d.a = Rel.d.a;
+ uint32_t Offset;
+ if (is64Bit()) {
+ MachO::section_64 Sect = getSection64(Sec);
+ Offset = Sect.reloff;
+ } else {
+ MachO::section Sect = getSection(Sec);
+ Offset = Sect.reloff;
+ }
+
+ auto P = reinterpret_cast<const MachO::any_relocation_info *>(
+ getPtr(this, Offset)) + Rel.d.b;
+ return getStruct<MachO::any_relocation_info>(
+ this, reinterpret_cast<const char *>(P));
}
MachO::data_in_code_entry
diff --git a/lib/Object/MachOUniversal.cpp b/lib/Object/MachOUniversal.cpp
index 70baa9f..5085efd 100644
--- a/lib/Object/MachOUniversal.cpp
+++ b/lib/Object/MachOUniversal.cpp
@@ -14,6 +14,7 @@
#include "llvm/Object/MachOUniversal.h"
#include "llvm/Object/MachO.h"
#include "llvm/Object/ObjectFile.h"
+#include "llvm/Object/Archive.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/MemoryBuffer.h"
@@ -57,7 +58,7 @@ static T getUniversalBinaryStruct(const char *Ptr) {
MachOUniversalBinary::ObjectForArch::ObjectForArch(
const MachOUniversalBinary *Parent, uint32_t Index)
: Parent(Parent), Index(Index) {
- if (Parent == 0 || Index > Parent->getNumberOfObjects()) {
+ if (!Parent || Index > Parent->getNumberOfObjects()) {
clear();
} else {
// Parse object header.
@@ -90,6 +91,25 @@ error_code MachOUniversalBinary::ObjectForArch::getAsObjectFile(
return object_error::parse_failed;
}
+error_code MachOUniversalBinary::ObjectForArch::getAsArchive(
+ std::unique_ptr<Archive> &Result) const {
+ if (Parent) {
+ StringRef ParentData = Parent->getData();
+ StringRef ObjectData = ParentData.substr(Header.offset, Header.size);
+ std::string ObjectName =
+ Parent->getFileName().str() + ":" +
+ Triple::getArchTypeName(MachOObjectFile::getArch(Header.cputype));
+ MemoryBuffer *ObjBuffer = MemoryBuffer::getMemBuffer(
+ ObjectData, ObjectName, false);
+ ErrorOr<Archive *> Obj = Archive::create(ObjBuffer);
+ if (error_code EC = Obj.getError())
+ return EC;
+ Result.reset(Obj.get());
+ return object_error::success;
+ }
+ return object_error::parse_failed;
+}
+
void MachOUniversalBinary::anchor() { }
ErrorOr<MachOUniversalBinary *>
diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp
index 243bd44..b0068a8 100644
--- a/lib/Object/Object.cpp
+++ b/lib/Object/Object.cpp
@@ -60,7 +60,7 @@ wrap(const relocation_iterator *SI) {
// ObjectFile creation
LLVMObjectFileRef LLVMCreateObjectFile(LLVMMemoryBufferRef MemBuf) {
ErrorOr<ObjectFile*> ObjOrErr(ObjectFile::createObjectFile(unwrap(MemBuf)));
- ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : 0;
+ ObjectFile *Obj = ObjOrErr ? ObjOrErr.get() : nullptr;
return wrap(Obj);
}
@@ -184,13 +184,6 @@ uint64_t LLVMGetSymbolAddress(LLVMSymbolIteratorRef SI) {
return ret;
}
-uint64_t LLVMGetSymbolFileOffset(LLVMSymbolIteratorRef SI) {
- uint64_t ret;
- if (error_code ec = (*unwrap(SI))->getFileOffset(ret))
- report_fatal_error(ec.message());
- return ret;
-}
-
uint64_t LLVMGetSymbolSize(LLVMSymbolIteratorRef SI) {
uint64_t ret;
if (error_code ec = (*unwrap(SI))->getSize(ret))
diff --git a/lib/Object/StringTableBuilder.cpp b/lib/Object/StringTableBuilder.cpp
new file mode 100644
index 0000000..9152834
--- /dev/null
+++ b/lib/Object/StringTableBuilder.cpp
@@ -0,0 +1,51 @@
+//===-- StringTableBuilder.cpp - String table building utility ------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Object/StringTableBuilder.h"
+
+using namespace llvm;
+
+static bool compareBySuffix(StringRef a, StringRef b) {
+ size_t sizeA = a.size();
+ size_t sizeB = b.size();
+ size_t len = std::min(sizeA, sizeB);
+ for (size_t i = 0; i < len; ++i) {
+ char ca = a[sizeA - i - 1];
+ char cb = b[sizeB - i - 1];
+ if (ca != cb)
+ return ca > cb;
+ }
+ return sizeA > sizeB;
+}
+
+void StringTableBuilder::finalize() {
+ SmallVector<StringRef, 8> Strings;
+ for (auto i = StringIndexMap.begin(), e = StringIndexMap.end(); i != e; ++i)
+ Strings.push_back(i->getKey());
+
+ std::sort(Strings.begin(), Strings.end(), compareBySuffix);
+
+ // FIXME: Starting with a null byte is ELF specific. Generalize this so we
+ // can use the class with other object formats.
+ StringTable += '\x00';
+
+ StringRef Previous;
+ for (StringRef s : Strings) {
+ if (Previous.endswith(s)) {
+ StringIndexMap[s] = StringTable.size() - 1 - s.size();
+ continue;
+ }
+
+ StringIndexMap[s] = StringTable.size();
+ StringTable += s;
+ StringTable += '\x00';
+ Previous = s;
+ }
+}