PDBStringTable.cpp revision 317760
1294838Szbb//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
2294838Szbb//
3294838Szbb//                     The LLVM Compiler Infrastructure
4294838Szbb//
5294838Szbb// This file is distributed under the University of Illinois Open Source
6294838Szbb// License. See LICENSE.TXT for details.
7294838Szbb//
8294838Szbb//===----------------------------------------------------------------------===//
9294838Szbb
10294838Szbb#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
11294838Szbb
12294838Szbb#include "llvm/ADT/ArrayRef.h"
13294838Szbb#include "llvm/DebugInfo/MSF/MappedBlockStream.h"
14294838Szbb#include "llvm/DebugInfo/PDB/Native/Hash.h"
15294838Szbb#include "llvm/DebugInfo/PDB/Native/RawError.h"
16294838Szbb#include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17294838Szbb#include "llvm/Support/BinaryStreamReader.h"
18294838Szbb#include "llvm/Support/Endian.h"
19294838Szbb
20294838Szbbusing namespace llvm;
21294838Szbbusing namespace llvm::support;
22294838Szbbusing namespace llvm::pdb;
23294838Szbb
24294838Szbbuint32_t PDBStringTable::getByteSize() const { return ByteSize; }
25294838Szbbuint32_t PDBStringTable::getNameCount() const { return NameCount; }
26294838Szbbuint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
27294838Szbbuint32_t PDBStringTable::getSignature() const { return Header->Signature; }
28294838Szbb
29294838SzbbError PDBStringTable::readHeader(BinaryStreamReader &Reader) {
30294838Szbb  if (auto EC = Reader.readObject(Header))
31294838Szbb    return EC;
32294838Szbb
33294838Szbb  if (Header->Signature != PDBStringTableSignature)
34294838Szbb    return make_error<RawError>(raw_error_code::corrupt_file,
35294838Szbb                                "Invalid hash table signature");
36294838Szbb  if (Header->HashVersion != 1 && Header->HashVersion != 2)
37294838Szbb    return make_error<RawError>(raw_error_code::corrupt_file,
38294838Szbb                                "Unsupported hash version");
39294838Szbb
40294838Szbb  assert(Reader.bytesRemaining() == 0);
41294838Szbb  return Error::success();
42294838Szbb}
43294838Szbb
44294838SzbbError PDBStringTable::readStrings(BinaryStreamReader &Reader) {
45294838Szbb  BinaryStreamRef Stream;
46294838Szbb  if (auto EC = Reader.readStreamRef(Stream))
47294838Szbb    return EC;
48294838Szbb
49294838Szbb  if (auto EC = Strings.initialize(Stream)) {
50294838Szbb    return joinErrors(std::move(EC),
51294838Szbb                      make_error<RawError>(raw_error_code::corrupt_file,
52294838Szbb                                           "Invalid hash table byte length"));
53294838Szbb  }
54294838Szbb
55294838Szbb  assert(Reader.bytesRemaining() == 0);
56294838Szbb  return Error::success();
57294838Szbb}
58294838Szbb
59294838SzbbError PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
60294838Szbb  const support::ulittle32_t *HashCount;
61294838Szbb  if (auto EC = Reader.readObject(HashCount))
62294838Szbb    return EC;
63294838Szbb
64294838Szbb  if (auto EC = Reader.readArray(IDs, *HashCount)) {
65294838Szbb    return joinErrors(std::move(EC),
66294838Szbb                      make_error<RawError>(raw_error_code::corrupt_file,
67294838Szbb                                           "Could not read bucket array"));
68294838Szbb  }
69294838Szbb
70294838Szbb  return Error::success();
71294838Szbb}
72294838Szbb
73294838SzbbError PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
74294838Szbb  if (auto EC = Reader.readInteger(NameCount))
75294838Szbb    return EC;
76294838Szbb
77294838Szbb  assert(Reader.bytesRemaining() == 0);
78294838Szbb  return Error::success();
79294838Szbb}
80294838Szbb
81294838SzbbError PDBStringTable::reload(BinaryStreamReader &Reader) {
82294838Szbb
83294838Szbb  BinaryStreamReader SectionReader;
84294838Szbb
85294838Szbb  std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
86294838Szbb  if (auto EC = readHeader(SectionReader))
87294838Szbb    return EC;
88294838Szbb
89294838Szbb  std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
90294838Szbb  if (auto EC = readStrings(SectionReader))
91294838Szbb    return EC;
92294838Szbb
93294838Szbb  // We don't know how long the hash table is until we parse it, so let the
94294838Szbb  // function responsible for doing that figure it out.
95294838Szbb  if (auto EC = readHashTable(Reader))
96294838Szbb    return EC;
97294838Szbb
98294838Szbb  std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
99294838Szbb  if (auto EC = readEpilogue(SectionReader))
100294838Szbb    return EC;
101294838Szbb
102294838Szbb  assert(Reader.bytesRemaining() == 0);
103294838Szbb  return Error::success();
104294838Szbb}
105294838Szbb
106294838SzbbExpected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
107294838Szbb  return Strings.getString(ID);
108294838Szbb}
109294838Szbb
110294838SzbbExpected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
111294838Szbb  uint32_t Hash =
112294838Szbb      (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
113294838Szbb  size_t Count = IDs.size();
114294838Szbb  uint32_t Start = Hash % Count;
115294838Szbb  for (size_t I = 0; I < Count; ++I) {
116294838Szbb    // The hash is just a starting point for the search, but if it
117294838Szbb    // doesn't work we should find the string no matter what, because
118294838Szbb    // we iterate the entire array.
119294838Szbb    uint32_t Index = (Start + I) % Count;
120294838Szbb
121294838Szbb    uint32_t ID = IDs[Index];
122294838Szbb    auto ExpectedStr = getStringForID(ID);
123294838Szbb    if (!ExpectedStr)
124294838Szbb      return ExpectedStr.takeError();
125294838Szbb
126294838Szbb    if (*ExpectedStr == Str)
127294838Szbb      return ID;
128294838Szbb  }
129294838Szbb  return make_error<RawError>(raw_error_code::no_entry);
130294838Szbb}
131294838Szbb
132294838SzbbFixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
133294838Szbb  return IDs;
134294838Szbb}
135294838Szbb