1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

[PDB] Move PDB functions to a separate file.

We are going to use the hash functions from TPI streams.

Differential Revision: http://reviews.llvm.org/D21142

llvm-svn: 272223
This commit is contained in:
Rui Ueyama 2016-06-08 23:11:14 +00:00
parent 50e6f3827e
commit c4f19f8773
4 changed files with 101 additions and 59 deletions

View File

@ -0,0 +1,22 @@
//===- Hash.h - PDB hash functions ------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_DEBUGINFO_PDB_RAW_HASH_H
#define LLVM_DEBUGINFO_PDB_RAW_HASH_H
#include "llvm/ADT/StringRef.h"
namespace llvm {
namespace pdb {
uint32_t HashStringV1(StringRef Str);
uint32_t HashStringV2(StringRef Str);
}
}
#endif

View File

@ -30,6 +30,7 @@ endif()
add_pdb_impl_folder(Raw add_pdb_impl_folder(Raw
Raw/DbiStream.cpp Raw/DbiStream.cpp
Raw/EnumTables.cpp Raw/EnumTables.cpp
Raw/Hash.cpp
Raw/IndexedStreamData.cpp Raw/IndexedStreamData.cpp
Raw/InfoStream.cpp Raw/InfoStream.cpp
Raw/MappedBlockStream.cpp Raw/MappedBlockStream.cpp

View File

@ -0,0 +1,77 @@
//===- Hash.cpp - PDB Hash Functions --------------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/Endian.h"
using namespace llvm;
using namespace llvm::support;
// Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
// Used for name hash table and TPI/IPI hashes.
uint32_t pdb::HashStringV1(StringRef Str) {
uint32_t Result = 0;
uint32_t Size = Str.size();
ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
Size / 4);
for (auto Value : Longs)
Result ^= Value;
const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
uint32_t RemainderSize = Size % 4;
// Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
// possibly remaining 1 byte.
if (RemainderSize >= 2) {
uint16_t Value = *reinterpret_cast<const ulittle16_t *>(Remainder);
Result ^= static_cast<uint32_t>(Value);
Remainder += 2;
RemainderSize -= 2;
}
// hash possible odd byte
if (RemainderSize == 1) {
Result ^= *(Remainder++);
}
const uint32_t toLowerMask = 0x20202020;
Result |= toLowerMask;
Result ^= (Result >> 11);
return Result ^ (Result >> 16);
}
// Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
// Used for name hash table.
uint32_t pdb::HashStringV2(StringRef Str) {
uint32_t Hash = 0xb170a1bf;
ArrayRef<char> Buffer(Str.begin(), Str.end());
ArrayRef<ulittle32_t> Items(
reinterpret_cast<const ulittle32_t *>(Buffer.data()),
Buffer.size() / sizeof(ulittle32_t));
for (ulittle32_t Item : Items) {
Hash += Item;
Hash += (Hash << 10);
Hash ^= (Hash >> 6);
}
Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
for (uint8_t Item : Buffer) {
Hash += Item;
Hash += (Hash << 10);
Hash ^= (Hash >> 6);
}
return Hash * 1664525L + 1013904223L;
}

View File

@ -11,6 +11,7 @@
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h" #include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h" #include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/Support/Endian.h" #include "llvm/Support/Endian.h"
@ -18,65 +19,6 @@ using namespace llvm;
using namespace llvm::support; using namespace llvm::support;
using namespace llvm::pdb; using namespace llvm::pdb;
// Corresponds to `Hasher::lhashPbCb` in PDB/include/misc.h.
static inline uint32_t HashStringV1(StringRef Str) {
uint32_t Result = 0;
uint32_t Size = Str.size();
ArrayRef<ulittle32_t> Longs(reinterpret_cast<const ulittle32_t *>(Str.data()),
Size / 4);
for (auto Value : Longs)
Result ^= Value;
const uint8_t *Remainder = reinterpret_cast<const uint8_t *>(Longs.end());
uint32_t RemainderSize = Size - Longs.size() * 4;
// Maximum of 3 bytes left. Hash a 2 byte word if possible, then hash the
// possibly remaining 1 byte.
if (RemainderSize >= 2) {
uint16_t Value = *reinterpret_cast<const ulittle16_t *>(Remainder);
Result ^= static_cast<uint32_t>(Value);
Remainder += 2;
RemainderSize -= 2;
}
// hash possible odd byte
if (RemainderSize == 1) {
Result ^= *(Remainder++);
}
const uint32_t toLowerMask = 0x20202020;
Result |= toLowerMask;
Result ^= (Result >> 11);
return Result ^ (Result >> 16);
}
// Corresponds to `HasherV2::HashULONG` in PDB/include/misc.h.
static inline uint32_t HashStringV2(StringRef Str) {
uint32_t Hash = 0xb170a1bf;
ArrayRef<char> Buffer(Str.begin(), Str.end());
ArrayRef<ulittle32_t> Items(
reinterpret_cast<const ulittle32_t *>(Buffer.data()),
Buffer.size() / sizeof(ulittle32_t));
for (ulittle32_t Item : Items) {
Hash += Item;
Hash += (Hash << 10);
Hash ^= (Hash >> 6);
}
Buffer = Buffer.slice(Items.size() * sizeof(ulittle32_t));
for (uint8_t Item : Buffer) {
Hash += Item;
Hash += (Hash << 10);
Hash ^= (Hash >> 6);
}
return Hash * 1664525L + 1013904223L;
}
NameHashTable::NameHashTable() : Signature(0), HashVersion(0), NameCount(0) {} NameHashTable::NameHashTable() : Signature(0), HashVersion(0), NameCount(0) {}
Error NameHashTable::load(codeview::StreamReader &Stream) { Error NameHashTable::load(codeview::StreamReader &Stream) {