[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

(cherry picked from commit 6732640f5f)
This commit is contained in:
Hans Wennborg 2026-04-07 16:16:30 +02:00 committed by Cullen Rhodes
parent f42d371a5d
commit 5b4dd04594
2 changed files with 31 additions and 1 deletions

View file

@ -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

View file

@ -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