llvm.org GIT mirror llvm / 479f5fd
Rename pdb::StringTable -> pdb::PDBStringTable. With the forthcoming codeview::StringTable which a pdb::StringTable would hold an instance of as one member, this ambiguity becomes confusing. Rename to PDBStringTable to avoid this. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301948 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 3 years ago
19 changed file(s) with 356 addition(s) and 354 deletion(s). Raw diff Collapse all Expand all
1212 #include "llvm/DebugInfo/CodeView/ModuleDebugFragment.h"
1313 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1414 #include "llvm/DebugInfo/PDB/Native/DbiModuleDescriptor.h"
15 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1516 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
1617 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
17 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
1818 #include "llvm/DebugInfo/PDB/PDBTypes.h"
1919 #include "llvm/Support/BinaryStreamArray.h"
2020 #include "llvm/Support/BinaryStreamArray.h"
9090 std::unique_ptr Stream;
9191
9292 std::vector ModuleInfos;
93 StringTable ECNames;
93 PDBStringTable ECNames;
9494
9595 BinaryStreamRef ModInfoSubstream;
9696 BinaryStreamRef SecContrSubstream;
3232 class DbiStream;
3333 class GlobalsStream;
3434 class InfoStream;
35 class StringTable;
35 class PDBStringTable;
3636 class PDBFileBuilder;
3737 class PublicsStream;
3838 class SymbolStream;
9494 Expected getPDBIpiStream();
9595 Expected getPDBPublicsStream();
9696 Expected getPDBSymbolStream();
97 Expected<StringTable &> getStringTable();
97 Expected<PDBStringTable &> getStringTable();
9898
9999 BumpPtrAllocator &getAllocator() { return Allocator; }
100100
105105 bool hasPDBPublicsStream();
106106 bool hasPDBSymbolStream();
107107 bool hasPDBTpiStream() const;
108 bool hasStringTable();
108 bool hasPDBStringTable();
109109
110110 private:
111111 Expected>
129129 std::unique_ptr Publics;
130130 std::unique_ptr Symbols;
131131 std::unique_ptr DirectoryStream;
132 std::unique_ptr StringTableStream;
133 std::unique_ptr<StringTable> Strings;
132 std::unique_ptr<msf::MappedBlockStream> PDBStringTableStream;
133 std::unique_ptr Strings;
134134 };
135135 }
136136 }
1414 #include "llvm/ADT/Optional.h"
1515 #include "llvm/DebugInfo/PDB/Native/NamedStreamMap.h"
1616 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
17 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
1718 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
18 #include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
1919 #include "llvm/Support/Allocator.h"
2020 #include "llvm/Support/Endian.h"
2121 #include "llvm/Support/Error.h"
4545 DbiStreamBuilder &getDbiBuilder();
4646 TpiStreamBuilder &getTpiBuilder();
4747 TpiStreamBuilder &getIpiBuilder();
48 StringTableBuilder &getStringTableBuilder();
48 PDBStringTableBuilder &getStringTableBuilder();
4949
5050 Error commit(StringRef Filename);
5151
6161 std::unique_ptr Tpi;
6262 std::unique_ptr Ipi;
6363
64 StringTableBuilder Strings;
64 PDBStringTableBuilder Strings;
6565 NamedStreamMap NamedStreams;
6666 };
6767 }
0 //===- PDBStringTable.h - PDB String Table -------------------------*- C++
1 //-*-===//
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
10 #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
11 #define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLE_H
12
13 #include "llvm/ADT/ArrayRef.h"
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/Support/BinaryStreamArray.h"
16 #include "llvm/Support/BinaryStreamRef.h"
17 #include "llvm/Support/Endian.h"
18 #include "llvm/Support/Error.h"
19 #include
20 #include
21
22 namespace llvm {
23 class BinaryStreamReader;
24
25 namespace pdb {
26
27 class PDBStringTable {
28 public:
29 PDBStringTable();
30
31 Error load(BinaryStreamReader &Stream);
32
33 uint32_t getByteSize() const;
34
35 uint32_t getNameCount() const { return NameCount; }
36 uint32_t getHashVersion() const { return HashVersion; }
37 uint32_t getSignature() const { return Signature; }
38
39 StringRef getStringForID(uint32_t ID) const;
40 uint32_t getIDForString(StringRef Str) const;
41
42 FixedStreamArray name_ids() const;
43
44 private:
45 BinaryStreamRef NamesBuffer;
46 FixedStreamArray IDs;
47 uint32_t ByteSize = 0;
48 uint32_t Signature = 0;
49 uint32_t HashVersion = 0;
50 uint32_t NameCount = 0;
51 };
52
53 } // end namespace pdb
54 } // end namespace llvm
55
56 #endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
0 //===- PDBStringTableBuilder.h - PDB String Table Builder -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file creates the "/names" stream.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
14 #define LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
15
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Error.h"
19 #include
20
21 namespace llvm {
22 class BinaryStreamWriter;
23
24 namespace pdb {
25
26 class PDBStringTableBuilder {
27 public:
28 // If string S does not exist in the string table, insert it.
29 // Returns the ID for S.
30 uint32_t insert(StringRef S);
31 uint32_t getStringIndex(StringRef S);
32
33 uint32_t finalize();
34 Error commit(BinaryStreamWriter &Writer) const;
35
36 private:
37 DenseMap Strings;
38 uint32_t StringSize = 1;
39 };
40
41 } // end namespace pdb
42 } // end namespace llvm
43
44 #endif // LLVM_DEBUGINFO_PDB_RAW_PDBSTRINGTABLEBUILDER_H
306306 };
307307
308308 /// The header preceeding the /names stream.
309 struct StringTableHeader {
309 struct PDBStringTableHeader {
310310 support::ulittle32_t Signature;
311311 support::ulittle32_t HashVersion;
312312 support::ulittle32_t ByteSize;
313313 };
314314
315 const uint32_t StringTableSignature = 0xEFFEEFFE;
315 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
316316
317317 } // namespace pdb
318318 } // namespace llvm
+0
-56
include/llvm/DebugInfo/PDB/Native/StringTable.h less more
None //===- StringTable.h - PDB String Table -------------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
10 #define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/Support/BinaryStreamArray.h"
15 #include "llvm/Support/BinaryStreamRef.h"
16 #include "llvm/Support/Endian.h"
17 #include "llvm/Support/Error.h"
18 #include
19 #include
20
21 namespace llvm {
22 class BinaryStreamReader;
23
24 namespace pdb {
25
26 class StringTable {
27 public:
28 StringTable();
29
30 Error load(BinaryStreamReader &Stream);
31
32 uint32_t getByteSize() const;
33
34 uint32_t getNameCount() const { return NameCount; }
35 uint32_t getHashVersion() const { return HashVersion; }
36 uint32_t getSignature() const { return Signature; }
37
38 StringRef getStringForID(uint32_t ID) const;
39 uint32_t getIDForString(StringRef Str) const;
40
41 FixedStreamArray name_ids() const;
42
43 private:
44 BinaryStreamRef NamesBuffer;
45 FixedStreamArray IDs;
46 uint32_t ByteSize = 0;
47 uint32_t Signature = 0;
48 uint32_t HashVersion = 0;
49 uint32_t NameCount = 0;
50 };
51
52 } // end namespace pdb
53 } // end namespace llvm
54
55 #endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLE_H
+0
-45
include/llvm/DebugInfo/PDB/Native/StringTableBuilder.h less more
None //===- StringTableBuilder.h - PDB String Table Builder ----------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file creates the "/names" stream.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #ifndef LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
14 #define LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
15
16 #include "llvm/ADT/DenseMap.h"
17 #include "llvm/ADT/StringRef.h"
18 #include "llvm/Support/Error.h"
19 #include
20
21 namespace llvm {
22 class BinaryStreamWriter;
23
24 namespace pdb {
25
26 class StringTableBuilder {
27 public:
28 // If string S does not exist in the string table, insert it.
29 // Returns the ID for S.
30 uint32_t insert(StringRef S);
31 uint32_t getStringIndex(StringRef S);
32
33 uint32_t finalize();
34 Error commit(BinaryStreamWriter &Writer) const;
35
36 private:
37 DenseMap Strings;
38 uint32_t StringSize = 1;
39 };
40
41 } // end namespace pdb
42 } // end namespace llvm
43
44 #endif // LLVM_DEBUGINFO_PDB_RAW_STRINGTABLEBUILDER_H
4747 Native/NativeSession.cpp
4848 Native/PDBFile.cpp
4949 Native/PDBFileBuilder.cpp
50 Native/PDBStringTable.cpp
51 Native/PDBStringTableBuilder.cpp
5052 Native/PDBTypeServerHandler.cpp
5153 Native/PublicsStream.cpp
5254 Native/RawError.cpp
53 Native/StringTable.cpp
54 Native/StringTableBuilder.cpp
5555 Native/SymbolStream.cpp
5656 Native/TpiHashing.cpp
5757 Native/TpiStream.cpp
1414 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1515 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
1616 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
17 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1718 #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
1819 #include "llvm/DebugInfo/PDB/Native/RawError.h"
19 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
2020 #include "llvm/DebugInfo/PDB/Native/SymbolStream.h"
2121 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
2222 #include "llvm/Support/BinaryStream.h"
336336 return *Symbols;
337337 }
338338
339 Expected PDBFile::getStringTable() {
340 if (!Strings || !StringTableStream) {
339 Expected PDBFile::getStringTable() {
340 if (!Strings || !PDBStringTableStream) {
341341 auto IS = getPDBInfoStream();
342342 if (!IS)
343343 return IS.takeError();
350350 return NS.takeError();
351351
352352 BinaryStreamReader Reader(**NS);
353 auto N = llvm::make_unique<StringTable>();
353 auto N = llvm::make_unique<PDBStringTable>();
354354 if (auto EC = N->load(Reader))
355355 return std::move(EC);
356356 Strings = std::move(N);
357 StringTableStream = std::move(*NS);
357 PDBStringTableStream = std::move(*NS);
358358 }
359359 return *Strings;
360360 }
388388
389389 bool PDBFile::hasPDBTpiStream() const { return StreamTPI < getNumStreams(); }
390390
391 bool PDBFile::hasStringTable() {
391 bool PDBFile::hasPDBStringTable() {
392392 auto IS = getPDBInfoStream();
393393 if (!IS)
394394 return false;
1616 #include "llvm/DebugInfo/PDB/Native/DbiStreamBuilder.h"
1717 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
1818 #include "llvm/DebugInfo/PDB/Native/InfoStreamBuilder.h"
19 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
1920 #include "llvm/DebugInfo/PDB/Native/RawError.h"
20 #include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
2121 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
2222 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
2323 #include "llvm/Support/BinaryStream.h"
6666 return *Ipi;
6767 }
6868
69 StringTableBuilder &PDBFileBuilder::getStringTableBuilder() { return Strings; }
69 PDBStringTableBuilder &PDBFileBuilder::getStringTableBuilder() {
70 return Strings;
71 }
7072
7173 Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
7274 auto ExpectedStream = Msf->addStream(Size);
7779 }
7880
7981 Expected PDBFileBuilder::finalizeMsfLayout() {
80 uint32_t StringTableSize = Strings.finalize();
82 uint32_t PDBStringTableSize = Strings.finalize();
8183
82 if (auto EC = addNamedStream("/names", StringTableSize))
84 if (auto EC = addNamedStream("/names", PDBStringTableSize))
8385 return std::move(EC);
8486 if (auto EC = addNamedStream("/LinkInfo", 0))
8587 return std::move(EC);
143145 return EC;
144146 }
145147
146 uint32_t StringTableStreamNo = 0;
147 if (!NamedStreams.get("/names", StringTableStreamNo))
148 uint32_t PDBStringTableStreamNo = 0;
149 if (!NamedStreams.get("/names", PDBStringTableStreamNo))
148150 return llvm::make_error(raw_error_code::no_stream);
149151
150 auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
151 StringTableStreamNo);
152 auto NS = WritableMappedBlockStream::createIndexedStream(
153 Layout, Buffer, PDBStringTableStreamNo);
152154 BinaryStreamWriter NSWriter(*NS);
153155 if (auto EC = Strings.commit(NSWriter))
154156 return EC;
0 //===- PDBStringTable.cpp - PDB String Table -----------------------*- C++
1 //-*-===//
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
10 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
11
12 #include "llvm/ADT/ArrayRef.h"
13 #include "llvm/DebugInfo/PDB/Native/Hash.h"
14 #include "llvm/DebugInfo/PDB/Native/RawError.h"
15 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
16 #include "llvm/Support/BinaryStreamReader.h"
17 #include "llvm/Support/Endian.h"
18
19 using namespace llvm;
20 using namespace llvm::support;
21 using namespace llvm::pdb;
22
23 PDBStringTable::PDBStringTable() {}
24
25 Error PDBStringTable::load(BinaryStreamReader &Stream) {
26 ByteSize = Stream.getLength();
27
28 const PDBStringTableHeader *H;
29 if (auto EC = Stream.readObject(H))
30 return EC;
31
32 if (H->Signature != PDBStringTableSignature)
33 return make_error(raw_error_code::corrupt_file,
34 "Invalid hash table signature");
35 if (H->HashVersion != 1 && H->HashVersion != 2)
36 return make_error(raw_error_code::corrupt_file,
37 "Unsupported hash version");
38
39 Signature = H->Signature;
40 HashVersion = H->HashVersion;
41 if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
42 return joinErrors(std::move(EC),
43 make_error(raw_error_code::corrupt_file,
44 "Invalid hash table byte length"));
45
46 const support::ulittle32_t *HashCount;
47 if (auto EC = Stream.readObject(HashCount))
48 return EC;
49
50 if (auto EC = Stream.readArray(IDs, *HashCount))
51 return joinErrors(std::move(EC),
52 make_error(raw_error_code::corrupt_file,
53 "Could not read bucket array"));
54
55 if (Stream.bytesRemaining() < sizeof(support::ulittle32_t))
56 return make_error(raw_error_code::corrupt_file,
57 "Missing name count");
58
59 if (auto EC = Stream.readInteger(NameCount))
60 return EC;
61
62 if (Stream.bytesRemaining() > 0)
63 return make_error(raw_error_code::stream_too_long,
64 "Unexpected bytes found in string table");
65
66 return Error::success();
67 }
68
69 uint32_t PDBStringTable::getByteSize() const { return ByteSize; }
70
71 StringRef PDBStringTable::getStringForID(uint32_t ID) const {
72 if (ID == IDs[0])
73 return StringRef();
74
75 // NamesBuffer is a buffer of null terminated strings back to back. ID is
76 // the starting offset of the string we're looking for. So just seek into
77 // the desired offset and a read a null terminated stream from that offset.
78 StringRef Result;
79 BinaryStreamReader NameReader(NamesBuffer);
80 NameReader.setOffset(ID);
81 if (auto EC = NameReader.readCString(Result))
82 consumeError(std::move(EC));
83 return Result;
84 }
85
86 uint32_t PDBStringTable::getIDForString(StringRef Str) const {
87 uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
88 size_t Count = IDs.size();
89 uint32_t Start = Hash % Count;
90 for (size_t I = 0; I < Count; ++I) {
91 // The hash is just a starting point for the search, but if it
92 // doesn't work we should find the string no matter what, because
93 // we iterate the entire array.
94 uint32_t Index = (Start + I) % Count;
95
96 uint32_t ID = IDs[Index];
97 StringRef S = getStringForID(ID);
98 if (S == Str)
99 return ID;
100 }
101 // IDs[0] contains the ID of the "invalid" entry.
102 return IDs[0];
103 }
104
105 FixedStreamArray PDBStringTable::name_ids() const {
106 return IDs;
107 }
0 //===- PDBStringTableBuilder.cpp - PDB String Table -------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/DebugInfo/PDB/Native/Hash.h"
12 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
14 #include "llvm/Support/Endian.h"
15
16 using namespace llvm;
17 using namespace llvm::support;
18 using namespace llvm::support::endian;
19 using namespace llvm::pdb;
20
21 uint32_t PDBStringTableBuilder::insert(StringRef S) {
22 auto P = Strings.insert({S, StringSize});
23
24 // If a given string didn't exist in the string table, we want to increment
25 // the string table size.
26 if (P.second)
27 StringSize += S.size() + 1; // +1 for '\0'
28 return P.first->second;
29 }
30
31 uint32_t PDBStringTableBuilder::getStringIndex(StringRef S) {
32 auto Iter = Strings.find(S);
33 assert(Iter != Strings.end());
34 return Iter->second;
35 }
36
37 static uint32_t computeBucketCount(uint32_t NumStrings) {
38 // The /names stream is basically an on-disk open-addressing hash table.
39 // Hash collisions are resolved by linear probing. We cannot make
40 // utilization 100% because it will make the linear probing extremely
41 // slow. But lower utilization wastes disk space. As a reasonable
42 // load factor, we choose 80%. We need +1 because slot 0 is reserved.
43 return (NumStrings + 1) * 1.25;
44 }
45
46 uint32_t PDBStringTableBuilder::finalize() {
47 uint32_t Size = 0;
48 Size += sizeof(PDBStringTableHeader);
49 Size += StringSize;
50 Size += sizeof(uint32_t); // Hash table begins with 4-byte size field.
51
52 uint32_t BucketCount = computeBucketCount(Strings.size());
53 Size += BucketCount * sizeof(uint32_t);
54
55 Size +=
56 sizeof(uint32_t); // The /names stream ends with the number of strings.
57 return Size;
58 }
59
60 Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
61 // Write a header
62 PDBStringTableHeader H;
63 H.Signature = PDBStringTableSignature;
64 H.HashVersion = 1;
65 H.ByteSize = StringSize;
66 if (auto EC = Writer.writeObject(H))
67 return EC;
68
69 // Write a string table.
70 uint32_t StringStart = Writer.getOffset();
71 for (auto Pair : Strings) {
72 StringRef S = Pair.first;
73 uint32_t Offset = Pair.second;
74 Writer.setOffset(StringStart + Offset);
75 if (auto EC = Writer.writeCString(S))
76 return EC;
77 }
78 Writer.setOffset(StringStart + StringSize);
79
80 // Write a hash table.
81 uint32_t BucketCount = computeBucketCount(Strings.size());
82 if (auto EC = Writer.writeInteger(BucketCount))
83 return EC;
84 std::vector Buckets(BucketCount);
85
86 for (auto Pair : Strings) {
87 StringRef S = Pair.first;
88 uint32_t Offset = Pair.second;
89 uint32_t Hash = hashStringV1(S);
90
91 for (uint32_t I = 0; I != BucketCount; ++I) {
92 uint32_t Slot = (Hash + I) % BucketCount;
93 if (Slot == 0)
94 continue; // Skip reserved slot
95 if (Buckets[Slot] != 0)
96 continue;
97 Buckets[Slot] = Offset;
98 break;
99 }
100 }
101
102 if (auto EC = Writer.writeArray(ArrayRef(Buckets)))
103 return EC;
104 if (auto EC = Writer.writeInteger(static_cast(Strings.size())))
105 return EC;
106 return Error::success();
107 }
+0
-109
lib/DebugInfo/PDB/Native/StringTable.cpp less more
None //===- StringTable.cpp - PDB String Table -----------------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
10
11 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/DebugInfo/PDB/Native/Hash.h"
13 #include "llvm/DebugInfo/PDB/Native/RawError.h"
14 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
15 #include "llvm/Support/BinaryStreamReader.h"
16 #include "llvm/Support/Endian.h"
17
18 using namespace llvm;
19 using namespace llvm::support;
20 using namespace llvm::pdb;
21
22 StringTable::StringTable() {}
23
24 Error StringTable::load(BinaryStreamReader &Stream) {
25 ByteSize = Stream.getLength();
26
27 const StringTableHeader *H;
28 if (auto EC = Stream.readObject(H))
29 return EC;
30
31 if (H->Signature != StringTableSignature)
32 return make_error(raw_error_code::corrupt_file,
33 "Invalid hash table signature");
34 if (H->HashVersion != 1 && H->HashVersion != 2)
35 return make_error(raw_error_code::corrupt_file,
36 "Unsupported hash version");
37
38 Signature = H->Signature;
39 HashVersion = H->HashVersion;
40 if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
41 return joinErrors(std::move(EC),
42 make_error(raw_error_code::corrupt_file,
43 "Invalid hash table byte length"));
44
45 const support::ulittle32_t *HashCount;
46 if (auto EC = Stream.readObject(HashCount))
47 return EC;
48
49 if (auto EC = Stream.readArray(IDs, *HashCount))
50 return joinErrors(std::move(EC),
51 make_error(raw_error_code::corrupt_file,
52 "Could not read bucket array"));
53
54 if (Stream.bytesRemaining() < sizeof(support::ulittle32_t))
55 return make_error(raw_error_code::corrupt_file,
56 "Missing name count");
57
58 if (auto EC = Stream.readInteger(NameCount))
59 return EC;
60
61 if (Stream.bytesRemaining() > 0)
62 return make_error(raw_error_code::stream_too_long,
63 "Unexpected bytes found in string table");
64
65 return Error::success();
66 }
67
68 uint32_t StringTable::getByteSize() const {
69 return ByteSize;
70 }
71
72 StringRef StringTable::getStringForID(uint32_t ID) const {
73 if (ID == IDs[0])
74 return StringRef();
75
76 // NamesBuffer is a buffer of null terminated strings back to back. ID is
77 // the starting offset of the string we're looking for. So just seek into
78 // the desired offset and a read a null terminated stream from that offset.
79 StringRef Result;
80 BinaryStreamReader NameReader(NamesBuffer);
81 NameReader.setOffset(ID);
82 if (auto EC = NameReader.readCString(Result))
83 consumeError(std::move(EC));
84 return Result;
85 }
86
87 uint32_t StringTable::getIDForString(StringRef Str) const {
88 uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
89 size_t Count = IDs.size();
90 uint32_t Start = Hash % Count;
91 for (size_t I = 0; I < Count; ++I) {
92 // The hash is just a starting point for the search, but if it
93 // doesn't work we should find the string no matter what, because
94 // we iterate the entire array.
95 uint32_t Index = (Start + I) % Count;
96
97 uint32_t ID = IDs[Index];
98 StringRef S = getStringForID(ID);
99 if (S == Str)
100 return ID;
101 }
102 // IDs[0] contains the ID of the "invalid" entry.
103 return IDs[0];
104 }
105
106 FixedStreamArray StringTable::name_ids() const {
107 return IDs;
108 }
+0
-108
lib/DebugInfo/PDB/Native/StringTableBuilder.cpp less more
None //===- StringTableBuilder.cpp - PDB String Table ----------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8
9 #include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
10 #include "llvm/ADT/ArrayRef.h"
11 #include "llvm/DebugInfo/PDB/Native/Hash.h"
12 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
14 #include "llvm/Support/Endian.h"
15
16 using namespace llvm;
17 using namespace llvm::support;
18 using namespace llvm::support::endian;
19 using namespace llvm::pdb;
20
21 uint32_t StringTableBuilder::insert(StringRef S) {
22 auto P = Strings.insert({S, StringSize});
23
24 // If a given string didn't exist in the string table, we want to increment
25 // the string table size.
26 if (P.second)
27 StringSize += S.size() + 1; // +1 for '\0'
28 return P.first->second;
29 }
30
31 uint32_t StringTableBuilder::getStringIndex(StringRef S) {
32 auto Iter = Strings.find(S);
33 assert(Iter != Strings.end());
34 return Iter->second;
35 }
36
37 static uint32_t computeBucketCount(uint32_t NumStrings) {
38 // The /names stream is basically an on-disk open-addressing hash table.
39 // Hash collisions are resolved by linear probing. We cannot make
40 // utilization 100% because it will make the linear probing extremely
41 // slow. But lower utilization wastes disk space. As a reasonable
42 // load factor, we choose 80%. We need +1 because slot 0 is reserved.
43 return (NumStrings + 1) * 1.25;
44 }
45
46 uint32_t StringTableBuilder::finalize() {
47 uint32_t Size = 0;
48 Size += sizeof(StringTableHeader);
49 Size += StringSize;
50 Size += sizeof(uint32_t); // Hash table begins with 4-byte size field.
51
52 uint32_t BucketCount = computeBucketCount(Strings.size());
53 Size += BucketCount * sizeof(uint32_t);
54
55 Size +=
56 sizeof(uint32_t); // The /names stream ends with the number of strings.
57 return Size;
58 }
59
60 Error StringTableBuilder::commit(BinaryStreamWriter &Writer) const {
61 // Write a header
62 StringTableHeader H;
63 H.Signature = StringTableSignature;
64 H.HashVersion = 1;
65 H.ByteSize = StringSize;
66 if (auto EC = Writer.writeObject(H))
67 return EC;
68
69 // Write a string table.
70 uint32_t StringStart = Writer.getOffset();
71 for (auto Pair : Strings) {
72 StringRef S = Pair.first;
73 uint32_t Offset = Pair.second;
74 Writer.setOffset(StringStart + Offset);
75 if (auto EC = Writer.writeCString(S))
76 return EC;
77 }
78 Writer.setOffset(StringStart + StringSize);
79
80 // Write a hash table.
81 uint32_t BucketCount = computeBucketCount(Strings.size());
82 if (auto EC = Writer.writeInteger(BucketCount))
83 return EC;
84 std::vector Buckets(BucketCount);
85
86 for (auto Pair : Strings) {
87 StringRef S = Pair.first;
88 uint32_t Offset = Pair.second;
89 uint32_t Hash = hashStringV1(S);
90
91 for (uint32_t I = 0; I != BucketCount; ++I) {
92 uint32_t Slot = (Hash + I) % BucketCount;
93 if (Slot == 0)
94 continue; // Skip reserved slot
95 if (Buckets[Slot] != 0)
96 continue;
97 Buckets[Slot] = Offset;
98 break;
99 }
100 }
101
102 if (auto EC = Writer.writeArray(ArrayRef(Buckets)))
103 return EC;
104 if (auto EC = Writer.writeInteger(static_cast(Strings.size())))
105 return EC;
106 return Error::success();
107 }
1212 #include "llvm/DebugInfo/CodeView/ModuleDebugInlineeLinesFragment.h"
1313 #include "llvm/DebugInfo/CodeView/ModuleDebugLineFragment.h"
1414 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
15 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1516 #include "llvm/DebugInfo/PDB/Native/RawError.h"
16 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
1717
1818 using namespace llvm;
1919 using namespace llvm::codeview;
1414 #include "llvm/DebugInfo/PDB/Native/Formatters.h"
1515 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
1616 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
17 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1718 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
18 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
1919
2020 #include "llvm/Support/FormatAdapters.h"
2121 #include "llvm/Support/FormatProviders.h"
4646 #include "llvm/DebugInfo/PDB/Native/NativeSession.h"
4747 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
4848 #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
49 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
4950 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
5051 #include "llvm/DebugInfo/PDB/Native/RawError.h"
51 #include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
5252 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
5353 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
5454 #include "llvm/DebugInfo/PDB/PDB.h"
426426 static uint32_t
427427 getFileChecksumOffset(StringRef FileName,
428428 ModuleDebugFileChecksumFragment &Checksums,
429 StringTableBuilder &Strings) {
429 PDBStringTableBuilder &Strings) {
430430 // The offset in the line info record is the offset of the checksum
431431 // entry for the corresponding file. That entry then contains an
432432 // offset into the global string table of the file name. So to
88
99 #include "ErrorChecking.h"
1010
11 #include "llvm/DebugInfo/PDB/Native/StringTable.h"
12 #include "llvm/DebugInfo/PDB/Native/StringTableBuilder.h"
11 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
12 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
1313 #include "llvm/Support/BinaryByteStream.h"
1414 #include "llvm/Support/BinaryStreamReader.h"
1515 #include "llvm/Support/BinaryStreamWriter.h"
2626
2727 TEST_F(StringTableBuilderTest, Simple) {
2828 // Create /names table contents.
29 StringTableBuilder Builder;
29 PDBStringTableBuilder Builder;
3030 EXPECT_EQ(1U, Builder.insert("foo"));
3131 EXPECT_EQ(5U, Builder.insert("bar"));
3232 EXPECT_EQ(1U, Builder.insert("foo"));
4040 // Reads the contents back.
4141 BinaryByteStream InStream(Buffer, little);
4242 BinaryStreamReader Reader(InStream);
43 StringTable Table;
43 PDBStringTable Table;
4444 EXPECT_NO_ERROR(Table.load(Reader));
4545
4646 EXPECT_EQ(3U, Table.getNameCount());