diff options
author | Nico Weber <nicolasweber@gmx.de> | 2019-04-29 23:09:35 +0000 |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2019-04-29 23:09:35 +0000 |
commit | e577be4ed1ecb7e354ec25f431de058365befe16 (patch) | |
tree | ea06db783b16b4a382bd701336315a8210b02fd6 /llvm/lib/DebugInfo/PDB/Native | |
parent | 8c474a38d174b472e75c948af11f8cf46dc465cc (diff) | |
download | bcm5719-llvm-e577be4ed1ecb7e354ec25f431de058365befe16.tar.gz bcm5719-llvm-e577be4ed1ecb7e354ec25f431de058365befe16.zip |
[PDB] Fix hash function used to write /src/headerblock
lld-link used to write PDB files that DIA couldn't recover natvis
files from if:
- The global strings table was > 64kiB
- There were at least 3 natvis files
The cause was that the hash function for the /src/headerblock stream
was incorrect: It needs to be truncated to 16 bit.
If the global strings table was <= 64kiB, truncating to 16 bit is a
no-op, so this wasn't needed for small programs.
If there are only 1 or 2 natvis files, then the growth strategy in
HashTable::grow() would mean the hash table would have 2 buckets (for 1
natvis file) or 4 buckets (for 4 natvis files), and since the hash
function is used modulo number of buckets, and since 2 and 4 divide
0x10000, the missing `% 0x10000` is a no-op there too. For 3 natvis
files, the hash table grows to 6 buckets, which has a factor that's not
common with 0x10000 and the difference starts to matter.
Fixes PR41626.
Differential Revision: https://reviews.llvm.org/D61277
llvm-svn: 359515
Diffstat (limited to 'llvm/lib/DebugInfo/PDB/Native')
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp | 8 |
2 files changed, 8 insertions, 1 deletions
diff --git a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp index a9965ff8d06..1c044e0c265 100644 --- a/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp @@ -34,6 +34,7 @@ uint16_t NamedStreamMapTraits::hashLookupKey(StringRef S) const { // Here, the type HASH is a typedef of unsigned short. // ** It is not a bug that we truncate the result of hashStringV1, in fact // it is a bug if we do not! ** + // See NMTNI::hash() in the reference implementation. return static_cast<uint16_t>(hashStringV1(S)); } diff --git a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp index 4b69e09a83d..eabb9d44669 100644 --- a/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp +++ b/llvm/lib/DebugInfo/PDB/Native/PDBStringTableBuilder.cpp @@ -26,7 +26,13 @@ StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table) : Table(&Table) {} uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const { - return Table->getIdForString(S); + // The reference implementation doesn't include code for /src/headerblock + // handling, but it can only read natvis entries lld's PDB files if + // this hash function truncates the hash to 16 bit. + // PDB/include/misc.h in the reference implementation has a hashSz() function + // that returns an unsigned short, that seems what's being used for + // /src/headerblock. + return static_cast<uint16_t>(Table->getIdForString(S)); } StringRef StringTableHashTraits::storageKeyToLookupKey(uint32_t Offset) const { |