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/Bitcode/ReaderWriter.h" 15 #include "llvm/IR/LLVMContext.h" 16 #include "llvm/IR/GVMaterializer.h" 17 #include "llvm/IR/Mangler.h" 18 #include "llvm/IR/Module.h" 19 #include "llvm/Object/IRObjectFile.h" 20 #include "llvm/Object/RecordStreamer.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::error_code &EC, LLVMContext &Context) 37 : SymbolicFile(Binary::ID_IR, std::move(Object)) { 38 ErrorOr<Module *> MOrErr = getLazyBitcodeModule(Data.get(), Context); 39 if ((EC = MOrErr.getError())) 40 return; 41 42 M.reset(MOrErr.get()); 43 44 // If we have a DataLayout, setup a mangler. 45 const DataLayout *DL = M->getDataLayout(); 46 if (!DL) 47 return; 48 49 Mang.reset(new Mangler(DL)); 50 51 const std::string &InlineAsm = M->getModuleInlineAsm(); 52 if (InlineAsm.empty()) 53 return; 54 55 StringRef Triple = M->getTargetTriple(); 56 std::string Err; 57 const Target *T = TargetRegistry::lookupTarget(Triple, Err); 58 if (!T) 59 return; 60 61 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); 62 if (!MRI) 63 return; 64 65 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple)); 66 if (!MAI) 67 return; 68 69 std::unique_ptr<MCSubtargetInfo> STI( 70 T->createMCSubtargetInfo(Triple, "", "")); 71 if (!STI) 72 return; 73 74 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 75 if (!MCII) 76 return; 77 78 MCObjectFileInfo MOFI; 79 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 80 MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 81 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 82 83 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 84 SourceMgr SrcMgr; 85 SrcMgr.AddNewSourceBuffer(Buffer.release(), SMLoc()); 86 std::unique_ptr<MCAsmParser> Parser( 87 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 88 89 MCTargetOptions MCOptions; 90 std::unique_ptr<MCTargetAsmParser> TAP( 91 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 92 if (!TAP) 93 return; 94 95 Parser->setTargetParser(*TAP); 96 if (Parser->Run(false)) 97 return; 98 99 for (auto &KV : *Streamer) { 100 StringRef Key = KV.first(); 101 RecordStreamer::State Value = KV.second; 102 uint32_t Res = BasicSymbolRef::SF_None; 103 switch (Value) { 104 case RecordStreamer::NeverSeen: 105 llvm_unreachable("foo"); 106 case RecordStreamer::DefinedGlobal: 107 Res |= BasicSymbolRef::SF_Global; 108 break; 109 case RecordStreamer::Defined: 110 break; 111 case RecordStreamer::Global: 112 case RecordStreamer::Used: 113 Res |= BasicSymbolRef::SF_Undefined; 114 Res |= BasicSymbolRef::SF_Global; 115 break; 116 } 117 AsmSymbols.push_back( 118 std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 119 } 120 } 121 122 IRObjectFile::~IRObjectFile() { M->getMaterializer()->releaseBuffer(); } 123 124 static const GlobalValue *getGV(DataRefImpl &Symb) { 125 if ((Symb.p & 3) == 3) 126 return nullptr; 127 128 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 129 } 130 131 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 132 if (I == M.alias_end()) 133 return 3; 134 const GlobalValue *GV = &*I; 135 return reinterpret_cast<uintptr_t>(GV) | 2; 136 } 137 138 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 139 if (I == M.global_end()) 140 return skipEmpty(M.alias_begin(), M); 141 const GlobalValue *GV = &*I; 142 return reinterpret_cast<uintptr_t>(GV) | 1; 143 } 144 145 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 146 if (I == M.end()) 147 return skipEmpty(M.global_begin(), M); 148 const GlobalValue *GV = &*I; 149 return reinterpret_cast<uintptr_t>(GV) | 0; 150 } 151 152 static unsigned getAsmSymIndex(DataRefImpl Symb) { 153 assert((Symb.p & uintptr_t(3)) == 3); 154 uintptr_t Index = Symb.p & ~uintptr_t(3); 155 Index >>= 2; 156 return Index; 157 } 158 159 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 160 const GlobalValue *GV = getGV(Symb); 161 uintptr_t Res; 162 163 switch (Symb.p & 3) { 164 case 0: { 165 Module::const_iterator Iter(static_cast<const Function*>(GV)); 166 ++Iter; 167 Res = skipEmpty(Iter, *M); 168 break; 169 } 170 case 1: { 171 Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 172 ++Iter; 173 Res = skipEmpty(Iter, *M); 174 break; 175 } 176 case 2: { 177 Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 178 ++Iter; 179 Res = skipEmpty(Iter, *M); 180 break; 181 } 182 case 3: { 183 unsigned Index = getAsmSymIndex(Symb); 184 assert(Index < AsmSymbols.size()); 185 ++Index; 186 Res = (Index << 2) | 3; 187 break; 188 } 189 } 190 191 Symb.p = Res; 192 } 193 194 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 195 DataRefImpl Symb) const { 196 const GlobalValue *GV = getGV(Symb); 197 if (!GV) { 198 unsigned Index = getAsmSymIndex(Symb); 199 assert(Index <= AsmSymbols.size()); 200 OS << AsmSymbols[Index].first; 201 return object_error::success;; 202 } 203 204 if (Mang) 205 Mang->getNameWithPrefix(OS, GV, false); 206 else 207 OS << GV->getName(); 208 209 return object_error::success; 210 } 211 212 static bool isDeclaration(const GlobalValue &V) { 213 if (V.hasAvailableExternallyLinkage()) 214 return true; 215 216 if (V.isMaterializable()) 217 return false; 218 219 return V.isDeclaration(); 220 } 221 222 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 223 const GlobalValue *GV = getGV(Symb); 224 225 if (!GV) { 226 unsigned Index = getAsmSymIndex(Symb); 227 assert(Index <= AsmSymbols.size()); 228 return AsmSymbols[Index].second; 229 } 230 231 uint32_t Res = BasicSymbolRef::SF_None; 232 if (isDeclaration(*GV)) 233 Res |= BasicSymbolRef::SF_Undefined; 234 if (GV->hasPrivateLinkage()) 235 Res |= BasicSymbolRef::SF_FormatSpecific; 236 if (!GV->hasLocalLinkage()) 237 Res |= BasicSymbolRef::SF_Global; 238 if (GV->hasCommonLinkage()) 239 Res |= BasicSymbolRef::SF_Common; 240 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) 241 Res |= BasicSymbolRef::SF_Weak; 242 243 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 std::error_code EC; 274 std::unique_ptr<IRObjectFile> Ret( 275 new IRObjectFile(std::move(Object), EC, Context)); 276 if (EC) 277 return EC; 278 return Ret.release(); 279 } 280