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