[llvm] 6732640 - [pdb] Fix public symbol hashing in GSIHashStreamBuilder::finalizeBuckets (#190133)

via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 7 07:16:37 PDT 2026


Author: Hans Wennborg
Date: 2026-04-07T14:16:30Z
New Revision: 6732640f5f3b2729c245e3b8026637d322c7f31d

URL: https://github.com/llvm/llvm-project/commit/6732640f5f3b2729c245e3b8026637d322c7f31d
DIFF: https://github.com/llvm/llvm-project/commit/6732640f5f3b2729c245e3b8026637d322c7f31d.diff

LOG: [pdb] Fix public symbol hashing in GSIHashStreamBuilder::finalizeBuckets (#190133)

BulkPublic.Name is not necessarily null terminated, so make sure not to
hash past its actual length.

In practice it would often be null terminated, but in the cases where it
was not, we would compute the wrong hash here, put it in the wrong hash
bucket, preventing debuggers from looking up the symbol by name, causing
issues such as
https://discourse.llvm.org/t/pdb-generated-by-lld-link-doesnt-point-to-correct-entry-point-when-debugged-using-visual-studio/90349

Added: 
    lld/test/COFF/pdb-publics-hashes.s

Modified: 
    llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/lld/test/COFF/pdb-publics-hashes.s b/lld/test/COFF/pdb-publics-hashes.s
new file mode 100644
index 0000000000000..07bfa482cbfa8
--- /dev/null
+++ b/lld/test/COFF/pdb-publics-hashes.s
@@ -0,0 +1,30 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj %s -o %t.obj -triple x86_64-windows-msvc
+# RUN: lld-link -entry:wWinMain -nodefaultlib %t.obj -out:%t.exe -pdb:%t.pdb -debug
+# RUN: llvm-pdbutil dump -publics -public-extras %t.pdb | FileCheck %s
+
+# Check that each symbol is placed in its own hash bucket.
+# CHECK: Public Symbols
+# CHECK: Hash Buckets
+# CHECK-NEXT: 0x00000000
+# CHECK-NEXT: 0x0000000c
+# CHECK-NEXT: 0x00000018
+
+.globl foo
+foo:
+.rept 33
+nop
+.endr
+
+# An 8-byte symbol name, meaning it fits precisely in the COFF symbol table's
+# name field and will not be null terminated. It's followed by the symbol
+# address in little-endian: 33 (ascii '!'), meaning if the symbol hashing
+# assumes this name is null terminated, it will compute the same hash as for
+# the symbol below, putting them in the same bucket.
+.globl wWinMain
+wWinMain:
+nop
+
+.globl "wWinMain!"
+"wWinMain!":
+nop

diff  --git a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
index 0c4b9362a0f04..32a5578b2acd1 100644
--- a/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
+++ b/llvm/lib/DebugInfo/PDB/Native/GSIStreamBuilder.cpp
@@ -200,7 +200,7 @@ void GSIHashStreamBuilder::finalizeBuckets(
     uint32_t RecordZeroOffset, MutableArrayRef<BulkPublic> Records) {
   // Hash every name in parallel.
   parallelFor(0, Records.size(), [&](size_t I) {
-    Records[I].setBucketIdx(hashStringV1(Records[I].Name) % IPHR_HASH);
+    Records[I].setBucketIdx(hashStringV1(Records[I].getName()) % IPHR_HASH);
   });
 
   // Count up the size of each bucket. Then, use an exclusive prefix sum to


        


More information about the llvm-commits mailing list