1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-22 18:54:02 +01:00

[ORC] Strip weak flags from a symbol once it is selected for materialization.

Once a symbol has been selected for materialization it can no longer be
overridden. Stripping the weak flag guarantees this (override attempts will
then be treated as duplicate definitions and result in a DuplicateDefinition
error).

llvm-svn: 334771
This commit is contained in:
Lang Hames 2018-06-14 21:16:29 +00:00
parent e567892d10
commit a86b02ba7f
2 changed files with 51 additions and 3 deletions

View File

@ -468,6 +468,8 @@ void VSO::resolve(const SymbolMap &Resolved) {
for (const auto &KV : Resolved) {
auto &Name = KV.first;
auto Sym = KV.second;
JITSymbolFlags ResolvedFlags = Sym.getFlags();
ResolvedFlags &= ~JITSymbolFlags::Weak;
assert(!Sym.getFlags().isLazy() && !Sym.getFlags().isMaterializing() &&
"Materializing flags should be managed internally");
@ -480,13 +482,11 @@ void VSO::resolve(const SymbolMap &Resolved) {
"Symbol should be materializing");
assert(I->second.getAddress() == 0 && "Symbol has already been resolved");
assert(Sym.getFlags() ==
assert(ResolvedFlags ==
JITSymbolFlags::stripTransientFlags(I->second.getFlags()) &&
"Resolved flags should match the declared flags");
// Once resolved, symbols can never be weak.
JITSymbolFlags ResolvedFlags = Sym.getFlags();
ResolvedFlags &= ~JITSymbolFlags::Weak;
ResolvedFlags |= JITSymbolFlags::Materializing;
I->second = JITEvaluatedSymbol(Sym.getAddress(), ResolvedFlags);
@ -748,6 +748,7 @@ void VSO::lookupImpl(std::shared_ptr<AsynchronousSymbolQuery> &Q,
for (auto &KV : MU->getSymbols()) {
auto SymK = Symbols.find(KV.first);
auto Flags = SymK->second.getFlags();
Flags &= ~JITSymbolFlags::Weak;
Flags &= ~JITSymbolFlags::Lazy;
Flags |= JITSymbolFlags::Materializing;
SymK->second.setFlags(Flags);

View File

@ -10,6 +10,7 @@
#include "OrcTestCommon.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/ExecutionEngine/Orc/Core.h"
#include "llvm/ExecutionEngine/Orc/OrcError.h"
#include "gtest/gtest.h"
#include <set>
@ -768,4 +769,50 @@ TEST(CoreAPIsTest, TestGetRequestedSymbolsAndDelegate) {
EXPECT_TRUE(BarMaterialized) << "Bar should be materialized now";
}
TEST(CoreAPIsTest, TestMaterializeWeakSymbol) {
// Confirm that once a weak definition is selected for materialization it is
// treated as strong.
constexpr JITTargetAddress FakeFooAddr = 0xdeadbeef;
JITSymbolFlags FooFlags = JITSymbolFlags::Exported;
FooFlags &= JITSymbolFlags::Weak;
auto FooSym = JITEvaluatedSymbol(FakeFooAddr, FooFlags);
ExecutionSession ES;
auto Foo = ES.getSymbolStringPool().intern("foo");
auto &V = ES.createVSO("V");
std::unique_ptr<MaterializationResponsibility> FooResponsibility;
auto MU = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, FooFlags}}), [&](MaterializationResponsibility R) {
FooResponsibility =
llvm::make_unique<MaterializationResponsibility>(std::move(R));
});
cantFail(V.define(MU));
auto Q = std::make_shared<AsynchronousSymbolQuery>(
SymbolNameSet({Foo}),
[](Expected<AsynchronousSymbolQuery::ResolutionResult> R) {
cantFail(std::move(R));
},
[](Error Err) { cantFail(std::move(Err)); });
V.lookup(std::move(Q), SymbolNameSet({Foo}));
auto MU2 = llvm::make_unique<SimpleMaterializationUnit>(
SymbolFlagsMap({{Foo, JITSymbolFlags::Exported}}),
[](MaterializationResponsibility R) {
llvm_unreachable("This unit should never be materialized");
});
auto Err = V.define(MU2);
EXPECT_TRUE(!!Err) << "Expected failure value";
EXPECT_TRUE(Err.isA<DuplicateDefinition>())
<< "Expected a duplicate definition error";
consumeError(std::move(Err));
FooResponsibility->resolve(SymbolMap({{Foo, FooSym}}));
FooResponsibility->finalize();
}
} // namespace