mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[llvm-jitlink] Add -phony-externals option to suppress unresolved externals.
The -phony-externals option adds a generator which explicitly defines any otherwise unresolved externals as null. This transforms link-time unresolved-symbol errors into potential runtime null pointer accesses (if an unresolved external is actually accessed during execution). This option can be useful in -harness mode to avoid having to mock a large number of symbols that are not reachable at runtime (e.g. unused methods referenced by a class vtable).
This commit is contained in:
parent
f9871c7f15
commit
b014cb8f2f
@ -337,12 +337,6 @@ void JITLinkerBase::applyLookupResult(AsyncLookupResult Result) {
|
||||
dbgs() << " " << Sym->getName() << ": "
|
||||
<< formatv("{0:x16}", Sym->getAddress()) << "\n";
|
||||
});
|
||||
assert(llvm::all_of(G->external_symbols(),
|
||||
[](Symbol *Sym) {
|
||||
return Sym->getAddress() != 0 ||
|
||||
Sym->getLinkage() == Linkage::Weak;
|
||||
}) &&
|
||||
"All strong external symbols should have been resolved by now");
|
||||
}
|
||||
|
||||
void JITLinkerBase::copyBlockContentToWorkingMemory(
|
||||
|
@ -27,6 +27,7 @@ _used_weak:
|
||||
.p2align 4, 0x90
|
||||
_public_func_to_test:
|
||||
callq _used_weak
|
||||
callq _used_unresolved_external
|
||||
jmp _public_func_to_interpose
|
||||
|
||||
.p2align 4, 0x90
|
||||
|
@ -3,7 +3,9 @@
|
||||
# RUN: -o %t/file_to_test.o %S/Inputs/MachO_test_harness_test.s
|
||||
# RUN: llvm-mc -triple=x86_64-apple-macosx10.9 -filetype=obj \
|
||||
# RUN: -o %t/test_harness.o %s
|
||||
# RUN: llvm-jitlink -noexec -check %s %t/file_to_test.o \
|
||||
# RUN: not llvm-jitlink -noexec -check %s %t/file_to_test.o \
|
||||
# RUN: -harness %t/test_harness.o
|
||||
# RUN: llvm-jitlink -noexec -phony-externals -check %s %t/file_to_test.o \
|
||||
# RUN: -harness %t/test_harness.o
|
||||
#
|
||||
# Check that we
|
||||
|
@ -132,6 +132,11 @@ static cl::opt<bool> ShowRelocatedSectionContents(
|
||||
cl::desc("show section contents after fixups have been applied"),
|
||||
cl::init(false));
|
||||
|
||||
static cl::opt<bool> PhonyExternals(
|
||||
"phony-externals",
|
||||
cl::desc("resolve all otherwise unresolved externals to null"),
|
||||
cl::init(false));
|
||||
|
||||
ExitOnError ExitOnErr;
|
||||
|
||||
namespace llvm {
|
||||
@ -179,9 +184,9 @@ static Error applyHarnessPromotions(Session &S, LinkGraph &G) {
|
||||
|
||||
LLVM_DEBUG(dbgs() << "Appling promotions to graph " << G.getName() << "\n");
|
||||
|
||||
// If it isn't then promote any symbols referenced by the harness to default
|
||||
// scope, remove all symbols that clash with harness definitions, and demote
|
||||
// all others.
|
||||
// If this graph is part of the test then promote any symbols referenced by
|
||||
// the harness to default scope, remove all symbols that clash with harness
|
||||
// definitions, demote all other definitions.
|
||||
std::vector<Symbol *> DefinitionsToRemove;
|
||||
for (auto *Sym : G.defined_symbols()) {
|
||||
|
||||
@ -560,6 +565,18 @@ Error LLVMJITLinkObjectLinkingLayer::add(JITDylib &JD,
|
||||
return JD.define(std::move(MU));
|
||||
}
|
||||
|
||||
class PhonyExternalsGenerator : public JITDylib::DefinitionGenerator {
|
||||
public:
|
||||
Error tryToGenerate(LookupKind K, JITDylib &JD,
|
||||
JITDylibLookupFlags JDLookupFlags,
|
||||
const SymbolLookupSet &LookupSet) override {
|
||||
SymbolMap PhonySymbols;
|
||||
for (auto &KV : LookupSet)
|
||||
PhonySymbols[KV.first] = JITEvaluatedSymbol(0, JITSymbolFlags::Exported);
|
||||
return JD.define(absoluteSymbols(std::move(PhonySymbols)));
|
||||
}
|
||||
};
|
||||
|
||||
Expected<std::unique_ptr<Session>> Session::Create(Triple TT) {
|
||||
Error Err = Error::success();
|
||||
std::unique_ptr<Session> S(new Session(std::move(TT), Err));
|
||||
@ -813,6 +830,10 @@ Error loadDylibs() {
|
||||
return Error::success();
|
||||
}
|
||||
|
||||
void addPhonyExternalsGenerator(Session &S) {
|
||||
S.MainJD->addGenerator(std::make_unique<PhonyExternalsGenerator>());
|
||||
}
|
||||
|
||||
Error loadObjects(Session &S) {
|
||||
|
||||
std::map<unsigned, JITDylib *> IdxToJLD;
|
||||
@ -1039,6 +1060,9 @@ int main(int argc, char *argv[]) {
|
||||
ExitOnErr(loadProcessSymbols(*S));
|
||||
ExitOnErr(loadDylibs());
|
||||
|
||||
if (PhonyExternals)
|
||||
addPhonyExternalsGenerator(*S);
|
||||
|
||||
{
|
||||
TimeRegion TR(Timers ? &Timers->LoadObjectsTimer : nullptr);
|
||||
ExitOnErr(loadObjects(*S));
|
||||
|
Loading…
x
Reference in New Issue
Block a user