IRObjectFile.cpp revision 36b56886974eae4f9c5ebc96befd3e7bfe5de338
121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// 321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// The LLVM Compiler Infrastructure 421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// 521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// This file is distributed under the University of Illinois Open Source 621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// License. See LICENSE.TXT for details. 721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// 821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===----------------------------------------------------------------------===// 921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// 1021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// Part of the IRObjectFile class implementation. 1121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch// 1221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch//===----------------------------------------------------------------------===// 1321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 1421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Bitcode/ReaderWriter.h" 1521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/LLVMContext.h" 1621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/Mangler.h" 1721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/IR/Module.h" 1821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Object/IRObjectFile.h" 1921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch#include "llvm/Support/raw_ostream.h" 2021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochusing namespace llvm; 2121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochusing namespace object; 2221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 2321efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochIRObjectFile::IRObjectFile(MemoryBuffer *Object, error_code &EC, 2421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch LLVMContext &Context, bool BufferOwned) 2521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch : SymbolicFile(Binary::ID_IR, Object, BufferOwned) { 2621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch ErrorOr<Module*> MOrErr = parseBitcodeFile(Object, Context); 2721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if ((EC = MOrErr.getError())) 2821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return; 2921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 3021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch M.reset(MOrErr.get()); 3121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 3221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch // If we have a DataLayout, setup a mangler. 3321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const DataLayout *DL = M->getDataLayout(); 3421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (!DL) 3521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return; 3621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 3721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Mang.reset(new Mangler(DL)); 3821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 3921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 4021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic const GlobalValue &getGV(DataRefImpl &Symb) { 4121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return *reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 4221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 4321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 4421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 4521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (I == M.alias_end()) 4621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return 3; 4721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue *GV = &*I; 4821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return reinterpret_cast<uintptr_t>(GV) | 2; 4921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 5021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 5121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 5221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (I == M.global_end()) 5321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return skipEmpty(M.alias_begin(), M); 5421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue *GV = &*I; 5521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return reinterpret_cast<uintptr_t>(GV) | 1; 5621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 5721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 5821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochstatic uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 5921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (I == M.end()) 6021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return skipEmpty(M.global_begin(), M); 6121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue *GV = &*I; 6221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return reinterpret_cast<uintptr_t>(GV) | 0; 6321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 6421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 6521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochvoid IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 6621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue *GV = &getGV(Symb); 6721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const Module &M = *GV->getParent(); 6821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch uintptr_t Res; 6921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch switch (Symb.p & 3) { 7021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case 0: { 7121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Module::const_iterator Iter(static_cast<const Function*>(GV)); 7221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch ++Iter; 7321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res = skipEmpty(Iter, M); 7421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch break; 7521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 7621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case 1: { 7721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 7821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch ++Iter; 7921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res = skipEmpty(Iter, M); 8021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch break; 8121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 8221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case 2: { 8321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 8421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch ++Iter; 8521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res = skipEmpty(Iter, M); 8621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch break; 8721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 8821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch case 3: 8921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch llvm_unreachable("Invalid symbol reference"); 9021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch } 9121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 9221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Symb.p = Res; 9321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 9421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 9521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdocherror_code IRObjectFile::printSymbolName(raw_ostream &OS, 9621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DataRefImpl Symb) const { 9721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue &GV = getGV(Symb); 9821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 9921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (Mang) 10021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Mang->getNameWithPrefix(OS, &GV, false); 10121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch else 10221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch OS << GV.getName(); 10321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 10421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return object_error::success; 10521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 10621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 10721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochuint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 10821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue &GV = getGV(Symb); 10921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 11021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch uint32_t Res = BasicSymbolRef::SF_None; 11121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GV.isDeclaration() || GV.hasAvailableExternallyLinkage()) 11221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res |= BasicSymbolRef::SF_Undefined; 11321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GV.hasPrivateLinkage()) 11421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res |= BasicSymbolRef::SF_FormatSpecific; 11521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (!GV.hasLocalLinkage()) 11621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res |= BasicSymbolRef::SF_Global; 11721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GV.hasCommonLinkage()) 11821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res |= BasicSymbolRef::SF_Common; 11921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (GV.hasLinkOnceLinkage() || GV.hasWeakLinkage()) 12021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Res |= BasicSymbolRef::SF_Weak; 12121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 12221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return Res; 12321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 12421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 12521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochconst GlobalValue &IRObjectFile::getSymbolGV(DataRefImpl Symb) const { 12621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch const GlobalValue &GV = getGV(Symb); 12721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return GV; 12821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 12921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 13021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochbasic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 13121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Module::const_iterator I = M->begin(); 13221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DataRefImpl Ret; 13321efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Ret.p = skipEmpty(I, *M); 13421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 13521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 13621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 13721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdochbasic_symbol_iterator IRObjectFile::symbol_end_impl() const { 13821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch DataRefImpl Ret; 13921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch Ret.p = 3; 14021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 14121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 14221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch 14321efce637eb329c94f1323b6a2334a1c977e1a9dBen MurdochErrorOr<SymbolicFile *> llvm::object::SymbolicFile::createIRObjectFile( 14421efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch MemoryBuffer *Object, LLVMContext &Context, bool BufferOwned) { 14521efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch error_code EC; 14621efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch std::unique_ptr<IRObjectFile> Ret( 14721efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch new IRObjectFile(Object, EC, Context, BufferOwned)); 14821efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch if (EC) 14921efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return EC; 15021efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch return Ret.release(); 15121efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch} 15221efce637eb329c94f1323b6a2334a1c977e1a9dBen Murdoch