1 //===- Hash.cpp - PDB Hash Functions --------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/PDB/Native/Hash.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/Support/CRC.h"
12 #include "llvm/Support/Endian.h"
16 using namespace llvm::support
;
18 // Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
19 // Used for name hash table and TPI/IPI hashes.
20 uint32_t pdb::hashStringV1(StringRef Str
) {
22 uint32_t Size
= Str
.size();
24 ArrayRef
<ulittle32_t
> Longs(reinterpret_cast<const ulittle32_t
*>(Str
.data()),
27 for (auto Value
: Longs
)
30 const uint8_t *Remainder
= reinterpret_cast<const uint8_t *>(Longs
.end());
31 uint32_t RemainderSize
= Size
% 4;
33 // Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
34 // possibly remaining 1 byte.
35 if (RemainderSize
>= 2) {
36 uint16_t Value
= *reinterpret_cast<const ulittle16_t
*>(Remainder
);
37 Result
^= static_cast<uint32_t>(Value
);
42 // hash possible odd byte
43 if (RemainderSize
== 1) {
44 Result
^= *(Remainder
++);
47 const uint32_t toLowerMask
= 0x20202020;
48 Result
|= toLowerMask
;
49 Result
^= (Result
>> 11);
51 return Result
^ (Result
>> 16);
54 // Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
55 // Used for name hash table.
56 uint32_t pdb::hashStringV2(StringRef Str
) {
57 uint32_t Hash
= 0xb170a1bf;
59 ArrayRef
<char> Buffer(Str
.begin(), Str
.end());
61 ArrayRef
<ulittle32_t
> Items(
62 reinterpret_cast<const ulittle32_t
*>(Buffer
.data()),
63 Buffer
.size() / sizeof(ulittle32_t
));
64 for (ulittle32_t Item
: Items
) {
69 Buffer
= Buffer
.slice(Items
.size() * sizeof(ulittle32_t
));
70 for (uint8_t Item
: Buffer
) {
76 return Hash
* 1664525U + 1013904223U;
79 // Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
80 uint32_t pdb::hashBufferV8(ArrayRef
<uint8_t> Buf
) {
81 JamCRC
JC(/*Init=*/0U);