diff options
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Object/Archive.cpp | 5 | ||||
-rw-r--r-- | llvm/lib/Object/Binary.cpp | 10 | ||||
-rw-r--r-- | llvm/lib/Object/CMakeLists.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Object/COFFObjectFile.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Object/IRObjectFile.cpp | 139 | ||||
-rw-r--r-- | llvm/lib/Object/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | llvm/lib/Object/MachOObjectFile.cpp | 12 | ||||
-rw-r--r-- | llvm/lib/Object/ObjectFile.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Object/SymbolicFile.cpp | 67 |
9 files changed, 239 insertions, 21 deletions
diff --git a/llvm/lib/Object/Archive.cpp b/llvm/lib/Object/Archive.cpp index 286e9eebab3..99bc4a5a3b3 100644 --- a/llvm/lib/Object/Archive.cpp +++ b/llvm/lib/Object/Archive.cpp @@ -182,12 +182,13 @@ error_code Archive::Child::getMemoryBuffer(OwningPtr<MemoryBuffer> &Result, return error_code::success(); } -error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result) const { +error_code Archive::Child::getAsBinary(OwningPtr<Binary> &Result, + LLVMContext *Context) const { OwningPtr<Binary> ret; OwningPtr<MemoryBuffer> Buff; if (error_code ec = getMemoryBuffer(Buff)) return ec; - ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.take()); + ErrorOr<Binary *> BinaryOrErr = createBinary(Buff.take(), Context); if (error_code EC = BinaryOrErr.getError()) return EC; Result.reset(BinaryOrErr.get()); diff --git a/llvm/lib/Object/Binary.cpp b/llvm/lib/Object/Binary.cpp index 63898d277f3..c7f868fcdd1 100644 --- a/llvm/lib/Object/Binary.cpp +++ b/llvm/lib/Object/Binary.cpp @@ -42,10 +42,9 @@ StringRef Binary::getFileName() const { } ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source, - sys::fs::file_magic Type) { + LLVMContext *Context) { OwningPtr<MemoryBuffer> scopedSource(Source); - if (Type == sys::fs::file_magic::unknown) - Type = sys::fs::identify_magic(Source->getBuffer()); + sys::fs::file_magic Type = sys::fs::identify_magic(Source->getBuffer()); switch (Type) { case sys::fs::file_magic::archive: @@ -67,11 +66,12 @@ ErrorOr<Binary *> object::createBinary(MemoryBuffer *Source, case sys::fs::file_magic::coff_object: case sys::fs::file_magic::coff_import_library: case sys::fs::file_magic::pecoff_executable: - return ObjectFile::createObjectFile(scopedSource.take(), true, Type); + case sys::fs::file_magic::bitcode: + return ObjectFile::createSymbolicFile(scopedSource.take(), true, Type, + Context); case sys::fs::file_magic::macho_universal_binary: return MachOUniversalBinary::create(scopedSource.take()); case sys::fs::file_magic::unknown: - case sys::fs::file_magic::bitcode: case sys::fs::file_magic::windows_resource: // Unrecognized object file format. return object_error::invalid_file_type; diff --git a/llvm/lib/Object/CMakeLists.txt b/llvm/lib/Object/CMakeLists.txt index 1f07cbba77d..dc182966ae6 100644 --- a/llvm/lib/Object/CMakeLists.txt +++ b/llvm/lib/Object/CMakeLists.txt @@ -7,9 +7,11 @@ add_llvm_library(LLVMObject ELFObjectFile.cpp ELFYAML.cpp Error.cpp + IRObjectFile.cpp MachOObjectFile.cpp MachOUniversal.cpp Object.cpp ObjectFile.cpp + SymbolicFile.cpp YAML.cpp ) diff --git a/llvm/lib/Object/COFFObjectFile.cpp b/llvm/lib/Object/COFFObjectFile.cpp index 5dcb1749861..ed5494dc394 100644 --- a/llvm/lib/Object/COFFObjectFile.cpp +++ b/llvm/lib/Object/COFFObjectFile.cpp @@ -549,17 +549,17 @@ COFFObjectFile::COFFObjectFile(MemoryBuffer *Object, error_code &EC, EC = object_error::success; } -symbol_iterator COFFObjectFile::symbol_begin() const { +basic_symbol_iterator COFFObjectFile::symbol_begin_impl() const { DataRefImpl Ret; Ret.p = reinterpret_cast<uintptr_t>(SymbolTable); - return symbol_iterator(SymbolRef(Ret, this)); + return basic_symbol_iterator(SymbolRef(Ret, this)); } -symbol_iterator COFFObjectFile::symbol_end() const { +basic_symbol_iterator COFFObjectFile::symbol_end_impl() const { // The symbol table ends where the string table begins. DataRefImpl Ret; Ret.p = reinterpret_cast<uintptr_t>(StringTable); - return symbol_iterator(SymbolRef(Ret, this)); + return basic_symbol_iterator(SymbolRef(Ret, this)); } library_iterator COFFObjectFile::needed_library_begin() const { @@ -832,8 +832,8 @@ const coff_symbol *COFFObjectFile::getCOFFSymbol(symbol_iterator &It) const { return toSymb(It->getRawDataRefImpl()); } -const coff_relocation *COFFObjectFile::getCOFFRelocation( - relocation_iterator &It) const { +const coff_relocation * +COFFObjectFile::getCOFFRelocation(relocation_iterator &It) const { return toRel(It->getRawDataRefImpl()); } diff --git a/llvm/lib/Object/IRObjectFile.cpp b/llvm/lib/Object/IRObjectFile.cpp new file mode 100644 index 00000000000..fb511ca28f8 --- /dev/null +++ b/llvm/lib/Object/IRObjectFile.cpp @@ -0,0 +1,139 @@ +//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Part of the IRObjectFile class implementation. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/IR/LLVMContext.h" +#include "llvm/IR/Module.h" +#include "llvm/Object/IRObjectFile.h" +using namespace llvm; +using namespace object; + +IRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC, + LLVMContext &Context, bool BufferOwned) + : SymbolicFile(Binary::ID_IR, Object, BufferOwned) { + ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context); + if ((EC = MOrErr.getError())) + return; + + M.reset(MOrErr.get()); +} + +static const GlobalValue &getGV(DataRefImpl &Symb) { + return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); +} + +static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { + if (I == M.alias_end()) + return 3; + const GlobalValue *GV = &*I; + return reinterpret_cast<uintptr_t>(GV) | 2; +} + +static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { + if (I == M.global_end()) + return skipEmpty(M.alias_begin(), M); + const GlobalValue *GV = &*I; + return reinterpret_cast<uintptr_t>(GV) | 1; +} + +static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { + if (I == M.end()) + return skipEmpty(M.global_begin(), M); + const GlobalValue *GV = &*I; + return reinterpret_cast<uintptr_t>(GV) | 0; +} + +void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { + const GlobalValue *GV = &getGV(Symb); + const Module &M = *GV->getParent(); + uintptr_t Res; + switch (Symb.p & 3) { + case 0: { + Module::const_iterator Iter(static_cast<const Function*>(GV)); + ++Iter; + Res = skipEmpty(Iter, M); + break; + } + case 1: { + Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); + ++Iter; + Res = skipEmpty(Iter, M); + break; + } + case 2: { + Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); + ++Iter; + Res = skipEmpty(Iter, M); + break; + } + case 3: + llvm_unreachable("Invalid symbol reference"); + } + + Symb.p = Res; +} + +error_code IRObjectFile::printSymbolName(raw_ostream &OS, + DataRefImpl Symb) const { + // FIXME: This should use the Mangler. + const GlobalValue &GV = getGV(Symb); + OS << GV.getName(); + return object_error::success; +} + +uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { + const GlobalValue &GV = getGV(Symb); + + uint32_t Res = BasicSymbolRef::SF_None; + if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage()) + Res |= BasicSymbolRef::SF_Undefined; + if (GV.hasPrivateLinkage() || GV.hasLinkerPrivateLinkage() || + GV.hasLinkerPrivateWeakLinkage()) + Res |= BasicSymbolRef::SF_FormatSpecific; + if (!GV.hasLocalLinkage()) + Res |= BasicSymbolRef::SF_Global; + if (GV.hasCommonLinkage()) + Res |= BasicSymbolRef::SF_Common; + if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage()) + Res |= BasicSymbolRef::SF_Weak; + + return Res; +} + +const GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const { + const GlobalValue &GV = getGV(Symb); + return GV; +} + +basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { + Module::const_iterator I = M->begin(); + DataRefImpl Ret; + Ret.p = skipEmpty(I, *M); + return basic_symbol_iterator(BasicSymbolRef(Ret, this)); +} + +basic_symbol_iterator IRObjectFile::symbol_end_impl() const { + DataRefImpl Ret; + Ret.p = 3; + return basic_symbol_iterator(BasicSymbolRef(Ret, this)); +} + +ErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile( + MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) { + error_code EC; + OwningPtr<IRObjectFile> Ret( + new IRObjectFile(Object, EC, Context, BufferOwned)); + if (EC) + return EC; + return Ret.take(); +} diff --git a/llvm/lib/Object/LLVMBuild.txt b/llvm/lib/Object/LLVMBuild.txt index 69610f991fd..a87da6e5f42 100644 --- a/llvm/lib/Object/LLVMBuild.txt +++ b/llvm/lib/Object/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Library name = Object parent = Libraries -required_libraries = Support +required_libraries = Support BitReader diff --git a/llvm/lib/Object/MachOObjectFile.cpp b/llvm/lib/Object/MachOObjectFile.cpp index 23c2d6d8bda..09fe6a7571e 100644 --- a/llvm/lib/Object/MachOObjectFile.cpp +++ b/llvm/lib/Object/MachOObjectFile.cpp @@ -1163,20 +1163,20 @@ error_code MachOObjectFile::getLibraryPath(DataRefImpl LibData, report_fatal_error("Needed libraries unimplemented in MachOObjectFile"); } -symbol_iterator MachOObjectFile::symbol_begin() const { +basic_symbol_iterator MachOObjectFile::symbol_begin_impl() const { DataRefImpl DRI; if (!SymtabLoadCmd) - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); MachO::symtab_command Symtab = getSymtabLoadCommand(); DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Symtab.symoff)); - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); } -symbol_iterator MachOObjectFile::symbol_end() const { +basic_symbol_iterator MachOObjectFile::symbol_end_impl() const { DataRefImpl DRI; if (!SymtabLoadCmd) - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); MachO::symtab_command Symtab = getSymtabLoadCommand(); unsigned SymbolTableEntrySize = is64Bit() ? @@ -1185,7 +1185,7 @@ symbol_iterator MachOObjectFile::symbol_end() const { unsigned Offset = Symtab.symoff + Symtab.nsyms * SymbolTableEntrySize; DRI.p = reinterpret_cast<uintptr_t>(getPtr(this, Offset)); - return symbol_iterator(SymbolRef(DRI, this)); + return basic_symbol_iterator(SymbolRef(DRI, this)); } section_iterator MachOObjectFile::section_begin() const { diff --git a/llvm/lib/Object/ObjectFile.cpp b/llvm/lib/Object/ObjectFile.cpp index 2e6b9e6505a..923baa58bcd 100644 --- a/llvm/lib/Object/ObjectFile.cpp +++ b/llvm/lib/Object/ObjectFile.cpp @@ -25,7 +25,16 @@ void ObjectFile::anchor() { } ObjectFile::ObjectFile(unsigned int Type, MemoryBuffer *Source, bool BufferOwned) - : Binary(Type, Source, BufferOwned) {} + : SymbolicFile(Type, Source, BufferOwned) {} + +error_code ObjectFile::printSymbolName(raw_ostream &OS, + DataRefImpl Symb) const { + StringRef Name; + if (error_code EC = getSymbolName(Symb, Name)) + return EC; + OS << Name; + return object_error::success; +} error_code ObjectFile::getSymbolAlignment(DataRefImpl DRI, uint32_t &Result) const { diff --git a/llvm/lib/Object/SymbolicFile.cpp b/llvm/lib/Object/SymbolicFile.cpp new file mode 100644 index 00000000000..495f0b62bc5 --- /dev/null +++ b/llvm/lib/Object/SymbolicFile.cpp @@ -0,0 +1,67 @@ +//===- SymbolicFile.cpp - Interface that only provides symbols --*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file defines a file format independent SymbolicFile class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/ObjectFile.h" +#include "llvm/Object/SymbolicFile.h" +#include "llvm/Support/MemoryBuffer.h" + +using namespace llvm; +using namespace object; + +SymbolicFile::SymbolicFile(unsigned int Type, MemoryBuffer *Source, + bool BufferOwned) + : Binary(Type, Source, BufferOwned) {} + +SymbolicFile::~SymbolicFile() {} + +ErrorOr<SymbolicFile *> +SymbolicFile::createSymbolicFile(MemoryBuffer *Object, bool BufferOwned, + sys::fs::file_magic Type, + LLVMContext *Context) { + if (Type == sys::fs::file_magic::unknown) + Type = sys::fs::identify_magic(Object->getBuffer()); + + switch (Type) { + case sys::fs::file_magic::bitcode: + if (Context) + return IRObjectFile::createIRObjectFile(Object, *Context, BufferOwned); + // Fallthrough + case sys::fs::file_magic::unknown: + case sys::fs::file_magic::archive: + case sys::fs::file_magic::macho_universal_binary: + case sys::fs::file_magic::windows_resource: + if (BufferOwned) + delete Object; + return object_error::invalid_file_type; + 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: + 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: + case sys::fs::file_magic::coff_object: + case sys::fs::file_magic::coff_import_library: + case sys::fs::file_magic::pecoff_executable: + return ObjectFile::createObjectFile(Object, BufferOwned, Type); + } + llvm_unreachable("Unexpected Binary File Type"); +} |