123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- //===- 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/Mangler.h"
- #include "llvm/IR/Module.h"
- #include "llvm/Object/IRObjectFile.h"
- #include "llvm/Support/raw_ostream.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());
- // If we have a DataLayout, setup a mangler.
- const DataLayout *DL = M->getDataLayout();
- if (!DL)
- return;
- Mang.reset(new Mangler(DL));
- }
- 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 {
- const GlobalValue &GV = getGV(Symb);
- if (Mang)
- Mang->getNameWithPrefix(OS, &GV, false);
- else
- 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())
- 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;
- std::unique_ptr<IRObjectFile> Ret(
- new IRObjectFile(Object, EC, Context, BufferOwned));
- if (EC)
- return EC;
- return Ret.release();
- }
|