LLVM API Documentation
00001 //===- IRObjectFile.cpp - IR object file implementation ---------*- C++ -*-===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // Part of the IRObjectFile class implementation. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "llvm/Object/IRObjectFile.h" 00015 #include "RecordStreamer.h" 00016 #include "llvm/Bitcode/ReaderWriter.h" 00017 #include "llvm/IR/LLVMContext.h" 00018 #include "llvm/IR/GVMaterializer.h" 00019 #include "llvm/IR/Mangler.h" 00020 #include "llvm/IR/Module.h" 00021 #include "llvm/MC/MCRegisterInfo.h" 00022 #include "llvm/MC/MCAsmInfo.h" 00023 #include "llvm/MC/MCContext.h" 00024 #include "llvm/MC/MCInstrInfo.h" 00025 #include "llvm/MC/MCObjectFileInfo.h" 00026 #include "llvm/MC/MCTargetAsmParser.h" 00027 #include "llvm/MC/MCParser/MCAsmParser.h" 00028 #include "llvm/Support/MemoryBuffer.h" 00029 #include "llvm/Support/SourceMgr.h" 00030 #include "llvm/Support/TargetRegistry.h" 00031 #include "llvm/Support/raw_ostream.h" 00032 using namespace llvm; 00033 using namespace object; 00034 00035 IRObjectFile::IRObjectFile(MemoryBufferRef Object, std::unique_ptr<Module> Mod) 00036 : SymbolicFile(Binary::ID_IR, Object), M(std::move(Mod)) { 00037 // If we have a DataLayout, setup a mangler. 00038 const DataLayout *DL = M->getDataLayout(); 00039 if (!DL) 00040 return; 00041 00042 Mang.reset(new Mangler(DL)); 00043 00044 const std::string &InlineAsm = M->getModuleInlineAsm(); 00045 if (InlineAsm.empty()) 00046 return; 00047 00048 StringRef Triple = M->getTargetTriple(); 00049 std::string Err; 00050 const Target *T = TargetRegistry::lookupTarget(Triple, Err); 00051 if (!T) 00052 return; 00053 00054 std::unique_ptr<MCRegisterInfo> MRI(T->createMCRegInfo(Triple)); 00055 if (!MRI) 00056 return; 00057 00058 std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, Triple)); 00059 if (!MAI) 00060 return; 00061 00062 std::unique_ptr<MCSubtargetInfo> STI( 00063 T->createMCSubtargetInfo(Triple, "", "")); 00064 if (!STI) 00065 return; 00066 00067 std::unique_ptr<MCInstrInfo> MCII(T->createMCInstrInfo()); 00068 if (!MCII) 00069 return; 00070 00071 MCObjectFileInfo MOFI; 00072 MCContext MCCtx(MAI.get(), MRI.get(), &MOFI); 00073 MOFI.InitMCObjectFileInfo(Triple, Reloc::Default, CodeModel::Default, MCCtx); 00074 std::unique_ptr<RecordStreamer> Streamer(new RecordStreamer(MCCtx)); 00075 00076 std::unique_ptr<MemoryBuffer> Buffer(MemoryBuffer::getMemBuffer(InlineAsm)); 00077 SourceMgr SrcMgr; 00078 SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc()); 00079 std::unique_ptr<MCAsmParser> Parser( 00080 createMCAsmParser(SrcMgr, MCCtx, *Streamer, *MAI)); 00081 00082 MCTargetOptions MCOptions; 00083 std::unique_ptr<MCTargetAsmParser> TAP( 00084 T->createMCAsmParser(*STI, *Parser, *MCII, MCOptions)); 00085 if (!TAP) 00086 return; 00087 00088 Parser->setTargetParser(*TAP); 00089 if (Parser->Run(false)) 00090 return; 00091 00092 for (auto &KV : *Streamer) { 00093 StringRef Key = KV.first(); 00094 RecordStreamer::State Value = KV.second; 00095 uint32_t Res = BasicSymbolRef::SF_None; 00096 switch (Value) { 00097 case RecordStreamer::NeverSeen: 00098 llvm_unreachable("foo"); 00099 case RecordStreamer::DefinedGlobal: 00100 Res |= BasicSymbolRef::SF_Global; 00101 break; 00102 case RecordStreamer::Defined: 00103 break; 00104 case RecordStreamer::Global: 00105 case RecordStreamer::Used: 00106 Res |= BasicSymbolRef::SF_Undefined; 00107 Res |= BasicSymbolRef::SF_Global; 00108 break; 00109 } 00110 AsmSymbols.push_back( 00111 std::make_pair<std::string, uint32_t>(Key, std::move(Res))); 00112 } 00113 } 00114 00115 IRObjectFile::~IRObjectFile() { 00116 } 00117 00118 static const GlobalValue *getGV(DataRefImpl &Symb) { 00119 if ((Symb.p & 3) == 3) 00120 return nullptr; 00121 00122 return reinterpret_cast<GlobalValue*>(Symb.p & ~uintptr_t(3)); 00123 } 00124 00125 static uintptr_t skipEmpty(Module::const_alias_iterator I, const Module &M) { 00126 if (I == M.alias_end()) 00127 return 3; 00128 const GlobalValue *GV = &*I; 00129 return reinterpret_cast<uintptr_t>(GV) | 2; 00130 } 00131 00132 static uintptr_t skipEmpty(Module::const_global_iterator I, const Module &M) { 00133 if (I == M.global_end()) 00134 return skipEmpty(M.alias_begin(), M); 00135 const GlobalValue *GV = &*I; 00136 return reinterpret_cast<uintptr_t>(GV) | 1; 00137 } 00138 00139 static uintptr_t skipEmpty(Module::const_iterator I, const Module &M) { 00140 if (I == M.end()) 00141 return skipEmpty(M.global_begin(), M); 00142 const GlobalValue *GV = &*I; 00143 return reinterpret_cast<uintptr_t>(GV) | 0; 00144 } 00145 00146 static unsigned getAsmSymIndex(DataRefImpl Symb) { 00147 assert((Symb.p & uintptr_t(3)) == 3); 00148 uintptr_t Index = Symb.p & ~uintptr_t(3); 00149 Index >>= 2; 00150 return Index; 00151 } 00152 00153 void IRObjectFile::moveSymbolNext(DataRefImpl &Symb) const { 00154 const GlobalValue *GV = getGV(Symb); 00155 uintptr_t Res; 00156 00157 switch (Symb.p & 3) { 00158 case 0: { 00159 Module::const_iterator Iter(static_cast<const Function*>(GV)); 00160 ++Iter; 00161 Res = skipEmpty(Iter, *M); 00162 break; 00163 } 00164 case 1: { 00165 Module::const_global_iterator Iter(static_cast<const GlobalVariable*>(GV)); 00166 ++Iter; 00167 Res = skipEmpty(Iter, *M); 00168 break; 00169 } 00170 case 2: { 00171 Module::const_alias_iterator Iter(static_cast<const GlobalAlias*>(GV)); 00172 ++Iter; 00173 Res = skipEmpty(Iter, *M); 00174 break; 00175 } 00176 case 3: { 00177 unsigned Index = getAsmSymIndex(Symb); 00178 assert(Index < AsmSymbols.size()); 00179 ++Index; 00180 Res = (Index << 2) | 3; 00181 break; 00182 } 00183 } 00184 00185 Symb.p = Res; 00186 } 00187 00188 std::error_code IRObjectFile::printSymbolName(raw_ostream &OS, 00189 DataRefImpl Symb) const { 00190 const GlobalValue *GV = getGV(Symb); 00191 if (!GV) { 00192 unsigned Index = getAsmSymIndex(Symb); 00193 assert(Index <= AsmSymbols.size()); 00194 OS << AsmSymbols[Index].first; 00195 return object_error::success;; 00196 } 00197 00198 if (Mang) 00199 Mang->getNameWithPrefix(OS, GV, false); 00200 else 00201 OS << GV->getName(); 00202 00203 return object_error::success; 00204 } 00205 00206 static bool isDeclaration(const GlobalValue &V) { 00207 if (V.hasAvailableExternallyLinkage()) 00208 return true; 00209 00210 if (V.isMaterializable()) 00211 return false; 00212 00213 return V.isDeclaration(); 00214 } 00215 00216 uint32_t IRObjectFile::getSymbolFlags(DataRefImpl Symb) const { 00217 const GlobalValue *GV = getGV(Symb); 00218 00219 if (!GV) { 00220 unsigned Index = getAsmSymIndex(Symb); 00221 assert(Index <= AsmSymbols.size()); 00222 return AsmSymbols[Index].second; 00223 } 00224 00225 uint32_t Res = BasicSymbolRef::SF_None; 00226 if (isDeclaration(*GV)) 00227 Res |= BasicSymbolRef::SF_Undefined; 00228 if (GV->hasPrivateLinkage()) 00229 Res |= BasicSymbolRef::SF_FormatSpecific; 00230 if (!GV->hasLocalLinkage()) 00231 Res |= BasicSymbolRef::SF_Global; 00232 if (GV->hasCommonLinkage()) 00233 Res |= BasicSymbolRef::SF_Common; 00234 if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) 00235 Res |= BasicSymbolRef::SF_Weak; 00236 00237 if (GV->getName().startswith("llvm.")) 00238 Res |= BasicSymbolRef::SF_FormatSpecific; 00239 else if (auto *Var = dyn_cast<GlobalVariable>(GV)) { 00240 if (Var->getSection() == StringRef("llvm.metadata")) 00241 Res |= BasicSymbolRef::SF_FormatSpecific; 00242 } 00243 00244 return Res; 00245 } 00246 00247 const GlobalValue *IRObjectFile::getSymbolGV(DataRefImpl Symb) const { 00248 const GlobalValue *GV = getGV(Symb); 00249 return GV; 00250 } 00251 00252 basic_symbol_iterator IRObjectFile::symbol_begin_impl() const { 00253 Module::const_iterator I = M->begin(); 00254 DataRefImpl Ret; 00255 Ret.p = skipEmpty(I, *M); 00256 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 00257 } 00258 00259 basic_symbol_iterator IRObjectFile::symbol_end_impl() const { 00260 DataRefImpl Ret; 00261 uint64_t NumAsm = AsmSymbols.size(); 00262 NumAsm <<= 2; 00263 Ret.p = 3 | NumAsm; 00264 return basic_symbol_iterator(BasicSymbolRef(Ret, this)); 00265 } 00266 00267 ErrorOr<std::unique_ptr<IRObjectFile>> 00268 llvm::object::IRObjectFile::createIRObjectFile(MemoryBufferRef Object, 00269 LLVMContext &Context) { 00270 00271 std::unique_ptr<MemoryBuffer> Buff(MemoryBuffer::getMemBuffer(Object, false)); 00272 00273 ErrorOr<Module *> MOrErr = getLazyBitcodeModule(std::move(Buff), Context); 00274 if (std::error_code EC = MOrErr.getError()) 00275 return EC; 00276 00277 std::unique_ptr<Module> M(MOrErr.get()); 00278 return llvm::make_unique<IRObjectFile>(Object, std::move(M)); 00279 }