llvm.org GIT mirror llvm / 6b4b26a
Resubmit r301986 and r301987 "Add codeview::StringTable" This was reverted due to a "missing" file, but in reality what happened was that I renamed a file, and then due to a merge conflict both the old file and the new file got added to the repository. This led to an unused cpp file being in the repo and not referenced by any CMakeLists.txt but #including a .h file that wasn't in the repo. In an even more unfortunate coincidence, CMake didn't report the unused cpp file because it was in a subdirectory of the folder with the CMakeLists.txt, and not in the same directory as any CMakeLists.txt. The presence of the unused file was then breaking certain tools that determine file lists by globbing rather than by what's specified in CMakeLists.txt In any case, the fix is to just remove the unused file from the patch set. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@302042 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 2 years ago
18 changed file(s) with 359 addition(s) and 116 deletion(s). Raw diff Collapse all Expand all
0 //===- StringTable.h - CodeView String Table Reader/Writer ------*- 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_CODEVIEW_STRINGTABLE_H
10 #define LLVM_DEBUGINFO_CODEVIEW_STRINGTABLE_H
11
12 #include "llvm/ADT/StringMap.h"
13 #include "llvm/ADT/StringRef.h"
14
15 #include "llvm/Support/BinaryStreamRef.h"
16 #include "llvm/Support/Error.h"
17
18 #include
19
20 namespace llvm {
21
22 class BinaryStreamReader;
23 class BinaryStreamRef;
24 class BinaryStreamWriter;
25
26 namespace codeview {
27
28 /// Represents a read-only view of a CodeView string table. This is a very
29 /// simple flat buffer consisting of null-terminated strings, where strings
30 /// are retrieved by their offset in the buffer. StringTableRef does not own
31 /// the underlying storage for the buffer.
32 class StringTableRef {
33 public:
34 StringTableRef();
35
36 Error initialize(BinaryStreamReader &Stream);
37
38 StringRef getString(uint32_t Offset) const;
39
40 private:
41 BinaryStreamRef Stream;
42 };
43
44 /// Represents a read-write view of a CodeView string table. StringTable owns
45 /// the underlying storage for the table, and is capable of serializing the
46 /// string table into a format understood by StringTableRef.
47 class StringTable {
48 public:
49 // If string S does not exist in the string table, insert it.
50 // Returns the ID for S.
51 uint32_t insert(StringRef S);
52
53 uint32_t calculateSerializedSize() const;
54 Error commit(BinaryStreamWriter &Writer) const;
55
56 uint32_t size() const;
57
58 StringMap::const_iterator begin() const { return Strings.begin(); }
59
60 StringMap::const_iterator end() const { return Strings.end(); }
61
62 private:
63 StringMap Strings;
64 uint32_t StringSize = 1;
65 };
66 }
67 }
68
69 #endif
129129 std::unique_ptr Publics;
130130 std::unique_ptr Symbols;
131131 std::unique_ptr DirectoryStream;
132 std::unique_ptr PDBStringTableStream;
132 std::unique_ptr StringTableStream;
133133 std::unique_ptr Strings;
134134 };
135135 }
4949
5050 Error commit(StringRef Filename);
5151
52 Expected getNamedStreamIndex(StringRef Name) const;
53 Error addNamedStream(StringRef Name, uint32_t Size);
54
5255 private:
53 Error addNamedStream(StringRef Name, uint32_t Size);
5456 Expected finalizeMsfLayout();
5557
5658 BumpPtrAllocator &Allocator;
1212
1313 #include "llvm/ADT/ArrayRef.h"
1414 #include "llvm/ADT/StringRef.h"
15 #include "llvm/DebugInfo/CodeView/StringTable.h"
1516 #include "llvm/Support/BinaryStreamArray.h"
1617 #include "llvm/Support/BinaryStreamRef.h"
1718 #include "llvm/Support/Endian.h"
2223 namespace llvm {
2324 class BinaryStreamReader;
2425
26 namespace msf {
27 class MappedBlockStream;
28 }
29
2530 namespace pdb {
31
32 struct PDBStringTableHeader;
2633
2734 class PDBStringTable {
2835 public:
29 PDBStringTable();
30
31 Error load(BinaryStreamReader &Stream);
36 Error reload(BinaryStreamReader &Reader);
3237
3338 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; }
39 uint32_t getNameCount() const;
40 uint32_t getHashVersion() const;
41 uint32_t getSignature() const;
3842
3943 StringRef getStringForID(uint32_t ID) const;
4044 uint32_t getIDForString(StringRef Str) const;
4246 FixedStreamArray name_ids() const;
4347
4448 private:
45 BinaryStreamRef NamesBuffer;
49 Error readHeader(BinaryStreamReader &Reader);
50 Error readStrings(BinaryStreamReader &Reader);
51 Error readHashTable(BinaryStreamReader &Reader);
52 Error readEpilogue(BinaryStreamReader &Reader);
53
54 const PDBStringTableHeader *Header = nullptr;
55 codeview::StringTableRef Strings;
4656 FixedStreamArray IDs;
4757 uint32_t ByteSize = 0;
48 uint32_t Signature = 0;
49 uint32_t HashVersion = 0;
5058 uint32_t NameCount = 0;
5159 };
5260
1515
1616 #include "llvm/ADT/DenseMap.h"
1717 #include "llvm/ADT/StringRef.h"
18 #include "llvm/DebugInfo/CodeView/StringTable.h"
1819 #include "llvm/Support/Error.h"
1920 #include
2021
2122 namespace llvm {
2223 class BinaryStreamWriter;
24 class WritableBinaryStreamRef;
25
26 namespace msf {
27 struct MSFLayout;
28 }
2329
2430 namespace pdb {
31
32 class PDBFileBuilder;
2533
2634 class PDBStringTableBuilder {
2735 public:
2836 // If string S does not exist in the string table, insert it.
2937 // Returns the ID for S.
3038 uint32_t insert(StringRef S);
31 uint32_t getStringIndex(StringRef S);
3239
33 uint32_t finalize();
40 uint32_t calculateSerializedSize() const;
3441 Error commit(BinaryStreamWriter &Writer) const;
3542
3643 private:
37 DenseMap Strings;
38 uint32_t StringSize = 1;
44 uint32_t calculateHashTableSize() const;
45 Error writeHeader(BinaryStreamWriter &Writer) const;
46 Error writeStrings(BinaryStreamWriter &Writer) const;
47 Error writeHashTable(BinaryStreamWriter &Writer) const;
48 Error writeEpilogue(BinaryStreamWriter &Writer) const;
49
50 codeview::StringTable Strings;
3951 };
4052
4153 } // end namespace pdb
307307
308308 /// The header preceeding the /names stream.
309309 struct PDBStringTableHeader {
310 support::ulittle32_t Signature;
311 support::ulittle32_t HashVersion;
312 support::ulittle32_t ByteSize;
310 support::ulittle32_t Signature; // PDBStringTableSignature
311 support::ulittle32_t HashVersion; // 1 or 2
312 support::ulittle32_t ByteSize; // Number of bytes of names buffer.
313313 };
314314
315315 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
3030 /// are overridable.
3131 class BinaryStreamReader {
3232 public:
33 BinaryStreamReader() = default;
3334 explicit BinaryStreamReader(BinaryStreamRef Stream);
3435 virtual ~BinaryStreamReader() {}
3536
242243 /// \returns the next byte in the stream.
243244 uint8_t peek() const;
244245
246 std::pair
247 split(uint32_t Offset) const;
248
245249 private:
246250 BinaryStreamRef Stream;
247251 uint32_t Offset;
1919 #include "llvm/Support/Error.h"
2020 #include
2121 #include
22 #include
2223
2324 namespace llvm {
2425
2930 /// although no methods are overridable.
3031 class BinaryStreamWriter {
3132 public:
32 // FIXME: We should be able to slice and drop_front etc on Writers / Readers.
33
3433 BinaryStreamWriter() = default;
3534 explicit BinaryStreamWriter(WritableBinaryStreamRef Stream);
3635 virtual ~BinaryStreamWriter() {}
151150 return writeStreamRef(Array.getUnderlyingStream());
152151 }
153152
153 /// Splits the Writer into two Writers at a given offset.
154 std::pair split(uint32_t Off) const;
155
154156 void setOffset(uint32_t Off) { Offset = Off; }
155157 uint32_t getOffset() const { return Offset; }
156158 uint32_t getLength() const { return Stream.getLength(); }
1414 ModuleDebugLineFragment.cpp
1515 ModuleDebugUnknownFragment.cpp
1616 RecordSerialization.cpp
17 StringTable.cpp
1718 SymbolRecordMapping.cpp
1819 SymbolDumper.cpp
1920 SymbolSerializer.cpp
0 //===- StringTable.cpp - CodeView String Table Reader/Writer ----*- 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/CodeView/StringTable.h"
10
11 #include "llvm/Support/BinaryStream.h"
12 #include "llvm/Support/BinaryStreamReader.h"
13 #include "llvm/Support/BinaryStreamWriter.h"
14
15 using namespace llvm;
16 using namespace llvm::codeview;
17
18 StringTableRef::StringTableRef() {}
19
20 Error StringTableRef::initialize(BinaryStreamReader &Reader) {
21 return Reader.readStreamRef(Stream, Reader.bytesRemaining());
22 }
23
24 StringRef StringTableRef::getString(uint32_t Offset) const {
25 BinaryStreamReader Reader(Stream);
26 Reader.setOffset(Offset);
27 StringRef Result;
28 Error EC = Reader.readCString(Result);
29 assert(!EC);
30 consumeError(std::move(EC));
31 return Result;
32 }
33
34 uint32_t StringTable::insert(StringRef S) {
35 auto P = Strings.insert({S, StringSize});
36
37 // If a given string didn't exist in the string table, we want to increment
38 // the string table size.
39 if (P.second)
40 StringSize += S.size() + 1; // +1 for '\0'
41 return P.first->second;
42 }
43
44 uint32_t StringTable::calculateSerializedSize() const { return StringSize; }
45
46 Error StringTable::commit(BinaryStreamWriter &Writer) const {
47 assert(Writer.bytesRemaining() == StringSize);
48 uint32_t MaxOffset = 1;
49
50 for (auto &Pair : Strings) {
51 StringRef S = Pair.getKey();
52 uint32_t Offset = Pair.getValue();
53 Writer.setOffset(Offset);
54 if (auto EC = Writer.writeCString(S))
55 return EC;
56 MaxOffset = std::max(MaxOffset, Offset + S.size() + 1);
57 }
58
59 Writer.setOffset(MaxOffset);
60 assert(Writer.bytesRemaining() == 0);
61 return Error::success();
62 }
63
64 uint32_t StringTable::size() const { return Strings.size(); }
145145
146146 if (ECSubstream.getLength() > 0) {
147147 BinaryStreamReader ECReader(ECSubstream);
148 if (auto EC = ECNames.load(ECReader))
148 if (auto EC = ECNames.reload(ECReader))
149149 return EC;
150150 }
151151
337337 }
338338
339339 Expected PDBFile::getStringTable() {
340 if (!Strings || !PDBStringTableStream) {
340 if (!Strings) {
341341 auto IS = getPDBInfoStream();
342342 if (!IS)
343343 return IS.takeError();
349349 if (!NS)
350350 return NS.takeError();
351351
352 auto N = llvm::make_unique();
352353 BinaryStreamReader Reader(**NS);
353 auto N = llvm::make_unique();
354 if (auto EC = N->load(Reader))
355 return std::move(EC);
354 if (auto EC = N->reload(Reader))
355 return std::move(EC);
356 assert(Reader.bytesRemaining() == 0);
357 StringTableStream = std::move(*NS);
356358 Strings = std::move(N);
357 PDBStringTableStream = std::move(*NS);
358359 }
359360 return *Strings;
360361 }
7979 }
8080
8181 Expected PDBFileBuilder::finalizeMsfLayout() {
82 uint32_t PDBStringTableSize = Strings.finalize();
82 uint32_t StringsLen = Strings.calculateSerializedSize();
8383
84 if (auto EC = addNamedStream("/names", PDBStringTableSize))
84 if (auto EC = addNamedStream("/names", StringsLen))
8585 return std::move(EC);
8686 if (auto EC = addNamedStream("/LinkInfo", 0))
8787 return std::move(EC);
106106 }
107107
108108 return Msf->build();
109 }
110
111 Expected PDBFileBuilder::getNamedStreamIndex(StringRef Name) const {
112 uint32_t SN = 0;
113 if (!NamedStreams.get(Name, SN))
114 return llvm::make_error(raw_error_code::no_stream);
115 return SN;
109116 }
110117
111118 Error PDBFileBuilder::commit(StringRef Filename) {
145152 return EC;
146153 }
147154
148 uint32_t PDBStringTableStreamNo = 0;
149 if (!NamedStreams.get("/names", PDBStringTableStreamNo))
150 return llvm::make_error(raw_error_code::no_stream);
155 auto ExpectedSN = getNamedStreamIndex("/names");
156 if (!ExpectedSN)
157 return ExpectedSN.takeError();
151158
152 auto NS = WritableMappedBlockStream::createIndexedStream(
153 Layout, Buffer, PDBStringTableStreamNo);
159 auto NS = WritableMappedBlockStream::createIndexedStream(Layout, Buffer,
160 *ExpectedSN);
154161 BinaryStreamWriter NSWriter(*NS);
155162 if (auto EC = Strings.commit(NSWriter))
156163 return EC;
None //===- PDBStringTable.cpp - PDB String Table -----------------------*- C++
1 //-*-===//
0 //===- PDBStringTable.cpp - PDB String Table ---------------------*- C++-*-===//
21 //
32 // The LLVM Compiler Infrastructure
43 //
109 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1110
1211 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1313 #include "llvm/DebugInfo/PDB/Native/Hash.h"
1414 #include "llvm/DebugInfo/PDB/Native/RawError.h"
1515 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
2020 using namespace llvm::support;
2121 using namespace llvm::pdb;
2222
23 PDBStringTable::PDBStringTable() {}
23 uint32_t PDBStringTable::getByteSize() const { return ByteSize; }
24 uint32_t PDBStringTable::getNameCount() const { return NameCount; }
25 uint32_t PDBStringTable::getHashVersion() const { return Header->HashVersion; }
26 uint32_t PDBStringTable::getSignature() const { return Header->Signature; }
2427
25 Error PDBStringTable::load(BinaryStreamReader &Stream) {
26 ByteSize = Stream.getLength();
27
28 const PDBStringTableHeader *H;
29 if (auto EC = Stream.readObject(H))
28 Error PDBStringTable::readHeader(BinaryStreamReader &Reader) {
29 if (auto EC = Reader.readObject(Header))
3030 return EC;
3131
32 if (H->Signature != PDBStringTableSignature)
32 if (Header->Signature != PDBStringTableSignature)
3333 return make_error(raw_error_code::corrupt_file,
3434 "Invalid hash table signature");
35 if (H->HashVersion != 1 && H->HashVersion != 2)
35 if (Header->HashVersion != 1 && Header->HashVersion != 2)
3636 return make_error(raw_error_code::corrupt_file,
3737 "Unsupported hash version");
3838
39 Signature = H->Signature;
40 HashVersion = H->HashVersion;
41 if (auto EC = Stream.readStreamRef(NamesBuffer, H->ByteSize))
39 assert(Reader.bytesRemaining() == 0);
40 return Error::success();
41 }
42
43 Error PDBStringTable::readStrings(BinaryStreamReader &Reader) {
44 if (auto EC = Strings.initialize(Reader)) {
4245 return joinErrors(std::move(EC),
4346 make_error(raw_error_code::corrupt_file,
4447 "Invalid hash table byte length"));
48 }
4549
50 assert(Reader.bytesRemaining() == 0);
51 return Error::success();
52 }
53
54 Error PDBStringTable::readHashTable(BinaryStreamReader &Reader) {
4655 const support::ulittle32_t *HashCount;
47 if (auto EC = Stream.readObject(HashCount))
56 if (auto EC = Reader.readObject(HashCount))
4857 return EC;
4958
50 if (auto EC = Stream.readArray(IDs, *HashCount))
59 if (auto EC = Reader.readArray(IDs, *HashCount)) {
5160 return joinErrors(std::move(EC),
5261 make_error(raw_error_code::corrupt_file,
5362 "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");
63 }
6564
6665 return Error::success();
6766 }
6867
69 uint32_t PDBStringTable::getByteSize() const { return ByteSize; }
68 Error PDBStringTable::readEpilogue(BinaryStreamReader &Reader) {
69 if (auto EC = Reader.readInteger(NameCount))
70 return EC;
71
72 assert(Reader.bytesRemaining() == 0);
73 return Error::success();
74 }
75
76 Error PDBStringTable::reload(BinaryStreamReader &Reader) {
77
78 BinaryStreamReader SectionReader;
79
80 std::tie(SectionReader, Reader) = Reader.split(sizeof(PDBStringTableHeader));
81 if (auto EC = readHeader(SectionReader))
82 return EC;
83
84 std::tie(SectionReader, Reader) = Reader.split(Header->ByteSize);
85 if (auto EC = readStrings(SectionReader))
86 return EC;
87
88 // We don't know how long the hash table is until we parse it, so let the
89 // function responsible for doing that figure it out.
90 if (auto EC = readHashTable(Reader))
91 return EC;
92
93 std::tie(SectionReader, Reader) = Reader.split(sizeof(uint32_t));
94 if (auto EC = readEpilogue(SectionReader))
95 return EC;
96
97 assert(Reader.bytesRemaining() == 0);
98 return Error::success();
99 }
70100
71101 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;
102 return Strings.getString(ID);
84103 }
85104
86105 uint32_t PDBStringTable::getIDForString(StringRef Str) const {
87 uint32_t Hash = (HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
106 uint32_t Hash =
107 (Header->HashVersion == 1) ? hashStringV1(Str) : hashStringV2(Str);
88108 size_t Count = IDs.size();
89109 uint32_t Start = Hash % Count;
90110 for (size_t I = 0; I < Count; ++I) {
77 //===----------------------------------------------------------------------===//
88
99 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
10
1011 #include "llvm/ADT/ArrayRef.h"
12 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1113 #include "llvm/DebugInfo/PDB/Native/Hash.h"
14 #include "llvm/DebugInfo/PDB/Native/PDBFileBuilder.h"
1215 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1316 #include "llvm/Support/BinaryStreamWriter.h"
1417 #include "llvm/Support/Endian.h"
1518
1619 using namespace llvm;
20 using namespace llvm::msf;
1721 using namespace llvm::support;
1822 using namespace llvm::support::endian;
1923 using namespace llvm::pdb;
2024
2125 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;
26 return Strings.insert(S);
3527 }
3628
3729 static uint32_t computeBucketCount(uint32_t NumStrings) {
4335 return (NumStrings + 1) * 1.25;
4436 }
4537
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.
38 uint32_t PDBStringTableBuilder::calculateHashTableSize() const {
39 uint32_t Size = sizeof(uint32_t); // Hash table begins with 4-byte size field.
40 Size += sizeof(uint32_t) * computeBucketCount(Strings.size());
5141
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.
5742 return Size;
5843 }
5944
60 Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
45 uint32_t PDBStringTableBuilder::calculateSerializedSize() const {
46 uint32_t Size = 0;
47 Size += sizeof(PDBStringTableHeader);
48 Size += Strings.calculateSerializedSize();
49 Size += calculateHashTableSize();
50 Size += sizeof(uint32_t); // The /names stream ends with the string count.
51 return Size;
52 }
53
54 Error PDBStringTableBuilder::writeHeader(BinaryStreamWriter &Writer) const {
6155 // Write a header
6256 PDBStringTableHeader H;
6357 H.Signature = PDBStringTableSignature;
6458 H.HashVersion = 1;
65 H.ByteSize = StringSize;
59 H.ByteSize = Strings.calculateSerializedSize();
6660 if (auto EC = Writer.writeObject(H))
6761 return EC;
62 assert(Writer.bytesRemaining() == 0);
63 return Error::success();
64 }
6865
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);
66 Error PDBStringTableBuilder::writeStrings(BinaryStreamWriter &Writer) const {
67 if (auto EC = Strings.commit(Writer))
68 return EC;
7969
70 assert(Writer.bytesRemaining() == 0);
71 return Error::success();
72 }
73
74 Error PDBStringTableBuilder::writeHashTable(BinaryStreamWriter &Writer) const {
8075 // Write a hash table.
8176 uint32_t BucketCount = computeBucketCount(Strings.size());
8277 if (auto EC = Writer.writeInteger(BucketCount))
8378 return EC;
8479 std::vector Buckets(BucketCount);
8580
86 for (auto Pair : Strings) {
87 StringRef S = Pair.first;
88 uint32_t Offset = Pair.second;
81 for (auto &Pair : Strings) {
82 StringRef S = Pair.getKey();
83 uint32_t Offset = Pair.getValue();
8984 uint32_t Hash = hashStringV1(S);
9085
9186 for (uint32_t I = 0; I != BucketCount; ++I) {
10196
10297 if (auto EC = Writer.writeArray(ArrayRef(Buckets)))
10398 return EC;
104 if (auto EC = Writer.writeInteger(static_cast(Strings.size())))
105 return EC;
99
100 assert(Writer.bytesRemaining() == 0);
106101 return Error::success();
107102 }
103
104 Error PDBStringTableBuilder::writeEpilogue(BinaryStreamWriter &Writer) const {
105 if (auto EC = Writer.writeInteger(Strings.size()))
106 return EC;
107 assert(Writer.bytesRemaining() == 0);
108 return Error::success();
109 }
110
111 Error PDBStringTableBuilder::commit(BinaryStreamWriter &Writer) const {
112 BinaryStreamWriter SectionWriter;
113
114 std::tie(SectionWriter, Writer) = Writer.split(sizeof(PDBStringTableHeader));
115 if (auto EC = writeHeader(SectionWriter))
116 return EC;
117
118 std::tie(SectionWriter, Writer) =
119 Writer.split(Strings.calculateSerializedSize());
120 if (auto EC = writeStrings(SectionWriter))
121 return EC;
122
123 std::tie(SectionWriter, Writer) = Writer.split(calculateHashTableSize());
124 if (auto EC = writeHashTable(SectionWriter))
125 return EC;
126
127 std::tie(SectionWriter, Writer) = Writer.split(sizeof(uint32_t));
128 if (auto EC = writeEpilogue(SectionWriter))
129 return EC;
130
131 return Error::success();
132 }
9292 llvm::consumeError(std::move(EC));
9393 return Buffer[0];
9494 }
95
96 std::pair
97 BinaryStreamReader::split(uint32_t Off) const {
98 assert(getLength() >= Off);
99
100 BinaryStreamRef First = Stream.drop_front(Offset);
101
102 BinaryStreamRef Second = First.drop_front(Off);
103 First = First.keep_front(Off);
104 BinaryStreamReader W1{First};
105 BinaryStreamReader W2{Second};
106 return std::make_pair(W1, W2);
107 }
5858 return Error::success();
5959 }
6060
61 std::pair
62 BinaryStreamWriter::split(uint32_t Off) const {
63 assert(getLength() >= Off);
64
65 WritableBinaryStreamRef First = Stream.drop_front(Offset);
66
67 WritableBinaryStreamRef Second = First.drop_front(Off);
68 First = First.keep_front(Off);
69 BinaryStreamWriter W1{First};
70 BinaryStreamWriter W2{Second};
71 return std::make_pair(W1, W2);
72 }
73
6174 Error BinaryStreamWriter::padToAlignment(uint32_t Align) {
6275 uint32_t NewOffset = alignTo(Offset, Align);
6376 if (NewOffset > getLength())
3232 EXPECT_EQ(1U, Builder.insert("foo"));
3333 EXPECT_EQ(9U, Builder.insert("baz"));
3434
35 std::vector Buffer(Builder.finalize());
35 std::vector Buffer(Builder.calculateSerializedSize());
3636 MutableBinaryByteStream OutStream(Buffer, little);
3737 BinaryStreamWriter Writer(OutStream);
3838 EXPECT_NO_ERROR(Builder.commit(Writer));
4141 BinaryByteStream InStream(Buffer, little);
4242 BinaryStreamReader Reader(InStream);
4343 PDBStringTable Table;
44 EXPECT_NO_ERROR(Table.load(Reader));
44 EXPECT_NO_ERROR(Table.reload(Reader));
4545
4646 EXPECT_EQ(3U, Table.getNameCount());
4747 EXPECT_EQ(1U, Table.getHashVersion());