[llvm] [PDB] Add public symbol lookup by address (PR #157361)
Alexandre Ganea via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 9 05:40:45 PDT 2025
================
@@ -96,3 +99,65 @@ Error PublicsStream::reload() {
"Corrupted publics stream.");
return Error::success();
}
+
+static uint32_t compareSegmentOffset(uint16_t LhsSegment, uint32_t LhsOffset,
+ uint16_t RhsSegment, uint32_t RhsOffset) {
+ if (LhsSegment == RhsSegment)
+ return LhsOffset - RhsOffset;
+ return LhsSegment - RhsSegment;
+}
+
+static uint32_t compareSegmentOffset(uint16_t LhsSegment, uint32_t LhsOffst,
+ const codeview::PublicSym32 &Rhs) {
+ return compareSegmentOffset(LhsSegment, LhsOffst, Rhs.Segment, Rhs.Offset);
+}
+
+// This is a reimplementation of NearestSym:
+// https://github.com/microsoft/microsoft-pdb/blob/805655a28bd8198004be2ac27e6e0290121a5e89/PDB/dbi/gsi.cpp#L1492-L1581
+std::optional<std::pair<codeview::PublicSym32, size_t>>
+PublicsStream::findByAddress(const SymbolStream &Symbols, uint16_t Segment,
+ uint32_t Offset) const {
+ // The address map is sorted by address, so we can use lower_bound to find the
+ // position. Each element is an offset into the symbols for a public symbol.
+ auto It = llvm::lower_bound(
+ AddressMap, std::pair(Segment, Offset),
+ [&](support::ulittle32_t Cur, auto Addr) {
+ auto Sym = Symbols.readRecord(Cur.value());
+ if (Sym.kind() != codeview::S_PUB32)
+ return false; // stop here, this is most likely corrupted debug info
+
+ auto Psym =
+ codeview::SymbolDeserializer::deserializeAs<codeview::PublicSym32>(
+ Sym);
+ if (!Psym) {
+ consumeError(Psym.takeError());
+ return false;
+ }
+
+ if (Psym->Segment == Addr.first)
----------------
aganea wrote:
You can actually use `std::tie` to aggregate several fields for comparing them in order. ie. `return std::tie(Psym->Segment, Psym->Offset) < std::tie(Addr.first, Addr.second);`. And above too in `compareSegmentOffset`.
https://github.com/llvm/llvm-project/pull/157361
More information about the llvm-commits
mailing list