[llvm] [ORC] Add AutoImportGenerator for COFF dllimport auto-import (PR #203914)

Lang Hames via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 31 04:37:02 PDT 2026


================
@@ -583,5 +584,117 @@ DLLImportDefinitionGenerator::createStubsGraph(const SymbolMap &Resolved) {
   return std::move(G);
 }
 
+Expected<std::unique_ptr<AutoImportGenerator>>
+AutoImportGenerator::Load(ExecutionSession &ES, ObjectLinkingLayer &L,
+                          DylibManager &DylibMgr, const char *LibraryPath) {
+  // x86_64-only for now: createStubsGraph emits x86_64 pointer slots / stubs.
+  if (ES.getTargetTriple().getArch() != Triple::x86_64)
+    return make_error<StringError>(
+        "AutoImportGenerator currently only supports x86_64",
+        inconvertibleErrorCode());
+
+  auto LibHandle = DylibMgr.loadDylib(LibraryPath);
+  if (!LibHandle)
+    return LibHandle.takeError();
+
+  return std::unique_ptr<AutoImportGenerator>(
+      new AutoImportGenerator(ES, L, DylibMgr, *LibHandle));
+}
+
+Error AutoImportGenerator::tryToGenerate(LookupState &LS, LookupKind K,
+                                         JITDylib &JD,
+                                         JITDylibLookupFlags JDLookupFlags,
+                                         const SymbolLookupSet &Symbols) {
+  if (Symbols.empty())
+    return Error::success();
+
+  // Weakly reference each symbol (minus any __imp_ prefix) so unexported names
+  // are left unresolved; de-dup __imp_X and X into one lookup.
+  SymbolLookupSet LookupSymbols;
+  DenseSet<SymbolStringPtr> Seen;
+  for (auto &KV : Symbols) {
+    StringRef Base = *KV.first;
+    if (Base.starts_with(getImpPrefix()))
+      Base = Base.drop_front(getImpPrefix().size());
+    SymbolStringPtr BaseName = ES.intern(Base);
+    if (Seen.insert(BaseName).second)
+      LookupSymbols.add(BaseName, SymbolLookupFlags::WeaklyReferencedSymbol);
+  }
+
+  DylibMgr.lookupSymbolsAsync(
+      LibHandle, LookupSymbols,
+      [this, &JD, LS = std::move(LS), LookupSymbols](auto Result) mutable {
+        if (!Result)
+          return LS.continueLookup(Result.takeError());
+
+        // Keep the exported (non-null) results.
+        SymbolMap Resolved;
+        for (auto [Sym, Addr] : llvm::zip_equal(LookupSymbols, *Result))
+          if (Addr && *Addr)
+            Resolved[Sym.first] = {*Addr, JITSymbolFlags::Exported |
+                                              JITSymbolFlags::Callable};
+
+        if (Resolved.empty())
+          return LS.continueLookup(Error::success());
+
+        auto G = createStubsGraph(Resolved);
+        if (!G)
+          return LS.continueLookup(G.takeError());
+
+        // One tracker owns all stubs so they can be reclaimed together.
+        if (!ImportStubsRT || ImportStubsRT->isDefunct())
----------------
lhames wrote:

No -- this should be fine: `isDefunct` checks the tracker state under the session lock.

https://github.com/llvm/llvm-project/pull/203914


More information about the llvm-commits mailing list