diff options
author | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
---|---|---|
committer | Stephen Hines <srhines@google.com> | 2014-05-29 02:49:00 -0700 |
commit | dce4a407a24b04eebc6a376f8e62b41aaa7b071f (patch) | |
tree | dcebc53f2b182f145a2e659393bf9a0472cedf23 /lib/Object | |
parent | 220b921aed042f9e520c26cffd8282a94c66c3d5 (diff) | |
download | external_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.mk | 1 | ||||
-rw-r--r-- | lib/Object/Archive.cpp | 21 | ||||
-rw-r--r-- | lib/Object/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 55 | ||||
-rw-r--r-- | lib/Object/COFFYAML.cpp | 33 | ||||
-rw-r--r-- | lib/Object/ELF.cpp | 10 | ||||
-rw-r--r-- | lib/Object/ELFYAML.cpp | 429 | ||||
-rw-r--r-- | lib/Object/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 135 | ||||
-rw-r--r-- | lib/Object/MachOUniversal.cpp | 22 | ||||
-rw-r--r-- | lib/Object/Object.cpp | 9 | ||||
-rw-r--r-- | lib/Object/StringTableBuilder.cpp | 51 |
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; + } +} |