summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/Object/Archive.cpp5
-rw-r--r--llvm/lib/Object/Binary.cpp10
-rw-r--r--llvm/lib/Object/CMakeLists.txt2
-rw-r--r--llvm/lib/Object/COFFObjectFile.cpp12
-rw-r--r--llvm/lib/Object/IRObjectFile.cpp139
-rw-r--r--llvm/lib/Object/LLVMBuild.txt2
-rw-r--r--llvm/lib/Object/MachOObjectFile.cpp12
-rw-r--r--llvm/lib/Object/ObjectFile.cpp11
-rw-r--r--llvm/lib/Object/SymbolicFile.cpp67
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");
+}
OpenPOWER on IntegriCloud