LLVM  6.0.0svn
PDBStringTable.cpp
Go to the documentation of this file.
1 //===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
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 
11 
12 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/Support/Endian.h"
19 
20 using namespace llvm;
21 using namespace llvm::support;
22 using namespace llvm::pdb;
23 
24 uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
25 uint32_t PDBStringTable::getNameCount() const { return NameCount; }
26 uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
27 uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
28 
29 Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
30  if (auto EC = Reader.readObject(Header))
31  return EC;
32 
33  if (Header->Signature != PDBStringTableSignature)
34  return make_error<RawError>(raw_error_code::corrupt_file,
35  "Invalid hash table signature");
36  if (Header->HashVersion != 1 && Header->HashVersion != 2)
37  return make_error<RawError>(raw_error_code::corrupt_file,
38  "Unsupported hash version");
39 
40  assert(Reader.bytesRemaining() == 0);
41  return Error::success();
42 }
43 
44 Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
45  BinaryStreamRef Stream;
46  if (auto EC = Reader.readStreamRef(Stream))
47  return EC;
48 
49  if (auto EC = Strings.initialize(Stream)) {
50  return joinErrors(std::move(EC),
51  make_error<RawError>(raw_error_code::corrupt_file,
52  "Invalid hash table byte length"));
53  }
54 
55  assert(Reader.bytesRemaining() == 0);
56  return Error::success();
57 }
58 
60 PDBStringTable::getStringTable() const {
61  return Strings;
62 }
63 
64 Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
65  const support::ulittle32_t *HashCount;
66  if (auto EC = Reader.readObject(HashCount))
67  return EC;
68 
69  if (auto EC = Reader.readArray(IDs, *HashCount)) {
70  return joinErrors(std::move(EC),
71  make_error<RawError>(raw_error_code::corrupt_file,
72  "Could not read bucket array"));
73  }
74 
75  return Error::success();
76 }
77 
78 Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
79  if (auto EC = Reader.readInteger(NameCount))
80  return EC;
81 
82  assert(Reader.bytesRemaining() == 0);
83  return Error::success();
84 }
85 
86 Error PDBStringTable::reload(BinaryStreamReader &Reader) {
87 
88  BinaryStreamReader SectionReader;
89 
90  std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
91  if (auto EC = readHeader(SectionReader))
92  return EC;
93 
94  std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
95  if (auto EC = readStrings(SectionReader))
96  return EC;
97 
98  // We don't know how long the hash table is until we parse it, so let the
99  // function responsible for doing that figure it out.
100  if (auto EC = readHashTable(Reader))
101  return EC;
102 
103  std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
104  if (auto EC = readEpilogue(SectionReader))
105  return EC;
106 
107  assert(Reader.bytesRemaining() == 0);
108  return Error::success();
109 }
110 
111 Expected<StringRef> PDBStringTable::getStringForID(uint32_t ID) const {
112  return Strings.getString(ID);
113 }
114 
115 Expected<uint32_t> PDBStringTable::getIDForString(StringRef Str) const {
116  uint32_t Hash =
117  (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
118  size_t Count = IDs.size();
119  uint32_t Start = Hash % Count;
120  for (size_t I = 0; I < Count; ++I) {
121  // The hash is just a starting point for the search, but if it
122  // doesn't work we should find the string no matter what, because
123  // we iterate the entire array.
124  uint32_t Index = (Start + I) % Count;
125 
126  uint32_t ID = IDs[Index];
127  auto ExpectedStr = getStringForID(ID);
128  if (!ExpectedStr)
129  return ExpectedStr.takeError();
130 
131  if (*ExpectedStr == Str)
132  return ID;
133  }
134  return make_error<RawError>(raw_error_code::no_entry);
135 }
136 
137 FixedStreamArray<support::ulittle32_t> PDBStringTable::name_ids() const {
138  return IDs;
139 }
uint32_t hashStringV2(StringRef Str)
Definition: Hash.cpp:57
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream&#39;s offset.
Error readObject(const T *&Dest)
Get a pointer to an object of type T from the underlying stream, as if by memcpy, and store the resul...
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
std::pair< BinaryStreamReader, BinaryStreamReader > split(uint32_t Offset) const
The header preceeding the /names stream.
Definition: RawTypes.h:323
uint32_t hashStringV1(StringRef Str)
Definition: Hash.cpp:21
static ErrorSuccess success()
Create a success value.
Definition: Error.h:313
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Represents a read-only view of a CodeView string table.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:408
#define I(x, y, z)
Definition: MD5.cpp:58
Error readStreamRef(BinaryStreamRef &Ref)
Read the entire remainder of the underlying stream into Ref.
uint32_t bytesRemaining() const
const uint32_t PDBStringTableSignature
Definition: RawTypes.h:329
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
Definition: Error.h:156
Provides read only access to a subclass of BinaryStream.
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static std::string getSignature(FunctionType *FTy)
Error readArray(ArrayRef< T > &Array, uint32_t NumElements)
Get a reference to a NumElements element array of objects of type T from the underlying stream as if ...