[llvm] [llvm-jitlink] Add optional index argument in jitlink-check stub_addr() expressions (PR #78369)
Stefan Gränitz via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 19 09:25:48 PST 2024
https://github.com/weliveindetail updated https://github.com/llvm/llvm-project/pull/78369
>From 773fc105655651748d5055deb0795a9f6c5daad3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Stefan=20Gr=C3=A4nitz?= <stefan.graenitz at gmail.com>
Date: Sat, 13 Jan 2024 23:35:54 +0100
Subject: [PATCH] [llvm-jitlink] Allow optional stub-kind filter in stub_addr()
expressions
---
.../llvm/ExecutionEngine/RuntimeDyldChecker.h | 2 +-
.../RuntimeDyld/RuntimeDyldChecker.cpp | 27 ++++--
.../RuntimeDyld/RuntimeDyldCheckerImpl.h | 3 +-
llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp | 2 +-
llvm/tools/llvm-jitlink/llvm-jitlink.cpp | 86 +++++++++++++++++--
llvm/tools/llvm-jitlink/llvm-jitlink.h | 7 +-
llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp | 11 ++-
7 files changed, 114 insertions(+), 24 deletions(-)
diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
index 80e4bbf494339c..034c134a13731d 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyldChecker.h
@@ -154,7 +154,7 @@ class RuntimeDyldChecker {
using GetSectionInfoFunction = std::function<Expected<MemoryRegionInfo>(
StringRef FileName, StringRef SectionName)>;
using GetStubInfoFunction = std::function<Expected<MemoryRegionInfo>(
- StringRef StubContainer, StringRef TargetName)>;
+ StringRef StubContainer, StringRef TargetName, StringRef StubKindFilter)>;
using GetGOTInfoFunction = std::function<Expected<MemoryRegionInfo>(
StringRef GOTContainer, StringRef TargetName)>;
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
index 7fadbdd6a1fff2..11fb21a9c1c0a7 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldChecker.cpp
@@ -400,6 +400,15 @@ class RuntimeDyldCheckerExprEval {
StringRef Symbol;
std::tie(Symbol, RemainingExpr) = parseSymbol(RemainingExpr);
+ // Parse optional parameter to filter by stub kind
+ StringRef KindNameFilter;
+ if (RemainingExpr.starts_with(",")) {
+ RemainingExpr = RemainingExpr.substr(1).ltrim();
+ size_t ClosingBracket = RemainingExpr.find(")");
+ KindNameFilter = RemainingExpr.substr(0, ClosingBracket);
+ RemainingExpr = RemainingExpr.substr(ClosingBracket);
+ }
+
if (!RemainingExpr.starts_with(")"))
return std::make_pair(
unexpectedToken(RemainingExpr, Expr, "expected ')'"), "");
@@ -407,8 +416,9 @@ class RuntimeDyldCheckerExprEval {
uint64_t StubAddr;
std::string ErrorMsg;
- std::tie(StubAddr, ErrorMsg) = Checker.getStubOrGOTAddrFor(
- StubContainerName, Symbol, PCtx.IsInsideLoad, IsStubAddr);
+ std::tie(StubAddr, ErrorMsg) =
+ Checker.getStubOrGOTAddrFor(StubContainerName, Symbol, KindNameFilter,
+ PCtx.IsInsideLoad, IsStubAddr);
if (ErrorMsg != "")
return std::make_pair(EvalResult(ErrorMsg), "");
@@ -985,11 +995,14 @@ std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getSectionAddr(
}
std::pair<uint64_t, std::string> RuntimeDyldCheckerImpl::getStubOrGOTAddrFor(
- StringRef StubContainerName, StringRef SymbolName, bool IsInsideLoad,
- bool IsStubAddr) const {
-
- auto StubInfo = IsStubAddr ? GetStubInfo(StubContainerName, SymbolName)
- : GetGOTInfo(StubContainerName, SymbolName);
+ StringRef StubContainerName, StringRef SymbolName, StringRef StubKindFilter,
+ bool IsInsideLoad, bool IsStubAddr) const {
+
+ assert((StubKindFilter.empty() || IsStubAddr) &&
+ "Kind name filter only supported for stubs");
+ auto StubInfo =
+ IsStubAddr ? GetStubInfo(StubContainerName, SymbolName, StubKindFilter)
+ : GetGOTInfo(StubContainerName, SymbolName);
if (!StubInfo) {
std::string ErrMsg;
diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
index 9f44a9389f4734..bda554e9e5b673 100644
--- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
+++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldCheckerImpl.h
@@ -64,7 +64,8 @@ class RuntimeDyldCheckerImpl {
std::pair<uint64_t, std::string>
getStubOrGOTAddrFor(StringRef StubContainerName, StringRef Symbol,
- bool IsInsideLoad, bool IsStubAddr) const;
+ StringRef StubKindFilter, bool IsInsideLoad,
+ bool IsStubAddr) const;
std::optional<uint64_t> getSectionLoadAddress(void *LocalAddr) const;
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
index c6b4218aad7af8..1f0fca2202a0ef 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink-elf.cpp
@@ -91,7 +91,7 @@ static Error registerSymbol(LinkGraph &G, Symbol &Sym, Session::FileInfo &FI,
case Stubs:
return FI.registerStubEntry(G, Sym, getELFStubTarget);
case AArch32Stubs:
- return FI.registerStubEntry(G, Sym, getELFAArch32StubTarget);
+ return FI.registerMultiStubEntry(G, Sym, getELFAArch32StubTarget);
case Other:
return Error::success();
}
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
index 8c18610313ce8f..d233ebdb5a3a8d 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.cpp
@@ -331,8 +331,12 @@ operator<<(raw_ostream &OS, const Session::FileInfo &FI) {
OS << " Section \"" << SIKV.first() << "\": " << SIKV.second << "\n";
for (auto &GOTKV : FI.GOTEntryInfos)
OS << " GOT \"" << GOTKV.first() << "\": " << GOTKV.second << "\n";
- for (auto &StubKV : FI.StubInfos)
- OS << " Stub \"" << StubKV.first() << "\": " << StubKV.second << "\n";
+ for (auto &StubKVs : FI.StubInfos) {
+ OS << " Stubs \"" << StubKVs.first() << "\":";
+ for (auto MemRegion : StubKVs.second)
+ OS << " " << MemRegion;
+ OS << "\n";
+ }
return OS;
}
@@ -1207,9 +1211,35 @@ Error Session::FileInfo::registerStubEntry(
auto TS = GetSymbolTarget(G, Sym.getBlock());
if (!TS)
return TS.takeError();
- StubInfos[TS->getName()] = {Sym.getSymbolContent(),
- Sym.getAddress().getValue(),
- Sym.getTargetFlags()};
+
+ SmallVector<MemoryRegionInfo> &Entry = StubInfos[TS->getName()];
+ Entry.insert(Entry.begin(),
+ {Sym.getSymbolContent(), Sym.getAddress().getValue(),
+ Sym.getTargetFlags()});
+ return Error::success();
+}
+
+Error Session::FileInfo::registerMultiStubEntry(
+ LinkGraph &G, Symbol &Sym, GetSymbolTargetFunction GetSymbolTarget) {
+ if (Sym.isSymbolZeroFill())
+ return make_error<StringError>("Unexpected zero-fill symbol in section " +
+ Sym.getBlock().getSection().getName(),
+ inconvertibleErrorCode());
+
+ auto Target = GetSymbolTarget(G, Sym.getBlock());
+ if (!Target)
+ return Target.takeError();
+
+ SmallVector<MemoryRegionInfo> &Entry = StubInfos[Target->getName()];
+ Entry.emplace_back(Sym.getSymbolContent(), Sym.getAddress().getValue(),
+ Sym.getTargetFlags());
+
+ // Let's keep stubs ordered by ascending address.
+ std::sort(Entry.begin(), Entry.end(),
+ [](const MemoryRegionInfo &L, const MemoryRegionInfo &R) {
+ return L.getTargetAddress() < R.getTargetAddress();
+ });
+
return Error::success();
}
@@ -1235,8 +1265,14 @@ Session::findSectionInfo(StringRef FileName, StringRef SectionName) {
return SecInfoItr->second;
}
+static StringRef detectStubKind(const Session::MemoryRegionInfo &Stub) {
+ // Implement acutal stub kind detection
+ return "";
+}
+
Expected<Session::MemoryRegionInfo &>
-Session::findStubInfo(StringRef FileName, StringRef TargetName) {
+Session::findStubInfo(StringRef FileName, StringRef TargetName,
+ StringRef KindNameFilter) {
auto FI = findFileInfo(FileName);
if (!FI)
return FI.takeError();
@@ -1246,7 +1282,38 @@ Session::findStubInfo(StringRef FileName, StringRef TargetName) {
"\" registered for file \"" + FileName +
"\"",
inconvertibleErrorCode());
- return StubInfoItr->second;
+ auto &StubsForTarget = StubInfoItr->second;
+ assert(!StubsForTarget.empty() && "At least 1 stub in each entry");
+ if (KindNameFilter.empty() && StubsForTarget.size() == 1)
+ return StubsForTarget[0]; // Regular single-stub match
+
+ std::string KindsStr;
+ SmallVector<MemoryRegionInfo *, 1> Matches;
+ Regex KindNameMatcher(KindNameFilter.empty() ? ".*" : KindNameFilter);
+ for (MemoryRegionInfo &Stub : StubsForTarget) {
+ StringRef Kind = detectStubKind(Stub);
+ if (KindNameMatcher.match(Kind))
+ Matches.push_back(&Stub);
+ KindsStr += "\"" + (Kind.empty() ? "<unknown>" : Kind.str()) + "\", ";
+ }
+ if (Matches.empty())
+ return make_error<StringError>(
+ "\"" + TargetName + "\" has " + Twine(StubsForTarget.size()) +
+ " stubs in file \"" + FileName +
+ "\", but none of them matches the stub-kind filter \"" +
+ KindNameFilter + "\" (all encountered kinds are " +
+ StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
+ inconvertibleErrorCode());
+ if (Matches.size() > 1)
+ return make_error<StringError>(
+ "\"" + TargetName + "\" has " + Twine(Matches.size()) +
+ " candidate stubs in file \"" + FileName +
+ "\". Please refine stub-kind filter \"" + KindNameFilter +
+ "\" for disambiguation (encountered kinds are " +
+ StringRef(KindsStr.data(), KindsStr.size() - 2) + ").",
+ inconvertibleErrorCode());
+
+ return *Matches[0];
}
Expected<Session::MemoryRegionInfo &>
@@ -2015,8 +2082,9 @@ static Error runChecks(Session &S, Triple TT, SubtargetFeatures Features) {
return S.findSectionInfo(FileName, SectionName);
};
- auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName) {
- return S.findStubInfo(FileName, SectionName);
+ auto GetStubInfo = [&S](StringRef FileName, StringRef SectionName,
+ StringRef KindNameFilter) {
+ return S.findStubInfo(FileName, SectionName, KindNameFilter);
};
auto GetGOTInfo = [&S](StringRef FileName, StringRef SectionName) {
diff --git a/llvm/tools/llvm-jitlink/llvm-jitlink.h b/llvm/tools/llvm-jitlink/llvm-jitlink.h
index 93a00266b15043..e09c15adace20e 100644
--- a/llvm/tools/llvm-jitlink/llvm-jitlink.h
+++ b/llvm/tools/llvm-jitlink/llvm-jitlink.h
@@ -49,7 +49,7 @@ struct Session {
struct FileInfo {
StringMap<MemoryRegionInfo> SectionInfos;
- StringMap<MemoryRegionInfo> StubInfos;
+ StringMap<SmallVector<MemoryRegionInfo, 1>> StubInfos;
StringMap<MemoryRegionInfo> GOTEntryInfos;
using Symbol = jitlink::Symbol;
@@ -61,6 +61,8 @@ struct Session {
GetSymbolTargetFunction GetSymbolTarget);
Error registerStubEntry(LinkGraph &G, Symbol &Sym,
GetSymbolTargetFunction GetSymbolTarget);
+ Error registerMultiStubEntry(LinkGraph &G, Symbol &Sym,
+ GetSymbolTargetFunction GetSymbolTarget);
};
using DynLibJDMap = std::map<std::string, orc::JITDylib *>;
@@ -74,7 +76,8 @@ struct Session {
Expected<MemoryRegionInfo &> findSectionInfo(StringRef FileName,
StringRef SectionName);
Expected<MemoryRegionInfo &> findStubInfo(StringRef FileName,
- StringRef TargetName);
+ StringRef TargetName,
+ StringRef KindNameFilter);
Expected<MemoryRegionInfo &> findGOTEntryInfo(StringRef FileName,
StringRef TargetName);
diff --git a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
index 107b555a99faa4..4cb76f4347422b 100644
--- a/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
+++ b/llvm/tools/llvm-rtdyld/llvm-rtdyld.cpp
@@ -926,7 +926,8 @@ static int linkAndVerify() {
};
auto GetStubInfo = [&Dyld, &StubMap](StringRef StubContainer,
- StringRef SymbolName)
+ StringRef SymbolName,
+ StringRef KindNameFilter)
-> Expected<RuntimeDyldChecker::MemoryRegionInfo> {
if (!StubMap.count(StubContainer))
return make_error<StringError>("Stub container not found: " +
@@ -947,6 +948,11 @@ static int linkAndVerify() {
return StubMemInfo;
};
+ auto GetGOTInfo = [&GetStubInfo](StringRef StubContainer,
+ StringRef SymbolName) {
+ return GetStubInfo(StubContainer, SymbolName, "");
+ };
+
// We will initialize this below once we have the first object file and can
// know the endianness.
std::unique_ptr<RuntimeDyldChecker> Checker;
@@ -977,8 +983,7 @@ static int linkAndVerify() {
if (!Checker)
Checker = std::make_unique<RuntimeDyldChecker>(
- IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo,
- GetStubInfo,
+ IsSymbolValid, GetSymbolInfo, GetSectionInfo, GetStubInfo, GetGOTInfo,
Obj.isLittleEndian() ? llvm::endianness::little
: llvm::endianness::big,
TheTriple, MCPU, SubtargetFeatures(), dbgs());
More information about the llvm-commits
mailing list