1 //===----------- JITSymbol.cpp - JITSymbol class implementation -----------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // JITSymbol class implementation plus helper functions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/ExecutionEngine/JITSymbol.h" 14 #include "llvm/IR/Function.h" 15 #include "llvm/IR/GlobalAlias.h" 16 #include "llvm/IR/GlobalValue.h" 17 #include "llvm/IR/ModuleSummaryIndex.h" 18 #include "llvm/Object/ObjectFile.h" 19 20 using namespace llvm; 21 22 JITSymbolFlags 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 JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) { 41 JITSymbolFlags Flags = JITSymbolFlags::None; 42 auto L = S->linkage(); 43 if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L)) 44 Flags |= JITSymbolFlags::Weak; 45 if (GlobalValue::isCommonLinkage(L)) 46 Flags |= JITSymbolFlags::Common; 47 if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L)) 48 Flags |= JITSymbolFlags::Exported; 49 50 if (isa<FunctionSummary>(S)) 51 Flags |= JITSymbolFlags::Callable; 52 53 return Flags; 54 } 55 56 Expected<JITSymbolFlags> 57 llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 58 JITSymbolFlags Flags = JITSymbolFlags::None; 59 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Weak) 60 Flags |= JITSymbolFlags::Weak; 61 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Common) 62 Flags |= JITSymbolFlags::Common; 63 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Exported) 64 Flags |= JITSymbolFlags::Exported; 65 66 auto SymbolType = Symbol.getType(); 67 if (!SymbolType) 68 return SymbolType.takeError(); 69 70 if (*SymbolType & object::SymbolRef::ST_Function) 71 Flags |= JITSymbolFlags::Callable; 72 73 return Flags; 74 } 75 76 ARMJITSymbolFlags 77 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 78 ARMJITSymbolFlags Flags; 79 if (Symbol.getFlags() & object::BasicSymbolRef::SF_Thumb) 80 Flags |= ARMJITSymbolFlags::Thumb; 81 return Flags; 82 } 83 84 /// Performs lookup by, for each symbol, first calling 85 /// findSymbolInLogicalDylib and if that fails calling 86 /// findSymbol. 87 void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols, 88 OnResolvedFunction OnResolved) { 89 JITSymbolResolver::LookupResult Result; 90 for (auto &Symbol : Symbols) { 91 std::string SymName = Symbol.str(); 92 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 93 if (auto AddrOrErr = Sym.getAddress()) 94 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 95 else { 96 OnResolved(AddrOrErr.takeError()); 97 return; 98 } 99 } else if (auto Err = Sym.takeError()) { 100 OnResolved(std::move(Err)); 101 return; 102 } else { 103 // findSymbolInLogicalDylib failed. Lets try findSymbol. 104 if (auto Sym = findSymbol(SymName)) { 105 if (auto AddrOrErr = Sym.getAddress()) 106 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 107 else { 108 OnResolved(AddrOrErr.takeError()); 109 return; 110 } 111 } else if (auto Err = Sym.takeError()) { 112 OnResolved(std::move(Err)); 113 return; 114 } else { 115 OnResolved(make_error<StringError>("Symbol not found: " + Symbol, 116 inconvertibleErrorCode())); 117 return; 118 } 119 } 120 } 121 122 OnResolved(std::move(Result)); 123 } 124 125 /// Performs flags lookup by calling findSymbolInLogicalDylib and 126 /// returning the flags value for that symbol. 127 Expected<JITSymbolResolver::LookupSet> 128 LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) { 129 JITSymbolResolver::LookupSet Result; 130 131 for (auto &Symbol : Symbols) { 132 std::string SymName = Symbol.str(); 133 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 134 // If there's an existing def but it is not strong, then the caller is 135 // responsible for it. 136 if (!Sym.getFlags().isStrong()) 137 Result.insert(Symbol); 138 } else if (auto Err = Sym.takeError()) 139 return std::move(Err); 140 else { 141 // If there is no existing definition then the caller is responsible for 142 // it. 143 Result.insert(Symbol); 144 } 145 } 146 147 return std::move(Result); 148 } 149