LLVM 24.0.0git
COFFAutoImportGenerator.cpp
Go to the documentation of this file.
1//===- COFFAutoImportGenerator.cpp - COFF dllimport auto-import ---------===//
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
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/ADT/Twine.h"
14
15namespace llvm {
16namespace orc {
17
18Expected<std::unique_ptr<COFFAutoImportGenerator>>
20 DylibManager &DylibMgr, const char *LibraryPath) {
21 Triple TT = ES.getTargetTriple();
22
23 auto CreatePointer = jitlink::getAnonymousPointerCreator(TT);
24 if (!CreatePointer)
26 "COFFAutoImportGenerator: no pointer creator for " + TT.str(),
28
29 auto CreateStub = jitlink::getPointerJumpStubCreator(TT);
30 if (!CreateStub)
32 "COFFAutoImportGenerator: no stub creator for " + TT.str(),
34
35 auto LibHandle = DylibMgr.loadDylib(LibraryPath);
36 if (!LibHandle)
37 return LibHandle.takeError();
38
39 return std::unique_ptr<COFFAutoImportGenerator>(new COFFAutoImportGenerator(
40 ES, L, DylibMgr, *LibHandle, std::move(CreatePointer),
41 std::move(CreateStub)));
42}
43
45 JITDylib &JD,
46 JITDylibLookupFlags JDLookupFlags,
47 const SymbolLookupSet &Symbols) {
48 if (Symbols.empty())
49 return Error::success();
50
51 // Weakly reference each symbol (minus any __imp_ prefix) so unexported names
52 // are left unresolved; de-dup __imp_X and X into one lookup.
53 SymbolLookupSet LookupSymbols;
55 for (auto &KV : Symbols) {
56 StringRef Base = *KV.first;
57 if (Base.starts_with(getImpPrefix()))
58 Base = Base.drop_front(getImpPrefix().size());
59 SymbolStringPtr BaseName = ES.intern(Base);
60 if (Seen.insert(BaseName).second)
61 LookupSymbols.add(BaseName, SymbolLookupFlags::WeaklyReferencedSymbol);
62 }
63
64 DylibMgr.lookupSymbolsAsync(
65 LibHandle, LookupSymbols,
66 [this, &JD, LS = std::move(LS), LookupSymbols](auto Result) mutable {
67 if (!Result)
68 return LS.continueLookup(Result.takeError());
69
70 // Keep the exported (non-null) results.
72 for (auto [Sym, Addr] : llvm::zip_equal(LookupSymbols, *Result))
73 if (Addr && *Addr)
74 Resolved[Sym.first] = {*Addr, JITSymbolFlags::Exported |
76
77 if (Resolved.empty())
78 return LS.continueLookup(Error::success());
79
80 auto G = createStubsGraph(Resolved);
81 if (!G)
82 return LS.continueLookup(G.takeError());
83
84 // One tracker owns all stubs so they can be reclaimed together.
85 if (!ImportStubsRT || ImportStubsRT->isDefunct())
86 ImportStubsRT = JD.createResourceTracker();
87 LS.continueLookup(L.add(ImportStubsRT, std::move(*G)));
88 });
89
90 return Error::success();
91}
92
93// FIXME: Pull this into a helper shared with
94// DLLImportDefinitionGenerator::createStubsGraph (ExecutionUtils.cpp), which
95// builds the same __imp_X + thunk stubs. Until then, fixes here may need to
96// be mirrored there too.
98COFFAutoImportGenerator::createStubsGraph(const SymbolMap &Resolved) {
99 Triple TT = ES.getTargetTriple();
100
101 auto G = std::make_unique<jitlink::LinkGraph>(
102 "<AUTOIMPORT_STUBS>", ES.getSymbolStringPool(), TT, SubtargetFeatures(),
104 jitlink::Section &Sec =
105 G->createSection(getSectionName(), MemProt::Read | MemProt::Exec);
106
107 for (auto &KV : Resolved) {
108 // X's address as a local absolute symbol, referenced only by __imp_ (so it
109 // can't collide with the X thunk below).
110 jitlink::Symbol &Target = G->addAbsoluteSymbol(
111 *KV.first, KV.second.getAddress(), G->getPointerSize(),
113
114 // __imp_X: pointer slot holding X's address.
115 jitlink::Symbol &Ptr = CreatePointer(*G, Sec, &Target, 0);
116 Ptr.setName(G->intern((Twine(getImpPrefix()) + *KV.first).str()));
117 // Weak: a later real definition overrides this fallback (link.exe-style).
120
121 // X: thunk "jmpq *__imp_X(%rip)" so direct calls work too.
122 jitlink::Symbol &Stub = CreateStub(*G, Sec, Ptr);
123 Stub.setName(G->intern(*KV.first));
126 }
127
128 return std::move(G);
129}
130
131} // end namespace orc
132} // end namespace llvm
#define G(x, y, z)
Definition MD5.cpp:55
This file contains some templates that are useful if you are working with the STL at all.
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Manages the enabling and disabling of subtarget specific features.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
static Expected< std::unique_ptr< COFFAutoImportGenerator > > Load(ExecutionSession &ES, ObjectLinkingLayer &L, DylibManager &DylibMgr, const char *LibraryPath)
Loads the dynamic library at the given path in the executor (via the given DylibManager) and,...
Error tryToGenerate(LookupState &LS, LookupKind K, JITDylib &JD, JITDylibLookupFlags JDLookupFlags, const SymbolLookupSet &Symbols) override
DefinitionGenerators should override this method to insert new definitions into the parent JITDylib.
friend class ExecutionSession
Definition Core.h:633
const Triple & getTargetTriple() const
Return the triple for the executor.
Definition Core.h:1154
std::shared_ptr< SymbolStringPool > getSymbolStringPool()
Get the SymbolStringPool for this instance.
Definition Core.h:1160
Represents a JIT'd dynamic library.
Definition Core.h:675
LLVM_ABI ResourceTrackerSP createResourceTracker()
Create a resource tracker for this JITDylib.
Definition Core.cpp:670
Wraps state for a lookup-in-progress.
Definition Core.h:607
An ObjectLayer implementation built on JITLink.
A set of symbols to look up, each associated with a SymbolLookupFlags value.
SymbolLookupSet & add(SymbolStringPtr Name, SymbolLookupFlags Flags=SymbolLookupFlags::RequiredSymbol)
Add an element to the set.
Pointer to a pooled string representing a symbol name.
static constexpr const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
JITDylibLookupFlags
Lookup flags that apply to each dylib in the search order for a lookup.
Definition Core.h:132
DenseMap< SymbolStringPtr, ExecutorSymbolDef > SymbolMap
A map from symbol names (as SymbolStringPtrs) to JITSymbols (address/flags pairs).
LookupKind
Describes the kind of lookup being performed.
Definition Core.h:144
@ Resolved
Queried, materialization begun.
Definition Core.h:549
This is an optimization pass for GlobalISel generic memory operations.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition STLExtras.h:1669
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:840
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340