Skip to content

Commit b72f484

Browse files
committed
[ORC] Re-apply r322913 with a fix for a read-after-free error.
ExternalSymbolMap now stores the string key (rather than using a StringRef), as the object file backing the key may be removed at any time. llvm-svn: 323001
1 parent 8b2faee commit b72f484

17 files changed

+320
-202
lines changed

llvm/include/llvm/ExecutionEngine/ExecutionEngine.h

+9-12
Original file line numberDiff line numberDiff line change
@@ -137,17 +137,15 @@ class ExecutionEngine {
137137
virtual char *getMemoryForGV(const GlobalVariable *GV);
138138

139139
static ExecutionEngine *(*MCJITCtor)(
140-
std::unique_ptr<Module> M,
141-
std::string *ErrorStr,
142-
std::shared_ptr<MCJITMemoryManager> MM,
143-
std::shared_ptr<JITSymbolResolver> SR,
144-
std::unique_ptr<TargetMachine> TM);
140+
std::unique_ptr<Module> M, std::string *ErrorStr,
141+
std::shared_ptr<MCJITMemoryManager> MM,
142+
std::shared_ptr<LegacyJITSymbolResolver> SR,
143+
std::unique_ptr<TargetMachine> TM);
145144

146145
static ExecutionEngine *(*OrcMCJITReplacementCtor)(
147-
std::string *ErrorStr,
148-
std::shared_ptr<MCJITMemoryManager> MM,
149-
std::shared_ptr<JITSymbolResolver> SR,
150-
std::unique_ptr<TargetMachine> TM);
146+
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MM,
147+
std::shared_ptr<LegacyJITSymbolResolver> SR,
148+
std::unique_ptr<TargetMachine> TM);
151149

152150
static ExecutionEngine *(*InterpCtor)(std::unique_ptr<Module> M,
153151
std::string *ErrorStr);
@@ -532,7 +530,7 @@ class EngineBuilder {
532530
std::string *ErrorStr;
533531
CodeGenOpt::Level OptLevel;
534532
std::shared_ptr<MCJITMemoryManager> MemMgr;
535-
std::shared_ptr<JITSymbolResolver> Resolver;
533+
std::shared_ptr<LegacyJITSymbolResolver> Resolver;
536534
TargetOptions Options;
537535
Optional<Reloc::Model> RelocModel;
538536
Optional<CodeModel::Model> CMModel;
@@ -571,8 +569,7 @@ class EngineBuilder {
571569
EngineBuilder&
572570
setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM);
573571

574-
EngineBuilder&
575-
setSymbolResolver(std::unique_ptr<JITSymbolResolver> SR);
572+
EngineBuilder &setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR);
576573

577574
/// setErrorStr - Set the error string to write to on error. This option
578575
/// defaults to NULL.

llvm/include/llvm/ExecutionEngine/JITSymbol.h

+43-1
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,11 @@
1919
#include <cstddef>
2020
#include <cstdint>
2121
#include <functional>
22+
#include <map>
23+
#include <set>
2224
#include <string>
2325

26+
#include "llvm/ADT/StringRef.h"
2427
#include "llvm/Support/Error.h"
2528

2629
namespace llvm {
@@ -269,11 +272,50 @@ class JITSymbol {
269272
JITSymbolFlags Flags;
270273
};
271274

272-
/// \brief Symbol resolution.
275+
/// @brief Symbol resolution interface.
276+
///
277+
/// Allows symbol flags and addresses to be looked up by name.
278+
/// Symbol queries are done in bulk (i.e. you request resolution of a set of
279+
/// symbols, rather than a single one) to reduce IPC overhead in the case of
280+
/// remote JITing, and expose opportunities for parallel compilation.
273281
class JITSymbolResolver {
274282
public:
283+
using SymbolNameSet = std::set<StringRef>;
284+
using LookupResult = std::map<StringRef, JITEvaluatedSymbol>;
285+
using LookupFlagsResult = std::map<StringRef, JITSymbolFlags>;
286+
275287
virtual ~JITSymbolResolver() = default;
276288

289+
/// @brief Returns the fully resolved address and flags for each of the given
290+
/// symbols.
291+
///
292+
/// This method will return an error if any of the given symbols can not be
293+
/// resolved, or if the resolution process itself triggers an error.
294+
virtual Expected<LookupResult> lookup(const SymbolNameSet &Symbols) = 0;
295+
296+
/// @brief Returns the symbol flags for each of the given symbols.
297+
///
298+
/// This method does NOT return an error if any of the given symbols is
299+
/// missing. Instead, that symbol will be left out of the result map.
300+
virtual Expected<LookupFlagsResult>
301+
lookupFlags(const SymbolNameSet &Symbols) = 0;
302+
303+
private:
304+
virtual void anchor();
305+
};
306+
307+
/// \brief Legacy symbol resolution interface.
308+
class LegacyJITSymbolResolver : public JITSymbolResolver {
309+
public:
310+
/// @brief Performs lookup by, for each symbol, first calling
311+
/// findSymbolInLogicalDylib and if that fails calling
312+
/// findSymbol.
313+
Expected<LookupResult> lookup(const SymbolNameSet &Symbols) final;
314+
315+
/// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
316+
/// returning the flags value for that symbol.
317+
Expected<LookupFlagsResult> lookupFlags(const SymbolNameSet &Symbols) final;
318+
277319
/// This method returns the address of the specified symbol if it exists
278320
/// within the logical dynamic library represented by this JITSymbolResolver.
279321
/// Unlike findSymbol, queries through this interface should return addresses

llvm/include/llvm/ExecutionEngine/Orc/CompileOnDemandLayer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ class CompileOnDemandLayer {
183183
return Error::success();
184184
}
185185

186-
std::shared_ptr<JITSymbolResolver> ExternalSymbolResolver;
186+
std::shared_ptr<LegacyJITSymbolResolver> ExternalSymbolResolver;
187187
std::unique_ptr<IndirectStubsMgrT> StubsMgr;
188188
StaticGlobalRenamer StaticRenamer;
189189
SourceModulesList SourceModules;
@@ -223,7 +223,7 @@ class CompileOnDemandLayer {
223223
/// @brief Add a module to the compile-on-demand layer.
224224
Expected<ModuleHandleT>
225225
addModule(std::shared_ptr<Module> M,
226-
std::shared_ptr<JITSymbolResolver> Resolver) {
226+
std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
227227

228228
LogicalDylibs.push_back(LogicalDylib());
229229
auto &LD = LogicalDylibs.back();

llvm/include/llvm/ExecutionEngine/Orc/LambdaResolver.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace llvm {
2323
namespace orc {
2424

2525
template <typename DylibLookupFtorT, typename ExternalLookupFtorT>
26-
class LambdaResolver : public JITSymbolResolver {
26+
class LambdaResolver : public LegacyJITSymbolResolver {
2727
public:
2828
LambdaResolver(DylibLookupFtorT DylibLookupFtor,
2929
ExternalLookupFtorT ExternalLookupFtor)

llvm/include/llvm/ExecutionEngine/Orc/NullResolver.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ namespace orc {
2222

2323
/// SymbolResolver impliementation that rejects all resolution requests.
2424
/// Useful for clients that have no cross-object fixups.
25-
class NullResolver : public JITSymbolResolver {
25+
class NullResolver : public LegacyJITSymbolResolver {
2626
public:
2727
JITSymbol findSymbol(const std::string &Name) final;
2828

llvm/include/llvm/ExecutionEngine/Orc/RemoteObjectLayer.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,8 @@ class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
328328
/// @return A handle that can be used to refer to the loaded object (for
329329
/// symbol searching, finalization, freeing memory, etc.).
330330
Expected<ObjHandleT>
331-
addObject(ObjectPtr Object, std::shared_ptr<JITSymbolResolver> Resolver) {
331+
addObject(ObjectPtr Object,
332+
std::shared_ptr<LegacyJITSymbolResolver> Resolver) {
332333
StringRef ObjBuffer = Object->getBinary()->getData();
333334
if (auto HandleOrErr =
334335
this->Remote.template callB<AddObject>(ObjBuffer)) {
@@ -386,7 +387,8 @@ class RemoteObjectClientLayer : public RemoteObjectLayer<RPCEndpoint> {
386387
}
387388

388389
std::map<remote::ResourceIdMgr::ResourceId,
389-
std::shared_ptr<JITSymbolResolver>> Resolvers;
390+
std::shared_ptr<LegacyJITSymbolResolver>>
391+
Resolvers;
390392
};
391393

392394
/// RemoteObjectServerLayer acts as a server and handling RPC calls for the

llvm/include/llvm/ExecutionEngine/RTDyldMemoryManager.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ class MCJITMemoryManager : public RuntimeDyld::MemoryManager {
5656
// FIXME: As the RuntimeDyld fills out, additional routines will be needed
5757
// for the varying types of objects to be allocated.
5858
class RTDyldMemoryManager : public MCJITMemoryManager,
59-
public JITSymbolResolver {
59+
public LegacyJITSymbolResolver {
6060
public:
6161
RTDyldMemoryManager() = default;
6262
RTDyldMemoryManager(const RTDyldMemoryManager&) = delete;

llvm/lib/ExecutionEngine/ExecutionEngine.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,13 @@ STATISTIC(NumGlobals , "Number of global vars initialized");
4949
ExecutionEngine *(*ExecutionEngine::MCJITCtor)(
5050
std::unique_ptr<Module> M, std::string *ErrorStr,
5151
std::shared_ptr<MCJITMemoryManager> MemMgr,
52-
53-
std::shared_ptr<JITSymbolResolver> Resolver,
52+
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
5453
std::unique_ptr<TargetMachine> TM) = nullptr;
5554

5655
ExecutionEngine *(*ExecutionEngine::OrcMCJITReplacementCtor)(
57-
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
58-
std::shared_ptr<JITSymbolResolver> Resolver,
59-
std::unique_ptr<TargetMachine> TM) = nullptr;
56+
std::string *ErrorStr, std::shared_ptr<MCJITMemoryManager> MemMgr,
57+
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
58+
std::unique_ptr<TargetMachine> TM) = nullptr;
6059

6160
ExecutionEngine *(*ExecutionEngine::InterpCtor)(std::unique_ptr<Module> M,
6261
std::string *ErrorStr) =nullptr;
@@ -502,9 +501,9 @@ EngineBuilder::setMemoryManager(std::unique_ptr<MCJITMemoryManager> MM) {
502501
return *this;
503502
}
504503

505-
EngineBuilder&
506-
EngineBuilder::setSymbolResolver(std::unique_ptr<JITSymbolResolver> SR) {
507-
Resolver = std::shared_ptr<JITSymbolResolver>(std::move(SR));
504+
EngineBuilder &
505+
EngineBuilder::setSymbolResolver(std::unique_ptr<LegacyJITSymbolResolver> SR) {
506+
Resolver = std::shared_ptr<LegacyJITSymbolResolver>(std::move(SR));
508507
return *this;
509508
}
510509

llvm/lib/ExecutionEngine/MCJIT/MCJIT.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,10 @@ static struct RegisterJIT {
3939
extern "C" void LLVMLinkInMCJIT() {
4040
}
4141

42-
ExecutionEngine*
43-
MCJIT::createJIT(std::unique_ptr<Module> M,
44-
std::string *ErrorStr,
42+
ExecutionEngine *
43+
MCJIT::createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
4544
std::shared_ptr<MCJITMemoryManager> MemMgr,
46-
std::shared_ptr<JITSymbolResolver> Resolver,
45+
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
4746
std::unique_ptr<TargetMachine> TM) {
4847
// Try to register the program as a source of symbols to resolve against.
4948
//
@@ -64,7 +63,7 @@ MCJIT::createJIT(std::unique_ptr<Module> M,
6463

6564
MCJIT::MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> TM,
6665
std::shared_ptr<MCJITMemoryManager> MemMgr,
67-
std::shared_ptr<JITSymbolResolver> Resolver)
66+
std::shared_ptr<LegacyJITSymbolResolver> Resolver)
6867
: ExecutionEngine(TM->createDataLayout(), std::move(M)), TM(std::move(TM)),
6968
Ctx(nullptr), MemMgr(std::move(MemMgr)),
7069
Resolver(*this, std::move(Resolver)), Dyld(*this->MemMgr, this->Resolver),

llvm/lib/ExecutionEngine/MCJIT/MCJIT.h

+8-9
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ class MCJIT;
2626
// functions across modules that it owns. It aggregates the memory manager
2727
// that is passed in to the MCJIT constructor and defers most functionality
2828
// to that object.
29-
class LinkingSymbolResolver : public JITSymbolResolver {
29+
class LinkingSymbolResolver : public LegacyJITSymbolResolver {
3030
public:
3131
LinkingSymbolResolver(MCJIT &Parent,
32-
std::shared_ptr<JITSymbolResolver> Resolver)
33-
: ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
32+
std::shared_ptr<LegacyJITSymbolResolver> Resolver)
33+
: ParentEngine(Parent), ClientResolver(std::move(Resolver)) {}
3434

3535
JITSymbol findSymbol(const std::string &Name) override;
3636

@@ -41,7 +41,7 @@ class LinkingSymbolResolver : public JITSymbolResolver {
4141

4242
private:
4343
MCJIT &ParentEngine;
44-
std::shared_ptr<JITSymbolResolver> ClientResolver;
44+
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
4545
};
4646

4747
// About Module states: added->loaded->finalized.
@@ -67,7 +67,7 @@ class LinkingSymbolResolver : public JITSymbolResolver {
6767
class MCJIT : public ExecutionEngine {
6868
MCJIT(std::unique_ptr<Module> M, std::unique_ptr<TargetMachine> tm,
6969
std::shared_ptr<MCJITMemoryManager> MemMgr,
70-
std::shared_ptr<JITSymbolResolver> Resolver);
70+
std::shared_ptr<LegacyJITSymbolResolver> Resolver);
7171

7272
typedef llvm::SmallPtrSet<Module *, 4> ModulePtrSet;
7373

@@ -300,11 +300,10 @@ class MCJIT : public ExecutionEngine {
300300
MCJITCtor = createJIT;
301301
}
302302

303-
static ExecutionEngine*
304-
createJIT(std::unique_ptr<Module> M,
305-
std::string *ErrorStr,
303+
static ExecutionEngine *
304+
createJIT(std::unique_ptr<Module> M, std::string *ErrorStr,
306305
std::shared_ptr<MCJITMemoryManager> MemMgr,
307-
std::shared_ptr<JITSymbolResolver> Resolver,
306+
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
308307
std::unique_ptr<TargetMachine> TM);
309308

310309
// @}

llvm/lib/ExecutionEngine/Orc/OrcCBindingsStack.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ class OrcCBindingsStack {
196196
return mapError(IndirectStubsMgr->updatePointer(Name, Addr));
197197
}
198198

199-
std::shared_ptr<JITSymbolResolver>
199+
std::shared_ptr<LegacyJITSymbolResolver>
200200
createResolver(LLVMOrcSymbolResolverFn ExternalResolver,
201201
void *ExternalResolverCtx) {
202202
return orc::createLambdaResolver(

llvm/lib/ExecutionEngine/Orc/OrcMCJITReplacement.h

+8-9
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ class OrcMCJITReplacement : public ExecutionEngine {
138138
std::shared_ptr<MCJITMemoryManager> ClientMM;
139139
};
140140

141-
class LinkingResolver : public JITSymbolResolver {
141+
class LinkingResolver : public LegacyJITSymbolResolver {
142142
public:
143143
LinkingResolver(OrcMCJITReplacement &M) : M(M) {}
144144

@@ -160,20 +160,19 @@ class OrcMCJITReplacement : public ExecutionEngine {
160160
static ExecutionEngine *
161161
createOrcMCJITReplacement(std::string *ErrorMsg,
162162
std::shared_ptr<MCJITMemoryManager> MemMgr,
163-
std::shared_ptr<JITSymbolResolver> Resolver,
163+
std::shared_ptr<LegacyJITSymbolResolver> Resolver,
164164
std::unique_ptr<TargetMachine> TM) {
165165
return new OrcMCJITReplacement(std::move(MemMgr), std::move(Resolver),
166166
std::move(TM));
167167
}
168168

169169
public:
170-
OrcMCJITReplacement(
171-
std::shared_ptr<MCJITMemoryManager> MemMgr,
172-
std::shared_ptr<JITSymbolResolver> ClientResolver,
173-
std::unique_ptr<TargetMachine> TM)
170+
OrcMCJITReplacement(std::shared_ptr<MCJITMemoryManager> MemMgr,
171+
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver,
172+
std::unique_ptr<TargetMachine> TM)
174173
: ExecutionEngine(TM->createDataLayout()), TM(std::move(TM)),
175-
MemMgr(std::make_shared<MCJITReplacementMemMgr>(*this,
176-
std::move(MemMgr))),
174+
MemMgr(
175+
std::make_shared<MCJITReplacementMemMgr>(*this, std::move(MemMgr))),
177176
Resolver(std::make_shared<LinkingResolver>(*this)),
178177
ClientResolver(std::move(ClientResolver)), NotifyObjectLoaded(*this),
179178
NotifyFinalized(*this),
@@ -378,7 +377,7 @@ class OrcMCJITReplacement : public ExecutionEngine {
378377
std::unique_ptr<TargetMachine> TM;
379378
std::shared_ptr<MCJITReplacementMemMgr> MemMgr;
380379
std::shared_ptr<LinkingResolver> Resolver;
381-
std::shared_ptr<JITSymbolResolver> ClientResolver;
380+
std::shared_ptr<LegacyJITSymbolResolver> ClientResolver;
382381
Mangler Mang;
383382

384383
// IMPORTANT: ShouldDelete *must* come before LocalModules: The shared_ptr

llvm/lib/ExecutionEngine/RuntimeDyld/JITSymbol.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,53 @@ ARMJITSymbolFlags llvm::ARMJITSymbolFlags::fromObjectSymbol(
4747
Flags |= ARMJITSymbolFlags::Thumb;
4848
return Flags;
4949
}
50+
51+
/// @brief Performs lookup by, for each symbol, first calling
52+
/// findSymbolInLogicalDylib and if that fails calling
53+
/// findSymbol.
54+
Expected<JITSymbolResolver::LookupResult>
55+
LegacyJITSymbolResolver::lookup(const SymbolNameSet &Symbols) {
56+
JITSymbolResolver::LookupResult Result;
57+
for (auto &Symbol : Symbols) {
58+
std::string SymName = Symbol.str();
59+
if (auto Sym = findSymbolInLogicalDylib(SymName)) {
60+
if (auto AddrOrErr = Sym.getAddress())
61+
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
62+
else
63+
return AddrOrErr.takeError();
64+
} else if (auto Err = Sym.takeError())
65+
return std::move(Err);
66+
else {
67+
// findSymbolInLogicalDylib failed. Lets try findSymbol.
68+
if (auto Sym = findSymbol(SymName)) {
69+
if (auto AddrOrErr = Sym.getAddress())
70+
Result[Symbol] = JITEvaluatedSymbol(*AddrOrErr, Sym.getFlags());
71+
else
72+
return AddrOrErr.takeError();
73+
} else if (auto Err = Sym.takeError())
74+
return std::move(Err);
75+
else
76+
return make_error<StringError>("Symbol not found: " + Symbol,
77+
inconvertibleErrorCode());
78+
}
79+
}
80+
81+
return std::move(Result);
82+
}
83+
84+
/// @brief Performs flags lookup by calling findSymbolInLogicalDylib and
85+
/// returning the flags value for that symbol.
86+
Expected<JITSymbolResolver::LookupFlagsResult>
87+
LegacyJITSymbolResolver::lookupFlags(const SymbolNameSet &Symbols) {
88+
JITSymbolResolver::LookupFlagsResult Result;
89+
90+
for (auto &Symbol : Symbols) {
91+
std::string SymName = Symbol.str();
92+
if (auto Sym = findSymbolInLogicalDylib(SymName))
93+
Result[Symbol] = Sym.getFlags();
94+
else if (auto Err = Sym.takeError())
95+
return std::move(Err);
96+
}
97+
98+
return std::move(Result);
99+
}

0 commit comments

Comments
 (0)