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