aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Object
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Object')
-rw-r--r--lib/Object/Archive.cpp14
-rw-r--r--lib/Object/Binary.cpp37
-rw-r--r--lib/Object/CMakeLists.txt3
-rw-r--r--lib/Object/COFFObjectFile.cpp11
-rw-r--r--lib/Object/COFFYAML.cpp281
-rw-r--r--lib/Object/ELFObjectFile.cpp2
-rw-r--r--lib/Object/ELFYAML.cpp229
-rw-r--r--lib/Object/MachOObjectFile.cpp70
-rw-r--r--lib/Object/Object.cpp5
-rw-r--r--lib/Object/ObjectFile.cpp58
-rw-r--r--lib/Object/YAML.cpp62
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);
+ }
+}