ObjectLinkingLayer.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. //===------- ObjectLinkingLayer.cpp - JITLink backed ORC ObjectLayer ------===//
  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. #include "llvm/ExecutionEngine/Orc/ObjectLinkingLayer.h"
  9. #include "llvm/ADT/Optional.h"
  10. #include "llvm/ExecutionEngine/JITLink/EHFrameSupport.h"
  11. #include <vector>
  12. #define DEBUG_TYPE "orc"
  13. using namespace llvm;
  14. using namespace llvm::jitlink;
  15. using namespace llvm::orc;
  16. namespace llvm {
  17. namespace orc {
  18. class ObjectLinkingLayerJITLinkContext final : public JITLinkContext {
  19. public:
  20. ObjectLinkingLayerJITLinkContext(ObjectLinkingLayer &Layer,
  21. MaterializationResponsibility MR,
  22. std::unique_ptr<MemoryBuffer> ObjBuffer)
  23. : Layer(Layer), MR(std::move(MR)), ObjBuffer(std::move(ObjBuffer)) {}
  24. JITLinkMemoryManager &getMemoryManager() override { return Layer.MemMgr; }
  25. MemoryBufferRef getObjectBuffer() const override {
  26. return ObjBuffer->getMemBufferRef();
  27. }
  28. void notifyFailed(Error Err) override {
  29. Layer.getExecutionSession().reportError(std::move(Err));
  30. MR.failMaterialization();
  31. }
  32. void lookup(const DenseSet<StringRef> &Symbols,
  33. std::unique_ptr<JITLinkAsyncLookupContinuation> LC) override {
  34. JITDylibSearchList SearchOrder;
  35. MR.getTargetJITDylib().withSearchOrderDo(
  36. [&](const JITDylibSearchList &JDs) { SearchOrder = JDs; });
  37. auto &ES = Layer.getExecutionSession();
  38. SymbolNameSet InternedSymbols;
  39. for (auto &S : Symbols)
  40. InternedSymbols.insert(ES.intern(S));
  41. // OnResolve -- De-intern the symbols and pass the result to the linker.
  42. auto OnResolve = [this, LookupContinuation = std::move(LC)](
  43. Expected<SymbolMap> Result) mutable {
  44. auto Main = Layer.getExecutionSession().intern("_main");
  45. if (!Result)
  46. LookupContinuation->run(Result.takeError());
  47. else {
  48. AsyncLookupResult LR;
  49. for (auto &KV : *Result)
  50. LR[*KV.first] = KV.second;
  51. LookupContinuation->run(std::move(LR));
  52. }
  53. };
  54. ES.lookup(SearchOrder, std::move(InternedSymbols), SymbolState::Resolved,
  55. std::move(OnResolve), [this](const SymbolDependenceMap &Deps) {
  56. registerDependencies(Deps);
  57. });
  58. }
  59. void notifyResolved(LinkGraph &G) override {
  60. auto &ES = Layer.getExecutionSession();
  61. SymbolFlagsMap ExtraSymbolsToClaim;
  62. bool AutoClaim = Layer.AutoClaimObjectSymbols;
  63. SymbolMap InternedResult;
  64. for (auto *Sym : G.defined_symbols())
  65. if (Sym->hasName() && Sym->getScope() != Scope::Local) {
  66. auto InternedName = ES.intern(Sym->getName());
  67. JITSymbolFlags Flags;
  68. if (Sym->isCallable())
  69. Flags |= JITSymbolFlags::Callable;
  70. if (Sym->getScope() == Scope::Default)
  71. Flags |= JITSymbolFlags::Exported;
  72. InternedResult[InternedName] =
  73. JITEvaluatedSymbol(Sym->getAddress(), Flags);
  74. if (AutoClaim && !MR.getSymbols().count(InternedName)) {
  75. assert(!ExtraSymbolsToClaim.count(InternedName) &&
  76. "Duplicate symbol to claim?");
  77. ExtraSymbolsToClaim[InternedName] = Flags;
  78. }
  79. }
  80. for (auto *Sym : G.absolute_symbols())
  81. if (Sym->hasName()) {
  82. auto InternedName = ES.intern(Sym->getName());
  83. JITSymbolFlags Flags;
  84. Flags |= JITSymbolFlags::Absolute;
  85. if (Sym->isCallable())
  86. Flags |= JITSymbolFlags::Callable;
  87. if (Sym->getLinkage() == Linkage::Weak)
  88. Flags |= JITSymbolFlags::Weak;
  89. InternedResult[InternedName] =
  90. JITEvaluatedSymbol(Sym->getAddress(), Flags);
  91. if (AutoClaim && !MR.getSymbols().count(InternedName)) {
  92. assert(!ExtraSymbolsToClaim.count(InternedName) &&
  93. "Duplicate symbol to claim?");
  94. ExtraSymbolsToClaim[InternedName] = Flags;
  95. }
  96. }
  97. if (!ExtraSymbolsToClaim.empty())
  98. if (auto Err = MR.defineMaterializing(ExtraSymbolsToClaim))
  99. return notifyFailed(std::move(Err));
  100. if (auto Err = MR.notifyResolved(InternedResult)) {
  101. Layer.getExecutionSession().reportError(std::move(Err));
  102. MR.failMaterialization();
  103. return;
  104. }
  105. Layer.notifyLoaded(MR);
  106. }
  107. void notifyFinalized(
  108. std::unique_ptr<JITLinkMemoryManager::Allocation> A) override {
  109. if (auto Err = Layer.notifyEmitted(MR, std::move(A))) {
  110. Layer.getExecutionSession().reportError(std::move(Err));
  111. MR.failMaterialization();
  112. return;
  113. }
  114. if (auto Err = MR.notifyEmitted()) {
  115. Layer.getExecutionSession().reportError(std::move(Err));
  116. MR.failMaterialization();
  117. }
  118. }
  119. LinkGraphPassFunction getMarkLivePass(const Triple &TT) const override {
  120. return [this](LinkGraph &G) { return markResponsibilitySymbolsLive(G); };
  121. }
  122. Error modifyPassConfig(const Triple &TT, PassConfiguration &Config) override {
  123. // Add passes to mark duplicate defs as should-discard, and to walk the
  124. // link graph to build the symbol dependence graph.
  125. Config.PrePrunePasses.push_back(
  126. [this](LinkGraph &G) { return externalizeWeakAndCommonSymbols(G); });
  127. Config.PostPrunePasses.push_back(
  128. [this](LinkGraph &G) { return computeNamedSymbolDependencies(G); });
  129. Layer.modifyPassConfig(MR, TT, Config);
  130. return Error::success();
  131. }
  132. private:
  133. using AnonToNamedDependenciesMap = DenseMap<const Symbol *, SymbolNameSet>;
  134. Error externalizeWeakAndCommonSymbols(LinkGraph &G) {
  135. auto &ES = Layer.getExecutionSession();
  136. for (auto *Sym : G.defined_symbols())
  137. if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
  138. if (!MR.getSymbols().count(ES.intern(Sym->getName())))
  139. G.makeExternal(*Sym);
  140. }
  141. for (auto *Sym : G.absolute_symbols())
  142. if (Sym->hasName() && Sym->getLinkage() == Linkage::Weak) {
  143. if (!MR.getSymbols().count(ES.intern(Sym->getName())))
  144. G.makeExternal(*Sym);
  145. }
  146. return Error::success();
  147. }
  148. Error markResponsibilitySymbolsLive(LinkGraph &G) const {
  149. auto &ES = Layer.getExecutionSession();
  150. for (auto *Sym : G.defined_symbols())
  151. if (Sym->hasName() && MR.getSymbols().count(ES.intern(Sym->getName())))
  152. Sym->setLive(true);
  153. return Error::success();
  154. }
  155. Error computeNamedSymbolDependencies(LinkGraph &G) {
  156. auto &ES = MR.getTargetJITDylib().getExecutionSession();
  157. auto AnonDeps = computeAnonDeps(G);
  158. for (auto *Sym : G.defined_symbols()) {
  159. // Skip anonymous and non-global atoms: we do not need dependencies for
  160. // these.
  161. if (Sym->getScope() == Scope::Local)
  162. continue;
  163. auto SymName = ES.intern(Sym->getName());
  164. SymbolNameSet &SymDeps = NamedSymbolDeps[SymName];
  165. for (auto &E : Sym->getBlock().edges()) {
  166. auto &TargetSym = E.getTarget();
  167. if (TargetSym.getScope() != Scope::Local)
  168. SymDeps.insert(ES.intern(TargetSym.getName()));
  169. else {
  170. assert(TargetSym.isDefined() &&
  171. "Anonymous/local symbols must be defined");
  172. auto I = AnonDeps.find(&TargetSym);
  173. if (I != AnonDeps.end())
  174. for (auto &S : I->second)
  175. SymDeps.insert(S);
  176. }
  177. }
  178. }
  179. return Error::success();
  180. }
  181. AnonToNamedDependenciesMap computeAnonDeps(LinkGraph &G) {
  182. auto &ES = MR.getTargetJITDylib().getExecutionSession();
  183. AnonToNamedDependenciesMap DepMap;
  184. // For all anonymous symbols:
  185. // (1) Add their named dependencies.
  186. // (2) Add them to the worklist for further iteration if they have any
  187. // depend on any other anonymous symbols.
  188. struct WorklistEntry {
  189. WorklistEntry(Symbol *Sym, DenseSet<Symbol *> SymAnonDeps)
  190. : Sym(Sym), SymAnonDeps(std::move(SymAnonDeps)) {}
  191. Symbol *Sym = nullptr;
  192. DenseSet<Symbol *> SymAnonDeps;
  193. };
  194. std::vector<WorklistEntry> Worklist;
  195. for (auto *Sym : G.defined_symbols())
  196. if (!Sym->hasName()) {
  197. auto &SymNamedDeps = DepMap[Sym];
  198. DenseSet<Symbol *> SymAnonDeps;
  199. for (auto &E : Sym->getBlock().edges()) {
  200. auto &TargetSym = E.getTarget();
  201. if (TargetSym.hasName())
  202. SymNamedDeps.insert(ES.intern(TargetSym.getName()));
  203. else {
  204. assert(TargetSym.isDefined() &&
  205. "Anonymous symbols must be defined");
  206. SymAnonDeps.insert(&TargetSym);
  207. }
  208. }
  209. if (!SymAnonDeps.empty())
  210. Worklist.push_back(WorklistEntry(Sym, std::move(SymAnonDeps)));
  211. }
  212. // Loop over all anonymous symbols with anonymous dependencies, propagating
  213. // their respective *named* dependencies. Iterate until we hit a stable
  214. // state.
  215. bool Changed;
  216. do {
  217. Changed = false;
  218. for (auto &WLEntry : Worklist) {
  219. auto *Sym = WLEntry.Sym;
  220. auto &SymNamedDeps = DepMap[Sym];
  221. auto &SymAnonDeps = WLEntry.SymAnonDeps;
  222. for (auto *TargetSym : SymAnonDeps) {
  223. auto I = DepMap.find(TargetSym);
  224. if (I != DepMap.end())
  225. for (const auto &S : I->second)
  226. Changed |= SymNamedDeps.insert(S).second;
  227. }
  228. }
  229. } while (Changed);
  230. return DepMap;
  231. }
  232. void registerDependencies(const SymbolDependenceMap &QueryDeps) {
  233. for (auto &NamedDepsEntry : NamedSymbolDeps) {
  234. auto &Name = NamedDepsEntry.first;
  235. auto &NameDeps = NamedDepsEntry.second;
  236. SymbolDependenceMap SymbolDeps;
  237. for (const auto &QueryDepsEntry : QueryDeps) {
  238. JITDylib &SourceJD = *QueryDepsEntry.first;
  239. const SymbolNameSet &Symbols = QueryDepsEntry.second;
  240. auto &DepsForJD = SymbolDeps[&SourceJD];
  241. for (const auto &S : Symbols)
  242. if (NameDeps.count(S))
  243. DepsForJD.insert(S);
  244. if (DepsForJD.empty())
  245. SymbolDeps.erase(&SourceJD);
  246. }
  247. MR.addDependencies(Name, SymbolDeps);
  248. }
  249. }
  250. ObjectLinkingLayer &Layer;
  251. MaterializationResponsibility MR;
  252. std::unique_ptr<MemoryBuffer> ObjBuffer;
  253. DenseMap<SymbolStringPtr, SymbolNameSet> NamedSymbolDeps;
  254. };
  255. ObjectLinkingLayer::Plugin::~Plugin() {}
  256. ObjectLinkingLayer::ObjectLinkingLayer(ExecutionSession &ES,
  257. JITLinkMemoryManager &MemMgr)
  258. : ObjectLayer(ES), MemMgr(MemMgr) {}
  259. ObjectLinkingLayer::~ObjectLinkingLayer() {
  260. if (auto Err = removeAllModules())
  261. getExecutionSession().reportError(std::move(Err));
  262. }
  263. void ObjectLinkingLayer::emit(MaterializationResponsibility R,
  264. std::unique_ptr<MemoryBuffer> O) {
  265. assert(O && "Object must not be null");
  266. jitLink(std::make_unique<ObjectLinkingLayerJITLinkContext>(
  267. *this, std::move(R), std::move(O)));
  268. }
  269. void ObjectLinkingLayer::modifyPassConfig(MaterializationResponsibility &MR,
  270. const Triple &TT,
  271. PassConfiguration &PassConfig) {
  272. for (auto &P : Plugins)
  273. P->modifyPassConfig(MR, TT, PassConfig);
  274. }
  275. void ObjectLinkingLayer::notifyLoaded(MaterializationResponsibility &MR) {
  276. for (auto &P : Plugins)
  277. P->notifyLoaded(MR);
  278. }
  279. Error ObjectLinkingLayer::notifyEmitted(MaterializationResponsibility &MR,
  280. AllocPtr Alloc) {
  281. Error Err = Error::success();
  282. for (auto &P : Plugins)
  283. Err = joinErrors(std::move(Err), P->notifyEmitted(MR));
  284. if (Err)
  285. return Err;
  286. {
  287. std::lock_guard<std::mutex> Lock(LayerMutex);
  288. UntrackedAllocs.push_back(std::move(Alloc));
  289. }
  290. return Error::success();
  291. }
  292. Error ObjectLinkingLayer::removeModule(VModuleKey K) {
  293. Error Err = Error::success();
  294. for (auto &P : Plugins)
  295. Err = joinErrors(std::move(Err), P->notifyRemovingModule(K));
  296. AllocPtr Alloc;
  297. {
  298. std::lock_guard<std::mutex> Lock(LayerMutex);
  299. auto AllocItr = TrackedAllocs.find(K);
  300. Alloc = std::move(AllocItr->second);
  301. TrackedAllocs.erase(AllocItr);
  302. }
  303. assert(Alloc && "No allocation for key K");
  304. return joinErrors(std::move(Err), Alloc->deallocate());
  305. }
  306. Error ObjectLinkingLayer::removeAllModules() {
  307. Error Err = Error::success();
  308. for (auto &P : Plugins)
  309. Err = joinErrors(std::move(Err), P->notifyRemovingAllModules());
  310. std::vector<AllocPtr> Allocs;
  311. {
  312. std::lock_guard<std::mutex> Lock(LayerMutex);
  313. Allocs = std::move(UntrackedAllocs);
  314. for (auto &KV : TrackedAllocs)
  315. Allocs.push_back(std::move(KV.second));
  316. TrackedAllocs.clear();
  317. }
  318. while (!Allocs.empty()) {
  319. Err = joinErrors(std::move(Err), Allocs.back()->deallocate());
  320. Allocs.pop_back();
  321. }
  322. return Err;
  323. }
  324. EHFrameRegistrationPlugin::EHFrameRegistrationPlugin(
  325. EHFrameRegistrar &Registrar)
  326. : Registrar(Registrar) {}
  327. void EHFrameRegistrationPlugin::modifyPassConfig(
  328. MaterializationResponsibility &MR, const Triple &TT,
  329. PassConfiguration &PassConfig) {
  330. assert(!InProcessLinks.count(&MR) && "Link for MR already being tracked?");
  331. PassConfig.PostFixupPasses.push_back(
  332. createEHFrameRecorderPass(TT, [this, &MR](JITTargetAddress Addr,
  333. size_t Size) {
  334. if (Addr)
  335. InProcessLinks[&MR] = { Addr, Size };
  336. }));
  337. }
  338. Error EHFrameRegistrationPlugin::notifyEmitted(
  339. MaterializationResponsibility &MR) {
  340. auto EHFrameRangeItr = InProcessLinks.find(&MR);
  341. if (EHFrameRangeItr == InProcessLinks.end())
  342. return Error::success();
  343. auto EHFrameRange = EHFrameRangeItr->second;
  344. assert(EHFrameRange.Addr &&
  345. "eh-frame addr to register can not be null");
  346. InProcessLinks.erase(EHFrameRangeItr);
  347. if (auto Key = MR.getVModuleKey())
  348. TrackedEHFrameRanges[Key] = EHFrameRange;
  349. else
  350. UntrackedEHFrameRanges.push_back(EHFrameRange);
  351. return Registrar.registerEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
  352. }
  353. Error EHFrameRegistrationPlugin::notifyRemovingModule(VModuleKey K) {
  354. auto EHFrameRangeItr = TrackedEHFrameRanges.find(K);
  355. if (EHFrameRangeItr == TrackedEHFrameRanges.end())
  356. return Error::success();
  357. auto EHFrameRange = EHFrameRangeItr->second;
  358. assert(EHFrameRange.Addr && "Tracked eh-frame range must not be null");
  359. TrackedEHFrameRanges.erase(EHFrameRangeItr);
  360. return Registrar.deregisterEHFrames(EHFrameRange.Addr, EHFrameRange.Size);
  361. }
  362. Error EHFrameRegistrationPlugin::notifyRemovingAllModules() {
  363. std::vector<EHFrameRange> EHFrameRanges =
  364. std::move(UntrackedEHFrameRanges);
  365. EHFrameRanges.reserve(EHFrameRanges.size() + TrackedEHFrameRanges.size());
  366. for (auto &KV : TrackedEHFrameRanges)
  367. EHFrameRanges.push_back(KV.second);
  368. TrackedEHFrameRanges.clear();
  369. Error Err = Error::success();
  370. while (!EHFrameRanges.empty()) {
  371. auto EHFrameRange = EHFrameRanges.back();
  372. assert(EHFrameRange.Addr && "Untracked eh-frame range must not be null");
  373. EHFrameRanges.pop_back();
  374. Err = joinErrors(std::move(Err),
  375. Registrar.deregisterEHFrames(EHFrameRange.Addr,
  376. EHFrameRange.Size));
  377. }
  378. return Err;
  379. }
  380. } // End namespace orc.
  381. } // End namespace llvm.