diff options
Diffstat (limited to 'lib/Object')
-rw-r--r-- | lib/Object/Archive.cpp | 14 | ||||
-rw-r--r-- | lib/Object/Binary.cpp | 37 | ||||
-rw-r--r-- | lib/Object/CMakeLists.txt | 3 | ||||
-rw-r--r-- | lib/Object/COFFObjectFile.cpp | 11 | ||||
-rw-r--r-- | lib/Object/COFFYAML.cpp | 281 | ||||
-rw-r--r-- | lib/Object/ELFObjectFile.cpp | 2 | ||||
-rw-r--r-- | lib/Object/ELFYAML.cpp | 229 | ||||
-rw-r--r-- | lib/Object/MachOObjectFile.cpp | 70 | ||||
-rw-r--r-- | lib/Object/Object.cpp | 5 | ||||
-rw-r--r-- | lib/Object/ObjectFile.cpp | 58 | ||||
-rw-r--r-- | lib/Object/YAML.cpp | 62 |
11 files changed, 692 insertions, 80 deletions
diff --git a/lib/Object/Archive.cpp b/lib/Object/Archive.cpp index 0e13d0540f..be35924062 100644 --- a/lib/Object/Archive.cpp +++ b/lib/Object/Archive.cpp @@ -132,8 +132,11 @@ Archive::Archive(MemoryBuffer *source, error_code &ec) // COFF archive format // First member : / // Second member : / (provides a directory of symbols) - // Third member : // contains the string table, this is present even if the - // string table is empty + // Third member : // (may exist, if it exists, contains the string table) + // Note: Microsoft PE/COFF Spec 8.3 says that the third member is present + // even if the string table is empty. However, lib.exe does not in fact + // seem to create the third member if there's no member whose filename + // exceeds 15 characters. So the third member is optional. if (name == "/") { SymbolTable = i; StringTable = e; @@ -150,14 +153,17 @@ Archive::Archive(MemoryBuffer *source, error_code &ec) Format = K_GNU; StringTable = i; ++i; - } else { + } else { Format = K_COFF; if (i != e) { SymbolTable = i; ++i; } if (i != e) { - StringTable = i; + if ((ec = i->getName(name))) + return; + if (name == "//") + StringTable = i; } } } else if (name == "__.SYMDEF") { diff --git a/lib/Object/Binary.cpp b/lib/Object/Binary.cpp index 4e528d8ea5..201899ffe2 100644 --- a/lib/Object/Binary.cpp +++ b/lib/Object/Binary.cpp @@ -14,6 +14,7 @@ #include "llvm/Object/Binary.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" // Include headers for createBinary. @@ -45,22 +46,19 @@ error_code object::createBinary(MemoryBuffer *Source, OwningPtr<MemoryBuffer> scopedSource(Source); if (!Source) return make_error_code(errc::invalid_argument); - if (Source->getBufferSize() < 64) - return object_error::invalid_file_type; - sys::LLVMFileType type = sys::IdentifyFileType(Source->getBufferStart(), - static_cast<unsigned>(Source->getBufferSize())); + sys::fs::file_magic type = sys::fs::identify_magic(Source->getBuffer()); error_code ec; switch (type) { - case sys::Archive_FileType: { + case sys::fs::file_magic::archive: { OwningPtr<Binary> ret(new Archive(scopedSource.take(), ec)); if (ec) return ec; Result.swap(ret); return object_error::success; } - case sys::ELF_Relocatable_FileType: - case sys::ELF_Executable_FileType: - case sys::ELF_SharedObject_FileType: - case sys::ELF_Core_FileType: { + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::elf_executable: + case sys::fs::file_magic::elf_shared_object: + case sys::fs::file_magic::elf_core: { OwningPtr<Binary> ret( ObjectFile::createELFObjectFile(scopedSource.take())); if (!ret) @@ -68,15 +66,15 @@ error_code object::createBinary(MemoryBuffer *Source, Result.swap(ret); return object_error::success; } - case sys::Mach_O_Object_FileType: - case sys::Mach_O_Executable_FileType: - case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: - case sys::Mach_O_Core_FileType: - case sys::Mach_O_PreloadExecutable_FileType: - case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: - case sys::Mach_O_DynamicLinker_FileType: - case sys::Mach_O_Bundle_FileType: - case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: { + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::macho_executable: + case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: + case sys::fs::file_magic::macho_core: + case sys::fs::file_magic::macho_preload_executable: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib: + case sys::fs::file_magic::macho_dynamic_linker: + case sys::fs::file_magic::macho_bundle: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: { OwningPtr<Binary> ret( ObjectFile::createMachOObjectFile(scopedSource.take())); if (!ret) @@ -84,7 +82,8 @@ error_code object::createBinary(MemoryBuffer *Source, Result.swap(ret); return object_error::success; } - case sys::COFF_FileType: { + case sys::fs::file_magic::coff_object: + case sys::fs::file_magic::pecoff_executable: { OwningPtr<Binary> ret(new COFFObjectFile(scopedSource.take(), ec)); if (ec) return ec; Result.swap(ret); diff --git a/lib/Object/CMakeLists.txt b/lib/Object/CMakeLists.txt index 4ed129f467..cec0e28337 100644 --- a/lib/Object/CMakeLists.txt +++ b/lib/Object/CMakeLists.txt @@ -2,9 +2,12 @@ add_llvm_library(LLVMObject Archive.cpp Binary.cpp COFFObjectFile.cpp + COFFYAML.cpp ELFObjectFile.cpp + ELFYAML.cpp Error.cpp MachOObjectFile.cpp Object.cpp ObjectFile.cpp + YAML.cpp ) diff --git a/lib/Object/COFFObjectFile.cpp b/lib/Object/COFFObjectFile.cpp index 6967a00ee2..269d87327b 100644 --- a/lib/Object/COFFObjectFile.cpp +++ b/lib/Object/COFFObjectFile.cpp @@ -714,13 +714,11 @@ error_code COFFObjectFile::getRelocationOffset(DataRefImpl Rel, Res = toRel(Rel)->VirtualAddress; return object_error::success; } -error_code COFFObjectFile::getRelocationSymbol(DataRefImpl Rel, - SymbolRef &Res) const { +symbol_iterator COFFObjectFile::getRelocationSymbol(DataRefImpl Rel) const { const coff_relocation* R = toRel(Rel); DataRefImpl Symb; Symb.p = reinterpret_cast<uintptr_t>(SymbolTable + R->SymbolTableIndex); - Res = SymbolRef(Symb, this); - return object_error::success; + return symbol_iterator(SymbolRef(Symb, this)); } error_code COFFObjectFile::getRelocationType(DataRefImpl Rel, uint64_t &Res) const { @@ -800,11 +798,6 @@ error_code COFFObjectFile::getRelocationTypeName(DataRefImpl Rel, #undef LLVM_COFF_SWITCH_RELOC_TYPE_NAME -error_code COFFObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { - Res = 0; - return object_error::success; -} error_code COFFObjectFile::getRelocationValueString(DataRefImpl Rel, SmallVectorImpl<char> &Result) const { const coff_relocation *reloc = toRel(Rel); diff --git a/lib/Object/COFFYAML.cpp b/lib/Object/COFFYAML.cpp new file mode 100644 index 0000000000..e549b4e9ea --- /dev/null +++ b/lib/Object/COFFYAML.cpp @@ -0,0 +1,281 @@ +//===- COFFYAML.cpp - COFF YAMLIO implementation --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of COFF. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/COFFYAML.h" + +#define ECase(X) IO.enumCase(Value, #X, COFF::X); +namespace llvm { + +namespace COFFYAML { +Section::Section() { memset(&Header, 0, sizeof(COFF::section)); } +Symbol::Symbol() { memset(&Header, 0, sizeof(COFF::symbol)); } +Object::Object() { memset(&Header, 0, sizeof(COFF::header)); } +} + +namespace yaml { +void ScalarEnumerationTraits<COFF::MachineTypes>::enumeration( + IO &IO, COFF::MachineTypes &Value) { + ECase(IMAGE_FILE_MACHINE_UNKNOWN); + ECase(IMAGE_FILE_MACHINE_AM33); + ECase(IMAGE_FILE_MACHINE_AMD64); + ECase(IMAGE_FILE_MACHINE_ARM); + ECase(IMAGE_FILE_MACHINE_ARMV7); + ECase(IMAGE_FILE_MACHINE_EBC); + ECase(IMAGE_FILE_MACHINE_I386); + ECase(IMAGE_FILE_MACHINE_IA64); + ECase(IMAGE_FILE_MACHINE_M32R); + ECase(IMAGE_FILE_MACHINE_MIPS16); + ECase(IMAGE_FILE_MACHINE_MIPSFPU); + ECase(IMAGE_FILE_MACHINE_MIPSFPU16); + ECase(IMAGE_FILE_MACHINE_POWERPC); + ECase(IMAGE_FILE_MACHINE_POWERPCFP); + ECase(IMAGE_FILE_MACHINE_R4000); + ECase(IMAGE_FILE_MACHINE_SH3); + ECase(IMAGE_FILE_MACHINE_SH3DSP); + ECase(IMAGE_FILE_MACHINE_SH4); + ECase(IMAGE_FILE_MACHINE_SH5); + ECase(IMAGE_FILE_MACHINE_THUMB); + ECase(IMAGE_FILE_MACHINE_WCEMIPSV2); +} + +void ScalarEnumerationTraits<COFF::SymbolBaseType>::enumeration( + IO &IO, COFF::SymbolBaseType &Value) { + ECase(IMAGE_SYM_TYPE_NULL); + ECase(IMAGE_SYM_TYPE_VOID); + ECase(IMAGE_SYM_TYPE_CHAR); + ECase(IMAGE_SYM_TYPE_SHORT); + ECase(IMAGE_SYM_TYPE_INT); + ECase(IMAGE_SYM_TYPE_LONG); + ECase(IMAGE_SYM_TYPE_FLOAT); + ECase(IMAGE_SYM_TYPE_DOUBLE); + ECase(IMAGE_SYM_TYPE_STRUCT); + ECase(IMAGE_SYM_TYPE_UNION); + ECase(IMAGE_SYM_TYPE_ENUM); + ECase(IMAGE_SYM_TYPE_MOE); + ECase(IMAGE_SYM_TYPE_BYTE); + ECase(IMAGE_SYM_TYPE_WORD); + ECase(IMAGE_SYM_TYPE_UINT); + ECase(IMAGE_SYM_TYPE_DWORD); +} + +void ScalarEnumerationTraits<COFF::SymbolStorageClass>::enumeration( + IO &IO, COFF::SymbolStorageClass &Value) { + ECase(IMAGE_SYM_CLASS_END_OF_FUNCTION); + ECase(IMAGE_SYM_CLASS_NULL); + ECase(IMAGE_SYM_CLASS_AUTOMATIC); + ECase(IMAGE_SYM_CLASS_EXTERNAL); + ECase(IMAGE_SYM_CLASS_STATIC); + ECase(IMAGE_SYM_CLASS_REGISTER); + ECase(IMAGE_SYM_CLASS_EXTERNAL_DEF); + ECase(IMAGE_SYM_CLASS_LABEL); + ECase(IMAGE_SYM_CLASS_UNDEFINED_LABEL); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_STRUCT); + ECase(IMAGE_SYM_CLASS_ARGUMENT); + ECase(IMAGE_SYM_CLASS_STRUCT_TAG); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_UNION); + ECase(IMAGE_SYM_CLASS_UNION_TAG); + ECase(IMAGE_SYM_CLASS_TYPE_DEFINITION); + ECase(IMAGE_SYM_CLASS_UNDEFINED_STATIC); + ECase(IMAGE_SYM_CLASS_ENUM_TAG); + ECase(IMAGE_SYM_CLASS_MEMBER_OF_ENUM); + ECase(IMAGE_SYM_CLASS_REGISTER_PARAM); + ECase(IMAGE_SYM_CLASS_BIT_FIELD); + ECase(IMAGE_SYM_CLASS_BLOCK); + ECase(IMAGE_SYM_CLASS_FUNCTION); + ECase(IMAGE_SYM_CLASS_END_OF_STRUCT); + ECase(IMAGE_SYM_CLASS_FILE); + ECase(IMAGE_SYM_CLASS_SECTION); + ECase(IMAGE_SYM_CLASS_WEAK_EXTERNAL); + ECase(IMAGE_SYM_CLASS_CLR_TOKEN); +} + +void ScalarEnumerationTraits<COFF::SymbolComplexType>::enumeration( + IO &IO, COFF::SymbolComplexType &Value) { + ECase(IMAGE_SYM_DTYPE_NULL); + ECase(IMAGE_SYM_DTYPE_POINTER); + ECase(IMAGE_SYM_DTYPE_FUNCTION); + ECase(IMAGE_SYM_DTYPE_ARRAY); +} + +void ScalarEnumerationTraits<COFF::RelocationTypeX86>::enumeration( + IO &IO, COFF::RelocationTypeX86 &Value) { + ECase(IMAGE_REL_I386_ABSOLUTE); + ECase(IMAGE_REL_I386_DIR16); + ECase(IMAGE_REL_I386_REL16); + ECase(IMAGE_REL_I386_DIR32); + ECase(IMAGE_REL_I386_DIR32NB); + ECase(IMAGE_REL_I386_SEG12); + ECase(IMAGE_REL_I386_SECTION); + ECase(IMAGE_REL_I386_SECREL); + ECase(IMAGE_REL_I386_TOKEN); + ECase(IMAGE_REL_I386_SECREL7); + ECase(IMAGE_REL_I386_REL32); + ECase(IMAGE_REL_AMD64_ABSOLUTE); + ECase(IMAGE_REL_AMD64_ADDR64); + ECase(IMAGE_REL_AMD64_ADDR32); + ECase(IMAGE_REL_AMD64_ADDR32NB); + ECase(IMAGE_REL_AMD64_REL32); + ECase(IMAGE_REL_AMD64_REL32_1); + ECase(IMAGE_REL_AMD64_REL32_2); + ECase(IMAGE_REL_AMD64_REL32_3); + ECase(IMAGE_REL_AMD64_REL32_4); + ECase(IMAGE_REL_AMD64_REL32_5); + ECase(IMAGE_REL_AMD64_SECTION); + ECase(IMAGE_REL_AMD64_SECREL); + ECase(IMAGE_REL_AMD64_SECREL7); + ECase(IMAGE_REL_AMD64_TOKEN); + ECase(IMAGE_REL_AMD64_SREL32); + ECase(IMAGE_REL_AMD64_PAIR); + ECase(IMAGE_REL_AMD64_SSPAN32); +} +#undef ECase + +#define BCase(X) IO.bitSetCase(Value, #X, COFF::X); +void ScalarBitSetTraits<COFF::Characteristics>::bitset( + IO &IO, COFF::Characteristics &Value) { + BCase(IMAGE_FILE_RELOCS_STRIPPED); + BCase(IMAGE_FILE_EXECUTABLE_IMAGE); + BCase(IMAGE_FILE_LINE_NUMS_STRIPPED); + BCase(IMAGE_FILE_LOCAL_SYMS_STRIPPED); + BCase(IMAGE_FILE_AGGRESSIVE_WS_TRIM); + BCase(IMAGE_FILE_LARGE_ADDRESS_AWARE); + BCase(IMAGE_FILE_BYTES_REVERSED_LO); + BCase(IMAGE_FILE_32BIT_MACHINE); + BCase(IMAGE_FILE_DEBUG_STRIPPED); + BCase(IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP); + BCase(IMAGE_FILE_NET_RUN_FROM_SWAP); + BCase(IMAGE_FILE_SYSTEM); + BCase(IMAGE_FILE_DLL); + BCase(IMAGE_FILE_UP_SYSTEM_ONLY); + BCase(IMAGE_FILE_BYTES_REVERSED_HI); +} + +void ScalarBitSetTraits<COFF::SectionCharacteristics>::bitset( + IO &IO, COFF::SectionCharacteristics &Value) { + BCase(IMAGE_SCN_TYPE_NO_PAD); + BCase(IMAGE_SCN_CNT_CODE); + BCase(IMAGE_SCN_CNT_INITIALIZED_DATA); + BCase(IMAGE_SCN_CNT_UNINITIALIZED_DATA); + BCase(IMAGE_SCN_LNK_OTHER); + BCase(IMAGE_SCN_LNK_INFO); + BCase(IMAGE_SCN_LNK_REMOVE); + BCase(IMAGE_SCN_LNK_COMDAT); + BCase(IMAGE_SCN_GPREL); + BCase(IMAGE_SCN_MEM_PURGEABLE); + BCase(IMAGE_SCN_MEM_16BIT); + BCase(IMAGE_SCN_MEM_LOCKED); + BCase(IMAGE_SCN_MEM_PRELOAD); + BCase(IMAGE_SCN_LNK_NRELOC_OVFL); + BCase(IMAGE_SCN_MEM_DISCARDABLE); + BCase(IMAGE_SCN_MEM_NOT_CACHED); + BCase(IMAGE_SCN_MEM_NOT_PAGED); + BCase(IMAGE_SCN_MEM_SHARED); + BCase(IMAGE_SCN_MEM_EXECUTE); + BCase(IMAGE_SCN_MEM_READ); + BCase(IMAGE_SCN_MEM_WRITE); +} +#undef BCase + +namespace { +struct NSectionCharacteristics { + NSectionCharacteristics(IO &) + : Characteristics(COFF::SectionCharacteristics(0)) {} + NSectionCharacteristics(IO &, uint32_t C) + : Characteristics(COFF::SectionCharacteristics(C)) {} + uint32_t denormalize(IO &) { return Characteristics; } + COFF::SectionCharacteristics Characteristics; +}; + +struct NStorageClass { + NStorageClass(IO &) : StorageClass(COFF::SymbolStorageClass(0)) {} + NStorageClass(IO &, uint8_t S) : StorageClass(COFF::SymbolStorageClass(S)) {} + uint8_t denormalize(IO &) { return StorageClass; } + + COFF::SymbolStorageClass StorageClass; +}; + +struct NMachine { + NMachine(IO &) : Machine(COFF::MachineTypes(0)) {} + NMachine(IO &, uint16_t M) : Machine(COFF::MachineTypes(M)) {} + uint16_t denormalize(IO &) { return Machine; } + COFF::MachineTypes Machine; +}; + +struct NHeaderCharacteristics { + NHeaderCharacteristics(IO &) : Characteristics(COFF::Characteristics(0)) {} + NHeaderCharacteristics(IO &, uint16_t C) + : Characteristics(COFF::Characteristics(C)) {} + uint16_t denormalize(IO &) { return Characteristics; } + + COFF::Characteristics Characteristics; +}; + +struct NType { + NType(IO &) : Type(COFF::RelocationTypeX86(0)) {} + NType(IO &, uint16_t T) : Type(COFF::RelocationTypeX86(T)) {} + uint16_t denormalize(IO &) { return Type; } + COFF::RelocationTypeX86 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); +} + +void MappingTraits<COFF::header>::mapping(IO &IO, COFF::header &H) { + MappingNormalization<NMachine, uint16_t> NM(IO, H.Machine); + MappingNormalization<NHeaderCharacteristics, uint16_t> NC(IO, + H.Characteristics); + + IO.mapRequired("Machine", NM->Machine); + IO.mapOptional("Characteristics", NC->Characteristics); +} + +void MappingTraits<COFFYAML::Symbol>::mapping(IO &IO, COFFYAML::Symbol &S) { + MappingNormalization<NStorageClass, uint8_t> NS(IO, S.Header.StorageClass); + + IO.mapRequired("Name", S.Name); + IO.mapRequired("Value", S.Header.Value); + IO.mapRequired("SectionNumber", S.Header.SectionNumber); + IO.mapRequired("SimpleType", S.SimpleType); + IO.mapRequired("ComplexType", S.ComplexType); + IO.mapRequired("StorageClass", NS->StorageClass); + IO.mapOptional("NumberOfAuxSymbols", S.Header.NumberOfAuxSymbols, + (uint8_t) 0); + IO.mapOptional("AuxiliaryData", S.AuxiliaryData, object::yaml::BinaryRef()); +} + +void MappingTraits<COFFYAML::Section>::mapping(IO &IO, COFFYAML::Section &Sec) { + MappingNormalization<NSectionCharacteristics, uint32_t> NC( + IO, Sec.Header.Characteristics); + IO.mapRequired("Name", Sec.Name); + IO.mapRequired("Characteristics", NC->Characteristics); + IO.mapOptional("Alignment", Sec.Alignment); + IO.mapRequired("SectionData", Sec.SectionData); + IO.mapOptional("Relocations", Sec.Relocations); +} + +void MappingTraits<COFFYAML::Object>::mapping(IO &IO, COFFYAML::Object &Obj) { + IO.mapRequired("header", Obj.Header); + IO.mapRequired("sections", Obj.Sections); + IO.mapRequired("symbols", Obj.Symbols); +} + +} +} diff --git a/lib/Object/ELFObjectFile.cpp b/lib/Object/ELFObjectFile.cpp index 62626d7c71..a6c128e2b3 100644 --- a/lib/Object/ELFObjectFile.cpp +++ b/lib/Object/ELFObjectFile.cpp @@ -26,7 +26,7 @@ ObjectFile *ObjectFile::createELFObjectFile(MemoryBuffer *Object) { error_code ec; std::size_t MaxAlignment = - 1ULL << CountTrailingZeros_64(uintptr_t(Object->getBufferStart())); + 1ULL << countTrailingZeros(uintptr_t(Object->getBufferStart())); if (Ident.first == ELF::ELFCLASS32 && Ident.second == ELF::ELFDATA2LSB) #if !LLVM_IS_UNALIGNED_ACCESS_FAST diff --git a/lib/Object/ELFYAML.cpp b/lib/Object/ELFYAML.cpp new file mode 100644 index 0000000000..967fd2b272 --- /dev/null +++ b/lib/Object/ELFYAML.cpp @@ -0,0 +1,229 @@ +//===- ELFYAML.cpp - ELF YAMLIO implementation ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines classes for handling the YAML representation of ELF. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/ELFYAML.h" + +namespace llvm { +namespace yaml { + +void +ScalarEnumerationTraits<ELFYAML::ELF_ET>::enumeration(IO &IO, + ELFYAML::ELF_ET &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X); + ECase(ET_NONE) + ECase(ET_REL) + ECase(ET_EXEC) + ECase(ET_DYN) + ECase(ET_CORE) +#undef ECase +} + +void +ScalarEnumerationTraits<ELFYAML::ELF_EM>::enumeration(IO &IO, + ELFYAML::ELF_EM &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X); + ECase(EM_NONE) + ECase(EM_M32) + ECase(EM_SPARC) + ECase(EM_386) + ECase(EM_68K) + ECase(EM_88K) + ECase(EM_486) + ECase(EM_860) + ECase(EM_MIPS) + ECase(EM_S370) + ECase(EM_MIPS_RS3_LE) + ECase(EM_PARISC) + ECase(EM_VPP500) + ECase(EM_SPARC32PLUS) + ECase(EM_960) + ECase(EM_PPC) + ECase(EM_PPC64) + ECase(EM_S390) + ECase(EM_SPU) + ECase(EM_V800) + ECase(EM_FR20) + ECase(EM_RH32) + ECase(EM_RCE) + ECase(EM_ARM) + ECase(EM_ALPHA) + ECase(EM_SH) + ECase(EM_SPARCV9) + ECase(EM_TRICORE) + ECase(EM_ARC) + ECase(EM_H8_300) + ECase(EM_H8_300H) + ECase(EM_H8S) + ECase(EM_H8_500) + ECase(EM_IA_64) + ECase(EM_MIPS_X) + ECase(EM_COLDFIRE) + ECase(EM_68HC12) + ECase(EM_MMA) + ECase(EM_PCP) + ECase(EM_NCPU) + ECase(EM_NDR1) + ECase(EM_STARCORE) + ECase(EM_ME16) + ECase(EM_ST100) + ECase(EM_TINYJ) + ECase(EM_X86_64) + ECase(EM_PDSP) + ECase(EM_PDP10) + ECase(EM_PDP11) + ECase(EM_FX66) + ECase(EM_ST9PLUS) + ECase(EM_ST7) + ECase(EM_68HC16) + ECase(EM_68HC11) + ECase(EM_68HC08) + ECase(EM_68HC05) + ECase(EM_SVX) + ECase(EM_ST19) + ECase(EM_VAX) + ECase(EM_CRIS) + ECase(EM_JAVELIN) + ECase(EM_FIREPATH) + ECase(EM_ZSP) + ECase(EM_MMIX) + ECase(EM_HUANY) + ECase(EM_PRISM) + ECase(EM_AVR) + ECase(EM_FR30) + ECase(EM_D10V) + ECase(EM_D30V) + ECase(EM_V850) + ECase(EM_M32R) + ECase(EM_MN10300) + ECase(EM_MN10200) + ECase(EM_PJ) + ECase(EM_OPENRISC) + ECase(EM_ARC_COMPACT) + ECase(EM_XTENSA) + ECase(EM_VIDEOCORE) + ECase(EM_TMM_GPP) + ECase(EM_NS32K) + ECase(EM_TPC) + ECase(EM_SNP1K) + ECase(EM_ST200) + ECase(EM_IP2K) + ECase(EM_MAX) + ECase(EM_CR) + ECase(EM_F2MC16) + ECase(EM_MSP430) + ECase(EM_BLACKFIN) + ECase(EM_SE_C33) + ECase(EM_SEP) + ECase(EM_ARCA) + ECase(EM_UNICORE) + ECase(EM_EXCESS) + ECase(EM_DXP) + ECase(EM_ALTERA_NIOS2) + ECase(EM_CRX) + ECase(EM_XGATE) + ECase(EM_C166) + ECase(EM_M16C) + ECase(EM_DSPIC30F) + ECase(EM_CE) + ECase(EM_M32C) + ECase(EM_TSK3000) + ECase(EM_RS08) + ECase(EM_SHARC) + ECase(EM_ECOG2) + ECase(EM_SCORE7) + ECase(EM_DSP24) + ECase(EM_VIDEOCORE3) + ECase(EM_LATTICEMICO32) + ECase(EM_SE_C17) + ECase(EM_TI_C6000) + ECase(EM_TI_C2000) + ECase(EM_TI_C5500) + ECase(EM_MMDSP_PLUS) + ECase(EM_CYPRESS_M8C) + ECase(EM_R32C) + ECase(EM_TRIMEDIA) + ECase(EM_HEXAGON) + ECase(EM_8051) + ECase(EM_STXP7X) + ECase(EM_NDS32) + ECase(EM_ECOG1) + ECase(EM_ECOG1X) + ECase(EM_MAXQ30) + ECase(EM_XIMO16) + ECase(EM_MANIK) + ECase(EM_CRAYNV2) + ECase(EM_RX) + ECase(EM_METAG) + ECase(EM_MCST_ELBRUS) + ECase(EM_ECOG16) + ECase(EM_CR16) + ECase(EM_ETPU) + ECase(EM_SLE9X) + ECase(EM_L10M) + ECase(EM_K10M) + ECase(EM_AARCH64) + ECase(EM_AVR32) + ECase(EM_STM8) + ECase(EM_TILE64) + ECase(EM_TILEPRO) + ECase(EM_MICROBLAZE) + ECase(EM_CUDA) + ECase(EM_TILEGX) + ECase(EM_CLOUDSHIELD) + ECase(EM_COREA_1ST) + ECase(EM_COREA_2ND) + ECase(EM_ARC_COMPACT2) + ECase(EM_OPEN8) + ECase(EM_RL78) + ECase(EM_VIDEOCORE5) + ECase(EM_78KOR) + ECase(EM_56800EX) + ECase(EM_MBLAZE) +#undef ECase +} + +void ScalarEnumerationTraits<ELFYAML::ELF_ELFCLASS>::enumeration( + IO &IO, ELFYAML::ELF_ELFCLASS &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X); + // Since the semantics of ELFCLASSNONE is "invalid", just don't accept it + // here. + ECase(ELFCLASS32) + ECase(ELFCLASS64) +#undef ECase +} + +void ScalarEnumerationTraits<ELFYAML::ELF_ELFDATA>::enumeration( + IO &IO, ELFYAML::ELF_ELFDATA &Value) { +#define ECase(X) IO.enumCase(Value, #X, ELF::X); + // Since the semantics of ELFDATANONE is "invalid", just don't accept it + // here. + ECase(ELFDATA2LSB) + ECase(ELFDATA2MSB) +#undef ECase +} + +void MappingTraits<ELFYAML::FileHeader>::mapping(IO &IO, + ELFYAML::FileHeader &FileHdr) { + IO.mapRequired("Class", FileHdr.Class); + IO.mapRequired("Data", FileHdr.Data); + IO.mapRequired("Type", FileHdr.Type); + IO.mapRequired("Machine", FileHdr.Machine); + IO.mapOptional("Entry", FileHdr.Entry, Hex64(0)); +} + +void MappingTraits<ELFYAML::Object>::mapping(IO &IO, ELFYAML::Object &Object) { + IO.mapRequired("FileHeader", Object.Header); +} + +} // end namespace yaml +} // end namespace llvm diff --git a/lib/Object/MachOObjectFile.cpp b/lib/Object/MachOObjectFile.cpp index dfd8d3d3dd..e62b5a4819 100644 --- a/lib/Object/MachOObjectFile.cpp +++ b/lib/Object/MachOObjectFile.cpp @@ -339,7 +339,7 @@ static void printRelocationTargetName(const MachOObjectFile *O, StringRef S; bool isExtern = O->getPlainRelocationExternal(RE); - uint64_t Val = O->getAnyRelocationAddress(RE); + uint64_t Val = O->getPlainRelocationSymbolNum(RE); if (isExtern) { symbol_iterator SI = O->begin_symbols(); @@ -347,7 +347,8 @@ static void printRelocationTargetName(const MachOObjectFile *O, SI->getName(S); } else { section_iterator SI = O->begin_sections(); - advanceTo(SI, Val); + // Adjust for the fact that sections are 1-indexed. + advanceTo(SI, Val - 1); SI->getName(S); } @@ -413,7 +414,7 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, bool IsLittleEndian, bool Is64bits, error_code &ec) : ObjectFile(getMachOType(IsLittleEndian, Is64bits), Object), - SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL) { + SymtabLoadCmd(NULL), DysymtabLoadCmd(NULL), DataInCodeLoadCmd(NULL) { uint32_t LoadCommandCount = this->getHeader().NumLoadCommands; macho::LoadCommandType SegmentLoadType = is64Bit() ? macho::LCT_Segment64 : macho::LCT_Segment; @@ -426,6 +427,9 @@ MachOObjectFile::MachOObjectFile(MemoryBuffer *Object, } else if (Load.C.Type == macho::LCT_Dysymtab) { assert(!DysymtabLoadCmd && "Multiple dynamic symbol tables"); DysymtabLoadCmd = Load.Ptr; + } else if (Load.C.Type == macho::LCT_DataInCode) { + assert(!DataInCodeLoadCmd && "Multiple data in code tables"); + DataInCodeLoadCmd = Load.Ptr; } else if (Load.C.Type == SegmentLoadType) { uint32_t NumSections = getSegmentLoadCommandNumSections(this, Load); for (unsigned J = 0; J < NumSections; ++J) { @@ -868,15 +872,13 @@ error_code MachOObjectFile::getRelocationOffset(DataRefImpl Rel, return object_error::success; } -error_code -MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { +symbol_iterator +MachOObjectFile::getRelocationSymbol(DataRefImpl Rel) const { macho::RelocationEntry RE = getRelocation(Rel); uint32_t SymbolIdx = getPlainRelocationSymbolNum(RE); bool isExtern = getPlainRelocationExternal(RE); - if (!isExtern) { - Res = *end_symbols(); - return object_error::success; - } + if (!isExtern) + return end_symbols(); macho::SymtabLoadCommand S = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? @@ -885,8 +887,7 @@ MachOObjectFile::getRelocationSymbol(DataRefImpl Rel, SymbolRef &Res) const { uint64_t Offset = S.SymbolTableOffset + SymbolIdx * SymbolTableEntrySize; DataRefImpl Sym; Sym.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); - Res = SymbolRef(Sym, this); - return object_error::success; + return symbol_iterator(SymbolRef(Sym, this)); } error_code MachOObjectFile::getRelocationType(DataRefImpl Rel, @@ -989,12 +990,6 @@ MachOObjectFile::getRelocationTypeName(DataRefImpl Rel, return object_error::success; } -error_code MachOObjectFile::getRelocationAdditionalInfo(DataRefImpl Rel, - int64_t &Res) const { - Res = 0; - return object_error::success; -} - error_code MachOObjectFile::getRelocationValueString(DataRefImpl Rel, SmallVectorImpl<char> &Result) const { @@ -1336,6 +1331,27 @@ relocation_iterator MachOObjectFile::getSectionRelEnd(unsigned Index) const { return getSectionRelEnd(DRI); } +dice_iterator MachOObjectFile::begin_dices() const { + DataRefImpl DRI; + if (!DataInCodeLoadCmd) + return dice_iterator(DiceRef(DRI, this)); + + macho::LinkeditDataLoadCommand DicLC = getDataInCodeLoadCommand(); + DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, DicLC.DataOffset)); + return dice_iterator(DiceRef(DRI, this)); +} + +dice_iterator MachOObjectFile::end_dices() const { + DataRefImpl DRI; + if (!DataInCodeLoadCmd) + return dice_iterator(DiceRef(DRI, this)); + + macho::LinkeditDataLoadCommand DicLC = getDataInCodeLoadCommand(); + unsigned Offset = DicLC.DataOffset + DicLC.DataSize; + DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); + return dice_iterator(DiceRef(DRI, this)); +} + StringRef MachOObjectFile::getSectionFinalSegmentName(DataRefImpl Sec) const { ArrayRef<char> Raw = getSectionRawFinalSegmentName(Sec); @@ -1500,6 +1516,12 @@ MachOObjectFile::getRelocation(DataRefImpl Rel) const { return getStruct<macho::RelocationEntry>(this, P); } +macho::DataInCodeTableEntry +MachOObjectFile::getDice(DataRefImpl Rel) const { + const char *P = reinterpret_cast<const char *>(Rel.p); + return getStruct<macho::DataInCodeTableEntry>(this, P); +} + macho::Header MachOObjectFile::getHeader() const { return getStruct<macho::Header>(this, getPtr(this, 0)); } @@ -1532,6 +1554,20 @@ macho::DysymtabLoadCommand MachOObjectFile::getDysymtabLoadCommand() const { return getStruct<macho::DysymtabLoadCommand>(this, DysymtabLoadCmd); } +macho::LinkeditDataLoadCommand +MachOObjectFile::getDataInCodeLoadCommand() const { + if (DataInCodeLoadCmd) + return getStruct<macho::LinkeditDataLoadCommand>(this, DataInCodeLoadCmd); + + // If there is no DataInCodeLoadCmd return a load command with zero'ed fields. + macho::LinkeditDataLoadCommand Cmd; + Cmd.Type = macho::LCT_DataInCode; + Cmd.Size = macho::LinkeditLoadCommandSize; + Cmd.DataOffset = 0; + Cmd.DataSize = 0; + return Cmd; +} + StringRef MachOObjectFile::getStringTableData() const { macho::SymtabLoadCommand S = getSymtabLoadCommand(); return getData().substr(S.StringTableOffset, S.StringTableSize); diff --git a/lib/Object/Object.cpp b/lib/Object/Object.cpp index 3e2c78ec47..6941708dd3 100644 --- a/lib/Object/Object.cpp +++ b/lib/Object/Object.cpp @@ -219,10 +219,7 @@ uint64_t LLVMGetRelocationOffset(LLVMRelocationIteratorRef RI) { } LLVMSymbolIteratorRef LLVMGetRelocationSymbol(LLVMRelocationIteratorRef RI) { - SymbolRef ret; - if (error_code ec = (*unwrap(RI))->getSymbol(ret)) - report_fatal_error(ec.message()); - + symbol_iterator ret = (*unwrap(RI))->getSymbol(); return wrap(new symbol_iterator(ret)); } diff --git a/lib/Object/ObjectFile.cpp b/lib/Object/ObjectFile.cpp index 77fd995cf0..3ec29bf7e7 100644 --- a/lib/Object/ObjectFile.cpp +++ b/lib/Object/ObjectFile.cpp @@ -14,8 +14,8 @@ #include "llvm/Object/ObjectFile.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" #include "llvm/Support/system_error.h" using namespace llvm; @@ -33,35 +33,41 @@ error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI, return object_error::success; } +section_iterator ObjectFile::getRelocatedSection(DataRefImpl Sec) const { + return section_iterator(SectionRef(Sec, this)); +} + ObjectFile *ObjectFile::createObjectFile(MemoryBuffer *Object) { if (!Object || Object->getBufferSize() < 64) return 0; - sys::LLVMFileType type = sys::IdentifyFileType(Object->getBufferStart(), - static_cast<unsigned>(Object->getBufferSize())); - switch (type) { - case sys::Unknown_FileType: - return 0; - case sys::ELF_Relocatable_FileType: - case sys::ELF_Executable_FileType: - case sys::ELF_SharedObject_FileType: - case sys::ELF_Core_FileType: - return createELFObjectFile(Object); - case sys::Mach_O_Object_FileType: - case sys::Mach_O_Executable_FileType: - case sys::Mach_O_FixedVirtualMemorySharedLib_FileType: - case sys::Mach_O_Core_FileType: - case sys::Mach_O_PreloadExecutable_FileType: - case sys::Mach_O_DynamicallyLinkedSharedLib_FileType: - case sys::Mach_O_DynamicLinker_FileType: - case sys::Mach_O_Bundle_FileType: - case sys::Mach_O_DynamicallyLinkedSharedLibStub_FileType: - case sys::Mach_O_DSYMCompanion_FileType: - return createMachOObjectFile(Object); - case sys::COFF_FileType: - return createCOFFObjectFile(Object); - default: - llvm_unreachable("Unexpected Object File Type"); + + sys::fs::file_magic Type = sys::fs::identify_magic(Object->getBuffer()); + switch (Type) { + case sys::fs::file_magic::unknown: + case sys::fs::file_magic::bitcode: + case sys::fs::file_magic::archive: + return 0; + case sys::fs::file_magic::elf_relocatable: + case sys::fs::file_magic::elf_executable: + case sys::fs::file_magic::elf_shared_object: + case sys::fs::file_magic::elf_core: + return createELFObjectFile(Object); + case sys::fs::file_magic::macho_object: + case sys::fs::file_magic::macho_executable: + case sys::fs::file_magic::macho_fixed_virtual_memory_shared_lib: + case sys::fs::file_magic::macho_core: + case sys::fs::file_magic::macho_preload_executable: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib: + case sys::fs::file_magic::macho_dynamic_linker: + case sys::fs::file_magic::macho_bundle: + case sys::fs::file_magic::macho_dynamically_linked_shared_lib_stub: + case sys::fs::file_magic::macho_dsym_companion: + return createMachOObjectFile(Object); + case sys::fs::file_magic::coff_object: + case sys::fs::file_magic::pecoff_executable: + return createCOFFObjectFile(Object); } + llvm_unreachable("Unexpected Object File Type"); } ObjectFile *ObjectFile::createObjectFile(StringRef ObjectPath) { diff --git a/lib/Object/YAML.cpp b/lib/Object/YAML.cpp new file mode 100644 index 0000000000..4e7f089098 --- /dev/null +++ b/lib/Object/YAML.cpp @@ -0,0 +1,62 @@ +//===- YAML.cpp - YAMLIO utilities for object files -----------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines utility classes for handling the YAML representation of +// object files. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/YAML.h" +#include "llvm/Support/raw_ostream.h" + +using namespace llvm; +using namespace object::yaml; + +void yaml::ScalarTraits<object::yaml::BinaryRef>::output( + const object::yaml::BinaryRef &Val, void *, llvm::raw_ostream &Out) { + Val.writeAsHex(Out); +} + +StringRef yaml::ScalarTraits<object::yaml::BinaryRef>::input( + StringRef Scalar, void *, object::yaml::BinaryRef &Val) { + if (Scalar.size() % 2 != 0) + return "BinaryRef hex string must contain an even number of nybbles."; + // TODO: Can we improve YAMLIO to permit a more accurate diagnostic here? + // (e.g. a caret pointing to the offending character). + for (unsigned I = 0, N = Scalar.size(); I != N; ++I) + if (!isxdigit(Scalar[I])) + return "BinaryRef hex string must contain only hex digits."; + Val = object::yaml::BinaryRef(Scalar); + return StringRef(); +} + +void BinaryRef::writeAsBinary(raw_ostream &OS) const { + if (!DataIsHexString) { + OS.write((const char *)Data.data(), Data.size()); + return; + } + for (unsigned I = 0, N = Data.size(); I != N; I += 2) { + uint8_t Byte; + StringRef((const char *)&Data[I], 2).getAsInteger(16, Byte); + OS.write(Byte); + } +} + +void BinaryRef::writeAsHex(raw_ostream &OS) const { + if (DataIsHexString) { + OS.write((const char *)Data.data(), Data.size()); + return; + } + for (ArrayRef<uint8_t>::iterator I = Data.begin(), E = Data.end(); I != E; + ++I) { + uint8_t Byte = *I; + OS << hexdigit(Byte >> 4); + OS << hexdigit(Byte & 0xf); + } +} |