• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- Hash.cpp - PDB Hash Functions --------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/PDB/Raw/Hash.h"
11 
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/Support/Endian.h"
14 
15 using namespace llvm;
16 using namespace llvm::support;
17 
18 // Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
19 // Used for name hash table and TPI/IPI hashes.
hashStringV1(StringRef Str)20 uint32_t pdb::hashStringV1(StringRef Str) {
21   uint32_t Result = 0;
22   uint32_t Size = Str.size();
23 
24   ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
25                               Size / 4);
26 
27   for (auto Value : Longs)
28     Result ^= Value;
29 
30   const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
31   uint32_t RemainderSize = Size % 4;
32 
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);
38     Remainder += 2;
39     RemainderSize -= 2;
40   }
41 
42   // hash possible odd byte
43   if (RemainderSize == 1) {
44     Result ^= *(Remainder++);
45   }
46 
47   const uint32_t toLowerMask = 0x20202020;
48   Result |= toLowerMask;
49   Result ^= (Result >> 11);
50 
51   return Result ^ (Result >> 16);
52 }
53 
54 // Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
55 // Used for name hash table.
hashStringV2(StringRef Str)56 uint32_t pdb::hashStringV2(StringRef Str) {
57   uint32_t Hash = 0xb170a1bf;
58 
59   ArrayRef<char> Buffer(Str.begin(), Str.end());
60 
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) {
65     Hash += Item;
66     Hash += (Hash << 10);
67     Hash ^= (Hash >> 6);
68   }
69   Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
70   for (uint8_t Item : Buffer) {
71     Hash += Item;
72     Hash += (Hash << 10);
73     Hash ^= (Hash >> 6);
74   }
75 
76   return Hash * 1664525L + 1013904223L;
77 }
78 
79 static const uint32_t V8HashTable[] = {
80     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
81     0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
82     0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
83     0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
84     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
85     0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
86     0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
87     0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
88     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
89     0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
90     0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
91     0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
92     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
93     0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
94     0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
95     0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
96     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
97     0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
98     0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
99     0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
100     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
101     0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
102     0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
103     0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
104     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
105     0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
106     0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
107     0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
108     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
109     0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
110     0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
111     0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
112     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
113     0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
114     0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
115     0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
116     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
117     0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
118     0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
119     0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
120     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
121     0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
122     0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D,
123 };
124 
125 // Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
hashBufferV8(ArrayRef<uint8_t> Buf)126 uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
127   uint32_t Hash = 0;
128   for (uint8_t Byte : Buf)
129     Hash = (Hash >> 8) ^ V8HashTable[(Hash & 0xff) ^ Byte];
130   return Hash;
131 }
132