LLVM 22.0.0git
PDBStringTable.cpp
Go to the documentation of this file.
1//===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
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
10
15#include "llvm/Support/Endian.h"
16
17using namespace llvm;
18using namespace llvm::support;
19using namespace llvm::pdb;
20
21uint32_t PDBStringTable::getByteSize() const { return Header->ByteSize; }
22uint32_t PDBStringTable::getNameCount() const { return NameCount; }
23uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
24uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
25
26Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
27 if (auto EC = Reader.readObject(Header))
28 return EC;
29
30 if (Header->Signature != PDBStringTableSignature)
32 "Invalid hash table signature");
33 if (Header->HashVersion != 1 && Header->HashVersion != 2)
35 "Unsupported hash version");
36
37 assert(Reader.bytesRemaining() == 0);
38 return Error::success();
39}
40
41Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
42 BinaryStreamRef Stream;
43 if (auto EC = Reader.readStreamRef(Stream))
44 return EC;
45
46 if (auto EC = Strings.initialize(Stream)) {
47 return joinErrors(std::move(EC),
49 "Invalid hash table byte length"));
50 }
51
52 assert(Reader.bytesRemaining() == 0);
53 return Error::success();
54}
55
56const codeview::DebugStringTableSubsectionRef &
58 return Strings;
59}
60
61Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
62 const support::ulittle32_t *HashCount;
63 if (auto EC = Reader.readObject(HashCount))
64 return EC;
65
66 if (auto EC = Reader.readArray(IDs, *HashCount)) {
67 return joinErrors(std::move(EC),
69 "Could not read bucket array"));
70 }
71
72 return Error::success();
73}
74
75Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
76 if (auto EC = Reader.readInteger(NameCount))
77 return EC;
78
79 assert(Reader.bytesRemaining() == 0);
80 return Error::success();
81}
82
84
85 BinaryStreamReader SectionReader;
86
87 std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
88 if (auto EC = readHeader(SectionReader))
89 return EC;
90
91 std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
92 if (auto EC = readStrings(SectionReader))
93 return EC;
94
95 // We don't know how long the hash table is until we parse it, so let the
96 // function responsible for doing that figure it out.
97 if (auto EC = readHashTable(Reader))
98 return EC;
99
100 std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
101 if (auto EC = readEpilogue(SectionReader))
102 return EC;
103
104 assert(Reader.bytesRemaining() == 0);
105 return Error::success();
106}
107
109 return Strings.getString(ID);
110}
111
113 uint32_t Hash =
114 (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
115 size_t Count = IDs.size();
116 uint32_t Start = Hash % Count;
117 for (size_t I = 0; I < Count; ++I) {
118 // The hash is just a starting point for the search, but if it
119 // doesn't work we should find the string no matter what, because
120 // we iterate the entire array.
121 uint32_t Index = (Start + I) % Count;
122
123 // If we find 0, it means the item isn't in the hash table.
124 uint32_t ID = IDs[Index];
125 if (ID == 0)
127 auto ExpectedStr = getStringForID(ID);
128 if (!ExpectedStr)
129 return ExpectedStr.takeError();
130
131 if (*ExpectedStr == Str)
132 return ID;
133 }
135}
136
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define I(x, y, z)
Definition MD5.cpp:58
Provides read only access to a subclass of BinaryStream.
LLVM_ABI Error readStreamRef(BinaryStreamRef &Ref)
Read the entire remainder of the underlying stream into Ref.
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...
Error readInteger(T &Dest)
Read an integer of the specified endianness into Dest and update the stream's offset.
LLVM_ABI std::pair< BinaryStreamReader, BinaryStreamReader > split(uint64_t Offset) const
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 ...
BinaryStreamRef is to BinaryStream what ArrayRef is to an Array.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
FixedStreamArray is similar to VarStreamArray, except with each record having a fixed-length.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
LLVM_ABI Error initialize(BinaryStreamRef Contents)
LLVM_ABI const codeview::DebugStringTableSubsectionRef & getStringTable() const
LLVM_ABI uint32_t getSignature() const
LLVM_ABI uint32_t getNameCount() const
LLVM_ABI Expected< uint32_t > getIDForString(StringRef Str) const
LLVM_ABI Error reload(BinaryStreamReader &Reader)
LLVM_ABI Expected< StringRef > getStringForID(uint32_t ID) const
LLVM_ABI uint32_t getByteSize() const
LLVM_ABI uint32_t getHashVersion() const
LLVM_ABI FixedStreamArray< support::ulittle32_t > name_ids() const
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
LLVM_ABI uint32_t hashStringV1(StringRef Str)
Definition Hash.cpp:20
const uint32_t PDBStringTableSignature
Definition RawTypes.h:318
LLVM_ABI uint32_t hashStringV2(StringRef Str)
Definition Hash.cpp:56
detail::packed_endian_specific_integral< uint32_t, llvm::endianness::little, unaligned > ulittle32_t
Definition Endian.h:286
This is an optimization pass for GlobalISel generic memory operations.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition Error.h:442
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
The header preceding the /names stream.
Definition RawTypes.h:312