1 //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===// 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 // JITSymbol class implementation plus helper functions. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "llvm/ExecutionEngine/JITSymbol.h" 15 #include "llvm/IR/Function.h" 16 #include "llvm/IR/GlobalAlias.h" 17 #include "llvm/IR/GlobalValue.h" 18 #include "llvm/Object/ObjectFile.h" 19 20 using namespace llvm; 21 fromGlobalValue(const GlobalValue & GV)22JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) { 23 JITSymbolFlags Flags = JITSymbolFlags::None; 24 if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage()) 25 Flags |= JITSymbolFlags::Weak; 26 if (GV.hasCommonLinkage()) 27 Flags |= JITSymbolFlags::Common; 28 if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility()) 29 Flags |= JITSymbolFlags::Exported; 30 31 if (isa<Function>(GV)) 32 Flags |= JITSymbolFlags::Callable; 33 else if (isa<GlobalAlias>(GV) && 34 isa<Function>(cast<GlobalAlias>(GV).getAliasee())) 35 Flags |= JITSymbolFlags::Callable; 36 37 return Flags; 38 } 39 40 Expected<JITSymbolFlags> fromObjectSymbol(const object::SymbolRef & Symbol)41llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 42 JITSymbolFlags Flags = JITSymbolFlags::None; 43 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak) 44 Flags |= JITSymbolFlags::Weak; 45 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common) 46 Flags |= JITSymbolFlags::Common; 47 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported) 48 Flags |= JITSymbolFlags::Exported; 49 50 auto SymbolType = Symbol.getType(); 51 if (!SymbolType) 52 return SymbolType.takeError(); 53 54 if (*SymbolType & object::SymbolRef::ST_Function) 55 Flags |= JITSymbolFlags::Callable; 56 57 return Flags; 58 } 59 60 ARMJITSymbolFlags fromObjectSymbol(const object::SymbolRef & Symbol)61llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 62 ARMJITSymbolFlags Flags; 63 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb) 64 Flags |= ARMJITSymbolFlags::Thumb; 65 return Flags; 66 } 67 68 /// Performs lookup by, for each symbol, first calling 69 /// findSymbolInLogicalDylib and if that fails calling 70 /// findSymbol. lookup(const LookupSet & Symbols,OnResolvedFunction OnResolved)71void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols, 72 OnResolvedFunction OnResolved) { 73 JITSymbolResolver::LookupResult Result; 74 for (auto &Symbol : Symbols) { 75 std::string SymName = Symbol.str(); 76 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 77 if (auto AddrOrErr = Sym.getAddress()) 78 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 79 else { 80 OnResolved(AddrOrErr.takeError()); 81 return; 82 } 83 } else if (auto Err = Sym.takeError()) { 84 OnResolved(std::move(Err)); 85 return; 86 } else { 87 // findSymbolInLogicalDylib failed. Lets try findSymbol. 88 if (auto Sym = findSymbol(SymName)) { 89 if (auto AddrOrErr = Sym.getAddress()) 90 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 91 else { 92 OnResolved(AddrOrErr.takeError()); 93 return; 94 } 95 } else if (auto Err = Sym.takeError()) { 96 OnResolved(std::move(Err)); 97 return; 98 } else { 99 OnResolved(make_error<StringError>("Symbol not found: " + Symbol, 100 inconvertibleErrorCode())); 101 return; 102 } 103 } 104 } 105 106 OnResolved(std::move(Result)); 107 } 108 109 /// Performs flags lookup by calling findSymbolInLogicalDylib and 110 /// returning the flags value for that symbol. 111 Expected<JITSymbolResolver::LookupSet> getResponsibilitySet(const LookupSet & Symbols)112LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) { 113 JITSymbolResolver::LookupSet Result; 114 115 for (auto &Symbol : Symbols) { 116 std::string SymName = Symbol.str(); 117 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 118 // If there's an existing def but it is not strong, then the caller is 119 // responsible for it. 120 if (!Sym.getFlags().isStrong()) 121 Result.insert(Symbol); 122 } else if (auto Err = Sym.takeError()) 123 return std::move(Err); 124 else { 125 // If there is no existing definition then the caller is responsible for 126 // it. 127 Result.insert(Symbol); 128 } 129 } 130 131 return std::move(Result); 132 } 133