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 Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 59 if (!SymbolFlagsOrErr) 60 // TODO: Test this error. 61 return SymbolFlagsOrErr.takeError(); 62 63 JITSymbolFlags Flags = JITSymbolFlags::None; 64 if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Weak) 65 Flags |= JITSymbolFlags::Weak; 66 if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Common) 67 Flags |= JITSymbolFlags::Common; 68 if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Exported) 69 Flags |= JITSymbolFlags::Exported; 70 71 auto SymbolType = Symbol.getType(); 72 if (!SymbolType) 73 return SymbolType.takeError(); 74 75 if (*SymbolType & object::SymbolRef::ST_Function) 76 Flags |= JITSymbolFlags::Callable; 77 78 return Flags; 79 } 80 81 ARMJITSymbolFlags 82 llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) { 83 Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags(); 84 if (!SymbolFlagsOrErr) 85 // TODO: Actually report errors helpfully. 86 report_fatal_error(SymbolFlagsOrErr.takeError()); 87 ARMJITSymbolFlags Flags; 88 if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb) 89 Flags |= ARMJITSymbolFlags::Thumb; 90 return Flags; 91 } 92 93 /// Performs lookup by, for each symbol, first calling 94 /// findSymbolInLogicalDylib and if that fails calling 95 /// findSymbol. 96 void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols, 97 OnResolvedFunction OnResolved) { 98 JITSymbolResolver::LookupResult Result; 99 for (auto &Symbol : Symbols) { 100 std::string SymName = Symbol.str(); 101 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 102 if (auto AddrOrErr = Sym.getAddress()) 103 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 104 else { 105 OnResolved(AddrOrErr.takeError()); 106 return; 107 } 108 } else if (auto Err = Sym.takeError()) { 109 OnResolved(std::move(Err)); 110 return; 111 } else { 112 // findSymbolInLogicalDylib failed. Lets try findSymbol. 113 if (auto Sym = findSymbol(SymName)) { 114 if (auto AddrOrErr = Sym.getAddress()) 115 Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags()); 116 else { 117 OnResolved(AddrOrErr.takeError()); 118 return; 119 } 120 } else if (auto Err = Sym.takeError()) { 121 OnResolved(std::move(Err)); 122 return; 123 } else { 124 OnResolved(make_error<StringError>("Symbol not found: " + Symbol, 125 inconvertibleErrorCode())); 126 return; 127 } 128 } 129 } 130 131 OnResolved(std::move(Result)); 132 } 133 134 /// Performs flags lookup by calling findSymbolInLogicalDylib and 135 /// returning the flags value for that symbol. 136 Expected<JITSymbolResolver::LookupSet> 137 LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) { 138 JITSymbolResolver::LookupSet Result; 139 140 for (auto &Symbol : Symbols) { 141 std::string SymName = Symbol.str(); 142 if (auto Sym = findSymbolInLogicalDylib(SymName)) { 143 // If there's an existing def but it is not strong, then the caller is 144 // responsible for it. 145 if (!Sym.getFlags().isStrong()) 146 Result.insert(Symbol); 147 } else if (auto Err = Sym.takeError()) 148 return std::move(Err); 149 else { 150 // If there is no existing definition then the caller is responsible for 151 // it. 152 Result.insert(Symbol); 153 } 154 } 155 156 return std::move(Result); 157 } 158