JITSymbol.cpp 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  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. #include "llvm/ExecutionEngine/JITSymbol.h"
  13. #include "llvm/IR/Function.h"
  14. #include "llvm/IR/GlobalAlias.h"
  15. #include "llvm/IR/GlobalValue.h"
  16. #include "llvm/IR/ModuleSummaryIndex.h"
  17. #include "llvm/Object/ObjectFile.h"
  18. using namespace llvm;
  19. JITSymbolFlags llvm::JITSymbolFlags::fromGlobalValue(const GlobalValue &GV) {
  20. assert(GV.hasName() && "Can't get flags for anonymous symbol");
  21. JITSymbolFlags Flags = JITSymbolFlags::None;
  22. if (GV.hasWeakLinkage() || GV.hasLinkOnceLinkage())
  23. Flags |= JITSymbolFlags::Weak;
  24. if (GV.hasCommonLinkage())
  25. Flags |= JITSymbolFlags::Common;
  26. if (!GV.hasLocalLinkage() && !GV.hasHiddenVisibility())
  27. Flags |= JITSymbolFlags::Exported;
  28. if (isa<Function>(GV))
  29. Flags |= JITSymbolFlags::Callable;
  30. else if (isa<GlobalAlias>(GV) &&
  31. isa<Function>(cast<GlobalAlias>(GV).getAliasee()))
  32. Flags |= JITSymbolFlags::Callable;
  33. // Check for a linker-private-global-prefix on the symbol name, in which
  34. // case it must be marked as non-exported.
  35. if (auto *M = GV.getParent()) {
  36. const auto &DL = M->getDataLayout();
  37. StringRef LPGP = DL.getLinkerPrivateGlobalPrefix();
  38. if (!LPGP.empty() && GV.getName().front() == '\01' &&
  39. GV.getName().substr(1).startswith(LPGP))
  40. Flags &= ~JITSymbolFlags::Exported;
  41. }
  42. return Flags;
  43. }
  44. JITSymbolFlags llvm::JITSymbolFlags::fromSummary(GlobalValueSummary *S) {
  45. JITSymbolFlags Flags = JITSymbolFlags::None;
  46. auto L = S->linkage();
  47. if (GlobalValue::isWeakLinkage(L) || GlobalValue::isLinkOnceLinkage(L))
  48. Flags |= JITSymbolFlags::Weak;
  49. if (GlobalValue::isCommonLinkage(L))
  50. Flags |= JITSymbolFlags::Common;
  51. if (GlobalValue::isExternalLinkage(L) || GlobalValue::isExternalWeakLinkage(L))
  52. Flags |= JITSymbolFlags::Exported;
  53. if (isa<FunctionSummary>(S))
  54. Flags |= JITSymbolFlags::Callable;
  55. return Flags;
  56. }
  57. Expected<JITSymbolFlags>
  58. llvm::JITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
  59. Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();
  60. if (!SymbolFlagsOrErr)
  61. // TODO: Test this error.
  62. return SymbolFlagsOrErr.takeError();
  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. auto SymbolType = Symbol.getType();
  71. if (!SymbolType)
  72. return SymbolType.takeError();
  73. if (*SymbolType == object::SymbolRef::ST_Function)
  74. Flags |= JITSymbolFlags::Callable;
  75. return Flags;
  76. }
  77. ARMJITSymbolFlags
  78. llvm::ARMJITSymbolFlags::fromObjectSymbol(const object::SymbolRef &Symbol) {
  79. Expected<uint32_t> SymbolFlagsOrErr = Symbol.getFlags();
  80. if (!SymbolFlagsOrErr)
  81. // TODO: Actually report errors helpfully.
  82. report_fatal_error(SymbolFlagsOrErr.takeError());
  83. ARMJITSymbolFlags Flags;
  84. if (*SymbolFlagsOrErr & object::BasicSymbolRef::SF_Thumb)
  85. Flags |= ARMJITSymbolFlags::Thumb;
  86. return Flags;
  87. }
  88. /// Performs lookup by, for each symbol, first calling
  89. /// findSymbolInLogicalDylib and if that fails calling
  90. /// findSymbol.
  91. void LegacyJITSymbolResolver::lookup(const LookupSet &Symbols,
  92. OnResolvedFunction OnResolved) {
  93. JITSymbolResolver::LookupResult Result;
  94. for (auto &Symbol : Symbols) {
  95. std::string SymName = Symbol.str();
  96. if (auto Sym = findSymbolInLogicalDylib(SymName)) {
  97. if (auto AddrOrErr = Sym.getAddress())
  98. Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
  99. else {
  100. OnResolved(AddrOrErr.takeError());
  101. return;
  102. }
  103. } else if (auto Err = Sym.takeError()) {
  104. OnResolved(std::move(Err));
  105. return;
  106. } else {
  107. // findSymbolInLogicalDylib failed. Lets try findSymbol.
  108. if (auto Sym = findSymbol(SymName)) {
  109. if (auto AddrOrErr = Sym.getAddress())
  110. Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
  111. else {
  112. OnResolved(AddrOrErr.takeError());
  113. return;
  114. }
  115. } else if (auto Err = Sym.takeError()) {
  116. OnResolved(std::move(Err));
  117. return;
  118. } else {
  119. OnResolved(make_error<StringError>("Symbol not found: " + Symbol,
  120. inconvertibleErrorCode()));
  121. return;
  122. }
  123. }
  124. }
  125. OnResolved(std::move(Result));
  126. }
  127. /// Performs flags lookup by calling findSymbolInLogicalDylib and
  128. /// returning the flags value for that symbol.
  129. Expected<JITSymbolResolver::LookupSet>
  130. LegacyJITSymbolResolver::getResponsibilitySet(const LookupSet &Symbols) {
  131. JITSymbolResolver::LookupSet Result;
  132. for (auto &Symbol : Symbols) {
  133. std::string SymName = Symbol.str();
  134. if (auto Sym = findSymbolInLogicalDylib(SymName)) {
  135. // If there's an existing def but it is not strong, then the caller is
  136. // responsible for it.
  137. if (!Sym.getFlags().isStrong())
  138. Result.insert(Symbol);
  139. } else if (auto Err = Sym.takeError())
  140. return std::move(Err);
  141. else {
  142. // If there is no existing definition then the caller is responsible for
  143. // it.
  144. Result.insert(Symbol);
  145. }
  146. }
  147. return std::move(Result);
  148. }