Hash.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. //===- Hash.cpp - PDB Hash Functions --------------------------------------===//
  2. //
  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
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/PDB/Native/Hash.h"
  9. #include "llvm/ADT/ArrayRef.h"
  10. #include "llvm/Support/CRC.h"
  11. #include "llvm/Support/Endian.h"
  12. #include <cstdint>
  13. using namespace llvm;
  14. using namespace llvm::support;
  15. // Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
  16. // Used for name hash table and TPI/IPI hashes.
  17. uint32_t pdb::hashStringV1(StringRef Str) {
  18. uint32_t Result = 0;
  19. uint32_t Size = Str.size();
  20. ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
  21. Size / 4);
  22. for (auto Value : Longs)
  23. Result ^= Value;
  24. const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
  25. uint32_t RemainderSize = Size % 4;
  26. // Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
  27. // possibly remaining 1 byte.
  28. if (RemainderSize >= 2) {
  29. uint16_t Value = *reinterpret_cast<const ulittle16_t *>(Remainder);
  30. Result ^= static_cast<uint32_t>(Value);
  31. Remainder += 2;
  32. RemainderSize -= 2;
  33. }
  34. // hash possible odd byte
  35. if (RemainderSize == 1) {
  36. Result ^= *(Remainder++);
  37. }
  38. const uint32_t toLowerMask = 0x20202020;
  39. Result |= toLowerMask;
  40. Result ^= (Result >> 11);
  41. return Result ^ (Result >> 16);
  42. }
  43. // Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
  44. // Used for name hash table.
  45. uint32_t pdb::hashStringV2(StringRef Str) {
  46. uint32_t Hash = 0xb170a1bf;
  47. ArrayRef<char> Buffer(Str.begin(), Str.end());
  48. ArrayRef<ulittle32_t> Items(
  49. reinterpret_cast<const ulittle32_t *>(Buffer.data()),
  50. Buffer.size() / sizeof(ulittle32_t));
  51. for (ulittle32_t Item : Items) {
  52. Hash += Item;
  53. Hash += (Hash << 10);
  54. Hash ^= (Hash >> 6);
  55. }
  56. Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
  57. for (uint8_t Item : Buffer) {
  58. Hash += Item;
  59. Hash += (Hash << 10);
  60. Hash ^= (Hash >> 6);
  61. }
  62. return Hash * 1664525U + 1013904223U;
  63. }
  64. // Corresponds to `SigForPbCb` in langapi/shared/crc32.h.
  65. uint32_t pdb::hashBufferV8(ArrayRef<uint8_t> Buf) {
  66. JamCRC JC(/*Init=*/0U);
  67. JC.update(Buf);
  68. return JC.getCRC();
  69. }