1*91bc56edSDimitry Andric //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 2*91bc56edSDimitry Andric // 3*91bc56edSDimitry Andric // The LLVM Compiler Infrastructure 4*91bc56edSDimitry Andric // 5*91bc56edSDimitry Andric // This file is distributed under the University of Illinois Open Source 6*91bc56edSDimitry Andric // License. See LICENSE.TXT for details. 7*91bc56edSDimitry Andric // 8*91bc56edSDimitry Andric //===----------------------------------------------------------------------===// 9*91bc56edSDimitry Andric // 10*91bc56edSDimitry Andric // Part of the IRObjectFile class implementation. 11*91bc56edSDimitry Andric // 12*91bc56edSDimitry Andric //===----------------------------------------------------------------------===// 13*91bc56edSDimitry Andric 14*91bc56edSDimitry Andric #include "llvm/Object/IRObjectFile.h" 15*91bc56edSDimitry Andric #include "RecordStreamer.h" 16*91bc56edSDimitry Andric #include "llvm/Bitcode/ReaderWriter.h" 17*91bc56edSDimitry Andric #include "llvm/IR/LLVMContext.h" 18*91bc56edSDimitry Andric #include "llvm/IR/GVMaterializer.h" 19*91bc56edSDimitry Andric #include "llvm/IR/Mangler.h" 20*91bc56edSDimitry Andric #include "llvm/IR/Module.h" 21*91bc56edSDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 22*91bc56edSDimitry Andric #include "llvm/MC/MCAsmInfo.h" 23*91bc56edSDimitry Andric #include "llvm/MC/MCContext.h" 24*91bc56edSDimitry Andric #include "llvm/MC/MCInstrInfo.h" 25*91bc56edSDimitry Andric #include "llvm/MC/MCObjectFileInfo.h" 26*91bc56edSDimitry Andric #include "llvm/MC/MCTargetAsmParser.h" 27*91bc56edSDimitry Andric #include "llvm/MC/MCParser/MCAsmParser.h" 28*91bc56edSDimitry Andric #include "llvm/Support/MemoryBuffer.h" 29*91bc56edSDimitry Andric #include "llvm/Support/SourceMgr.h" 30*91bc56edSDimitry Andric #include "llvm/Support/TargetRegistry.h" 31*91bc56edSDimitry Andric #include "llvm/Support/raw_ostream.h" 32*91bc56edSDimitry Andric using namespace llvm; 33*91bc56edSDimitry Andric using namespace object; 34*91bc56edSDimitry Andric 35*91bc56edSDimitry Andric IRObjectFile::IRObjectFile(std::unique_ptr<MemoryBuffer> Object, 36*91bc56edSDimitry Andric std::unique_ptr<Module> Mod) 37*91bc56edSDimitry Andric : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) { 38*91bc56edSDimitry Andric // If we have a DataLayout, setup a mangler. 39*91bc56edSDimitry Andric const DataLayout *DL = M->getDataLayout(); 40*91bc56edSDimitry Andric if (!DL) 41*91bc56edSDimitry Andric return; 42*91bc56edSDimitry Andric 43*91bc56edSDimitry Andric Mang.reset(new Mangler(DL)); 44*91bc56edSDimitry Andric 45*91bc56edSDimitry Andric const std::string &InlineAsm = M->getModuleInlineAsm(); 46*91bc56edSDimitry Andric if (InlineAsm.empty()) 47*91bc56edSDimitry Andric return; 48*91bc56edSDimitry Andric 49*91bc56edSDimitry Andric StringRef Triple = M->getTargetTriple(); 50*91bc56edSDimitry Andric std::string Err; 51*91bc56edSDimitry Andric const Target *T = TargetRegistry::lookupTarget(Triple, Err); 52*91bc56edSDimitry Andric if (!T) 53*91bc56edSDimitry Andric return; 54*91bc56edSDimitry Andric 55*91bc56edSDimitry Andric std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); 56*91bc56edSDimitry Andric if (!MRI) 57*91bc56edSDimitry Andric return; 58*91bc56edSDimitry Andric 59*91bc56edSDimitry Andric std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple)); 60*91bc56edSDimitry Andric if (!MAI) 61*91bc56edSDimitry Andric return; 62*91bc56edSDimitry Andric 63*91bc56edSDimitry Andric std::unique_ptr<MCSubtargetInfo> STI( 64*91bc56edSDimitry Andric T->createMCSubtargetInfo(Triple, "", "")); 65*91bc56edSDimitry Andric if (!STI) 66*91bc56edSDimitry Andric return; 67*91bc56edSDimitry Andric 68*91bc56edSDimitry Andric std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 69*91bc56edSDimitry Andric if (!MCII) 70*91bc56edSDimitry Andric return; 71*91bc56edSDimitry Andric 72*91bc56edSDimitry Andric MCObjectFileInfo MOFI; 73*91bc56edSDimitry Andric MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 74*91bc56edSDimitry Andric MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 75*91bc56edSDimitry Andric std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 76*91bc56edSDimitry Andric 77*91bc56edSDimitry Andric std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 78*91bc56edSDimitry Andric SourceMgr SrcMgr; 79*91bc56edSDimitry Andric SrcMgr.AddNewSourceBuffer(Buffer.release(), SMLoc()); 80*91bc56edSDimitry Andric std::unique_ptr<MCAsmParser> Parser( 81*91bc56edSDimitry Andric createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 82*91bc56edSDimitry Andric 83*91bc56edSDimitry Andric MCTargetOptions MCOptions; 84*91bc56edSDimitry Andric std::unique_ptr<MCTargetAsmParser> TAP( 85*91bc56edSDimitry Andric T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 86*91bc56edSDimitry Andric if (!TAP) 87*91bc56edSDimitry Andric return; 88*91bc56edSDimitry Andric 89*91bc56edSDimitry Andric Parser->setTargetParser(*TAP); 90*91bc56edSDimitry Andric if (Parser->Run(false)) 91*91bc56edSDimitry Andric return; 92*91bc56edSDimitry Andric 93*91bc56edSDimitry Andric for (auto &KV : *Streamer) { 94*91bc56edSDimitry Andric StringRef Key = KV.first(); 95*91bc56edSDimitry Andric RecordStreamer::State Value = KV.second; 96*91bc56edSDimitry Andric uint32_t Res = BasicSymbolRef::SF_None; 97*91bc56edSDimitry Andric switch (Value) { 98*91bc56edSDimitry Andric case RecordStreamer::NeverSeen: 99*91bc56edSDimitry Andric llvm_unreachable("foo"); 100*91bc56edSDimitry Andric case RecordStreamer::DefinedGlobal: 101*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Global; 102*91bc56edSDimitry Andric break; 103*91bc56edSDimitry Andric case RecordStreamer::Defined: 104*91bc56edSDimitry Andric break; 105*91bc56edSDimitry Andric case RecordStreamer::Global: 106*91bc56edSDimitry Andric case RecordStreamer::Used: 107*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Undefined; 108*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Global; 109*91bc56edSDimitry Andric break; 110*91bc56edSDimitry Andric } 111*91bc56edSDimitry Andric AsmSymbols.push_back( 112*91bc56edSDimitry Andric std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 113*91bc56edSDimitry Andric } 114*91bc56edSDimitry Andric } 115*91bc56edSDimitry Andric 116*91bc56edSDimitry Andric IRObjectFile::~IRObjectFile() { 117*91bc56edSDimitry Andric GVMaterializer *GVM = M->getMaterializer(); 118*91bc56edSDimitry Andric if (GVM) 119*91bc56edSDimitry Andric GVM->releaseBuffer(); 120*91bc56edSDimitry Andric } 121*91bc56edSDimitry Andric 122*91bc56edSDimitry Andric static const GlobalValue *getGV(DataRefImpl &Symb) { 123*91bc56edSDimitry Andric if ((Symb.p & 3) == 3) 124*91bc56edSDimitry Andric return nullptr; 125*91bc56edSDimitry Andric 126*91bc56edSDimitry Andric return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 127*91bc56edSDimitry Andric } 128*91bc56edSDimitry Andric 129*91bc56edSDimitry Andric static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 130*91bc56edSDimitry Andric if (I == M.alias_end()) 131*91bc56edSDimitry Andric return 3; 132*91bc56edSDimitry Andric const GlobalValue *GV = &*I; 133*91bc56edSDimitry Andric return reinterpret_cast<uintptr_t>(GV) | 2; 134*91bc56edSDimitry Andric } 135*91bc56edSDimitry Andric 136*91bc56edSDimitry Andric static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 137*91bc56edSDimitry Andric if (I == M.global_end()) 138*91bc56edSDimitry Andric return skipEmpty(M.alias_begin(), M); 139*91bc56edSDimitry Andric const GlobalValue *GV = &*I; 140*91bc56edSDimitry Andric return reinterpret_cast<uintptr_t>(GV) | 1; 141*91bc56edSDimitry Andric } 142*91bc56edSDimitry Andric 143*91bc56edSDimitry Andric static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 144*91bc56edSDimitry Andric if (I == M.end()) 145*91bc56edSDimitry Andric return skipEmpty(M.global_begin(), M); 146*91bc56edSDimitry Andric const GlobalValue *GV = &*I; 147*91bc56edSDimitry Andric return reinterpret_cast<uintptr_t>(GV) | 0; 148*91bc56edSDimitry Andric } 149*91bc56edSDimitry Andric 150*91bc56edSDimitry Andric static unsigned getAsmSymIndex(DataRefImpl Symb) { 151*91bc56edSDimitry Andric assert((Symb.p & uintptr_t(3)) == 3); 152*91bc56edSDimitry Andric uintptr_t Index = Symb.p & ~uintptr_t(3); 153*91bc56edSDimitry Andric Index >>= 2; 154*91bc56edSDimitry Andric return Index; 155*91bc56edSDimitry Andric } 156*91bc56edSDimitry Andric 157*91bc56edSDimitry Andric void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 158*91bc56edSDimitry Andric const GlobalValue *GV = getGV(Symb); 159*91bc56edSDimitry Andric uintptr_t Res; 160*91bc56edSDimitry Andric 161*91bc56edSDimitry Andric switch (Symb.p & 3) { 162*91bc56edSDimitry Andric case 0: { 163*91bc56edSDimitry Andric Module::const_iterator Iter(static_cast<const Function*>(GV)); 164*91bc56edSDimitry Andric ++Iter; 165*91bc56edSDimitry Andric Res = skipEmpty(Iter, *M); 166*91bc56edSDimitry Andric break; 167*91bc56edSDimitry Andric } 168*91bc56edSDimitry Andric case 1: { 169*91bc56edSDimitry Andric Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 170*91bc56edSDimitry Andric ++Iter; 171*91bc56edSDimitry Andric Res = skipEmpty(Iter, *M); 172*91bc56edSDimitry Andric break; 173*91bc56edSDimitry Andric } 174*91bc56edSDimitry Andric case 2: { 175*91bc56edSDimitry Andric Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 176*91bc56edSDimitry Andric ++Iter; 177*91bc56edSDimitry Andric Res = skipEmpty(Iter, *M); 178*91bc56edSDimitry Andric break; 179*91bc56edSDimitry Andric } 180*91bc56edSDimitry Andric case 3: { 181*91bc56edSDimitry Andric unsigned Index = getAsmSymIndex(Symb); 182*91bc56edSDimitry Andric assert(Index < AsmSymbols.size()); 183*91bc56edSDimitry Andric ++Index; 184*91bc56edSDimitry Andric Res = (Index << 2) | 3; 185*91bc56edSDimitry Andric break; 186*91bc56edSDimitry Andric } 187*91bc56edSDimitry Andric } 188*91bc56edSDimitry Andric 189*91bc56edSDimitry Andric Symb.p = Res; 190*91bc56edSDimitry Andric } 191*91bc56edSDimitry Andric 192*91bc56edSDimitry Andric std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 193*91bc56edSDimitry Andric DataRefImpl Symb) const { 194*91bc56edSDimitry Andric const GlobalValue *GV = getGV(Symb); 195*91bc56edSDimitry Andric if (!GV) { 196*91bc56edSDimitry Andric unsigned Index = getAsmSymIndex(Symb); 197*91bc56edSDimitry Andric assert(Index <= AsmSymbols.size()); 198*91bc56edSDimitry Andric OS << AsmSymbols[Index].first; 199*91bc56edSDimitry Andric return object_error::success;; 200*91bc56edSDimitry Andric } 201*91bc56edSDimitry Andric 202*91bc56edSDimitry Andric if (Mang) 203*91bc56edSDimitry Andric Mang->getNameWithPrefix(OS, GV, false); 204*91bc56edSDimitry Andric else 205*91bc56edSDimitry Andric OS << GV->getName(); 206*91bc56edSDimitry Andric 207*91bc56edSDimitry Andric return object_error::success; 208*91bc56edSDimitry Andric } 209*91bc56edSDimitry Andric 210*91bc56edSDimitry Andric static bool isDeclaration(const GlobalValue &V) { 211*91bc56edSDimitry Andric if (V.hasAvailableExternallyLinkage()) 212*91bc56edSDimitry Andric return true; 213*91bc56edSDimitry Andric 214*91bc56edSDimitry Andric if (V.isMaterializable()) 215*91bc56edSDimitry Andric return false; 216*91bc56edSDimitry Andric 217*91bc56edSDimitry Andric return V.isDeclaration(); 218*91bc56edSDimitry Andric } 219*91bc56edSDimitry Andric 220*91bc56edSDimitry Andric uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 221*91bc56edSDimitry Andric const GlobalValue *GV = getGV(Symb); 222*91bc56edSDimitry Andric 223*91bc56edSDimitry Andric if (!GV) { 224*91bc56edSDimitry Andric unsigned Index = getAsmSymIndex(Symb); 225*91bc56edSDimitry Andric assert(Index <= AsmSymbols.size()); 226*91bc56edSDimitry Andric return AsmSymbols[Index].second; 227*91bc56edSDimitry Andric } 228*91bc56edSDimitry Andric 229*91bc56edSDimitry Andric uint32_t Res = BasicSymbolRef::SF_None; 230*91bc56edSDimitry Andric if (isDeclaration(*GV)) 231*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Undefined; 232*91bc56edSDimitry Andric if (GV->hasPrivateLinkage()) 233*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 234*91bc56edSDimitry Andric if (!GV->hasLocalLinkage()) 235*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Global; 236*91bc56edSDimitry Andric if (GV->hasCommonLinkage()) 237*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Common; 238*91bc56edSDimitry Andric if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) 239*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_Weak; 240*91bc56edSDimitry Andric 241*91bc56edSDimitry Andric if (GV->getName().startswith("llvm.")) 242*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 243*91bc56edSDimitry Andric else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 244*91bc56edSDimitry Andric if (Var->getSection() == StringRef("llvm.metadata")) 245*91bc56edSDimitry Andric Res |= BasicSymbolRef::SF_FormatSpecific; 246*91bc56edSDimitry Andric } 247*91bc56edSDimitry Andric 248*91bc56edSDimitry Andric return Res; 249*91bc56edSDimitry Andric } 250*91bc56edSDimitry Andric 251*91bc56edSDimitry Andric const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const { 252*91bc56edSDimitry Andric const GlobalValue *GV = getGV(Symb); 253*91bc56edSDimitry Andric return GV; 254*91bc56edSDimitry Andric } 255*91bc56edSDimitry Andric 256*91bc56edSDimitry Andric basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 257*91bc56edSDimitry Andric Module::const_iterator I = M->begin(); 258*91bc56edSDimitry Andric DataRefImpl Ret; 259*91bc56edSDimitry Andric Ret.p = skipEmpty(I, *M); 260*91bc56edSDimitry Andric return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 261*91bc56edSDimitry Andric } 262*91bc56edSDimitry Andric 263*91bc56edSDimitry Andric basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 264*91bc56edSDimitry Andric DataRefImpl Ret; 265*91bc56edSDimitry Andric uint64_t NumAsm = AsmSymbols.size(); 266*91bc56edSDimitry Andric NumAsm <<= 2; 267*91bc56edSDimitry Andric Ret.p = 3 | NumAsm; 268*91bc56edSDimitry Andric return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 269*91bc56edSDimitry Andric } 270*91bc56edSDimitry Andric 271*91bc56edSDimitry Andric ErrorOr<IRObjectFile *> llvm::object::IRObjectFile::createIRObjectFile( 272*91bc56edSDimitry Andric std::unique_ptr<MemoryBuffer> Object, LLVMContext &Context) { 273*91bc56edSDimitry Andric ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Object.get(), Context); 274*91bc56edSDimitry Andric if (std::error_code EC = MOrErr.getError()) 275*91bc56edSDimitry Andric return EC; 276*91bc56edSDimitry Andric 277*91bc56edSDimitry Andric std::unique_ptr<Module> M(MOrErr.get()); 278*91bc56edSDimitry Andric return new IRObjectFile(std::move(Object), std::move(M)); 279*91bc56edSDimitry Andric } 280