llvm.org GIT mirror llvm / c643a82
Revert "Support embedding natvis files in PDBs." This is causing a test failure on a certain bot, so I'm removing this temporarily until we can figure out the source of the error. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327903 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 1 year, 5 months ago
19 changed file(s) with 43 addition(s) and 310 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
1010 #define LLVM_DEBUGINFO_CODEVIEW_DEBUGSTRINGTABLESUBSECTION_H
1111
12 #include "llvm/ADT/DenseMap.h"
1312 #include "llvm/ADT/StringMap.h"
1413 #include "llvm/ADT/StringRef.h"
1514 #include "llvm/DebugInfo/CodeView/CodeView.h"
6665 uint32_t insert(StringRef S);
6766
6867 // Return the ID for string S. Assumes S exists in the table.
69 uint32_t getIdForString(StringRef S) const;
70
71 StringRef getStringForId(uint32_t Id) const;
68 uint32_t getStringId(StringRef S) const;
7269
7370 uint32_t calculateSerializedSize() const override;
7471 Error commit(BinaryStreamWriter &Writer) const override;
7572
7673 uint32_t size() const;
7774
78 StringMap::const_iterator begin() const {
79 return StringToId.begin();
80 }
75 StringMap::const_iterator begin() const { return Strings.begin(); }
8176
82 StringMap::const_iterator end() const { return StringToId.end(); }
77 StringMap::const_iterator end() const { return Strings.end(); }
8378
8479 private:
85 DenseMap IdToString;
86 StringMap StringToId;
80 StringMap Strings;
8781 uint32_t StringSize = 1;
8882 };
8983
1818
1919 class DIAInjectedSource : public IPDBInjectedSource {
2020 public:
21 explicit DIAInjectedSource(CComPtr DiaSourceFile);
21 explicit DIAInjectedSource(const DIASession &Session,
22 CComPtr DiaSourceFile);
2223
2324 uint32_t getCrc32() const override;
2425 uint64_t getCodeByteSize() const override;
2930 std::string getCode() const override;
3031
3132 private:
33 const DIASession &Session;
3234 CComPtr SourceFile;
3335 };
3436 } // namespace pdb
212212 Deleted.clear();
213213 }
214214
215 bool empty() const { return size() == 0; }
216215 uint32_t capacity() const { return Buckets.size(); }
217216 uint32_t size() const { return Present.count(); }
218217
303302
304303 void grow() {
305304 uint32_t S = size();
306 uint32_t MaxLoad = maxLoad(capacity());
307305 if (S < maxLoad(capacity()))
308306 return;
309307 assert(capacity() != UINT32_MAX && "Can't grow Hash table!");
310308
311 uint32_t NewCapacity = (capacity() <= INT32_MAX) ? MaxLoad * 2 : UINT32_MAX;
309 uint32_t NewCapacity =
310 (capacity() <= INT32_MAX) ? capacity() * 2 : UINT32_MAX;
312311
313312 // Growing requires rebuilding the table and re-hashing every item. Make a
314313 // copy with a larger capacity, insert everything into the copy, then swap
1616 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1717 #include "llvm/DebugInfo/PDB/Native/PDBStringTableBuilder.h"
1818 #include "llvm/DebugInfo/PDB/Native/RawConstants.h"
19 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
2019 #include "llvm/Support/Allocator.h"
2120 #include "llvm/Support/Endian.h"
2221 #include "llvm/Support/Error.h"
23 #include "llvm/Support/MemoryBuffer.h"
2422
2523 #include
2624 #include
5553 Error commit(StringRef Filename);
5654
5755 Expected getNamedStreamIndex(StringRef Name) const;
58 Error addNamedStream(StringRef Name, StringRef Data);
59 void addInjectedSource(StringRef Name, std::unique_ptr Buffer);
56 Error addNamedStream(StringRef Name, uint32_t Size);
6057
6158 private:
62 struct InjectedSourceDescriptor {
63 // The full name of the stream that contains the contents of this injected
64 // source. This is built as a concatenation of the literal "/src/files"
65 // plus the "vname".
66 std::string StreamName;
67
68 // The exact name of the file name as specified by the user.
69 uint32_t NameIndex;
70
71 // The string table index of the "vname" of the file. As far as we
72 // understand, this is the same as the name, except it is lowercased and
73 // forward slashes are converted to backslashes.
74 uint32_t VNameIndex;
75 std::unique_ptr Content;
76 };
77
7859 Expected finalizeMsfLayout();
79 Expected allocateNamedStream(StringRef Name, uint32_t Size);
8060
8161 void commitFpm(WritableBinaryStream &MsfBuffer, const msf::MSFLayout &Layout);
82 void commitInjectedSources(WritableBinaryStream &MsfBuffer,
83 const msf::MSFLayout &Layout);
84 void commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
85 const msf::MSFLayout &Layout);
8662
8763 BumpPtrAllocator &Allocator;
8864
9470 std::unique_ptr Ipi;
9571
9672 PDBStringTableBuilder Strings;
97 StringTableHashTraits InjectedSourceHashTraits;
98 HashTable InjectedSourceTable;
99
100 SmallVector InjectedSources;
101
10273 NamedStreamMap NamedStreams;
103 DenseMap NamedStreamData;
10474 };
10575 }
10676 }
3030 namespace pdb {
3131
3232 class PDBFileBuilder;
33 class PDBStringTableBuilder;
34
35 struct StringTableHashTraits {
36 PDBStringTableBuilder *Table;
37
38 explicit StringTableHashTraits(PDBStringTableBuilder &Table);
39 uint32_t hashLookupKey(StringRef S) const;
40 StringRef storageKeyToLookupKey(uint32_t Offset) const;
41 uint32_t lookupKeyToStorageKey(StringRef S);
42 };
4333
4434 class PDBStringTableBuilder {
4535 public:
4636 // If string S does not exist in the string table, insert it.
4737 // Returns the ID for S.
4838 uint32_t insert(StringRef S);
49
50 uint32_t getIdForString(StringRef S) const;
51 StringRef getStringForId(uint32_t Id) const;
5239
5340 uint32_t calculateSerializedSize() const;
5441 Error commit(BinaryStreamWriter &Writer) const;
3030 PdbImplVC110 = 20091201,
3131 PdbImplVC140 = 20140508,
3232 };
33
34 enum class PdbRaw_SrcHeaderBlockVer : uint32_t { SrcVerOne = 19980827 };
3533
3634 enum class PdbRaw_FeatureSig : uint32_t {
3735 VC110 = PdbImplVC110,
327327
328328 const uint32_t PDBStringTableSignature = 0xEFFEEFFE;
329329
330 /// The header preceding the /src/headerblock stream.
331 struct SrcHeaderBlockHeader {
332 support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration.
333 support::ulittle32_t Size; // Size of entire stream.
334 uint64_t FileTime; // Time stamp (Windows FILETIME format).
335 support::ulittle32_t Age; // Age
336 uint8_t Padding[44]; // Pad to 64 bytes.
337 };
338 static_assert(sizeof(SrcHeaderBlockHeader) == 64, "Incorrect struct size!");
339
340 /// A single file record entry within the /src/headerblock stream.
341 struct SrcHeaderBlockEntry {
342 support::ulittle32_t Size; // Record Length.
343 support::ulittle32_t Version; // PdbRaw_SrcHeaderBlockVer enumeration.
344 support::ulittle32_t CRC; // CRC of the original file contents.
345 support::ulittle32_t FileSize; // Size of original source file.
346 support::ulittle32_t FileNI; // String table index of file name.
347 support::ulittle32_t ObjNI; // String table index of object name.
348 support::ulittle32_t VFileNI; // String table index of virtual file name.
349 uint8_t Compression; // PDB_SourceCompression enumeration.
350 uint8_t IsVirtual; // Is this a virtual file (injected)?
351 short Padding; // Pad to 4 bytes.
352 char Reserved[8];
353 };
354
355 constexpr int I = sizeof(SrcHeaderBlockEntry);
356 static_assert(sizeof(SrcHeaderBlockEntry) == 40, "Incorrect struct size!");
357
358330 } // namespace pdb
359331 } // namespace llvm
360332
108108 }
109109
110110 uint32_t DebugChecksumsSubsection::mapChecksumOffset(StringRef FileName) const {
111 uint32_t Offset = Strings.getIdForString(FileName);
111 uint32_t Offset = Strings.getStringId(FileName);
112112 auto Iter = OffsetMap.find(Offset);
113113 assert(Iter != OffsetMap.end());
114114 return Iter->second;
7979 Ids.push_back(&M);
8080
8181 std::sort(Ids.begin(), Ids.end(), [this](const T &L1, const T &L2) {
82 return Strings.getIdForString(L1->getKey()) <
83 Strings.getIdForString(L2->getKey());
82 return Strings.getStringId(L1->getKey()) <
83 Strings.getStringId(L2->getKey());
8484 });
8585
8686 for (const auto &Item : Ids) {
8787 CrossModuleImport Imp;
88 Imp.ModuleNameOffset = Strings.getIdForString(Item->getKey());
88 Imp.ModuleNameOffset = Strings.getStringId(Item->getKey());
8989 Imp.Count = Item->getValue().size();
9090 if (auto EC = Writer.writeObject(Imp))
9191 return EC;
4545 : DebugSubsection(DebugSubsectionKind::StringTable) {}
4646
4747 uint32_t DebugStringTableSubsection::insert(StringRef S) {
48 auto P = StringToId.insert({S, StringSize});
48 auto P = Strings.insert({S, StringSize});
4949
5050 // If a given string didn't exist in the string table, we want to increment
51 // the string table size and insert it into the reverse lookup.
52 if (P.second) {
53 IdToString.insert({P.first->getValue(), P.first->getKey()});
51 // the string table size.
52 if (P.second)
5453 StringSize += S.size() + 1; // +1 for '\0'
55 }
56
5754 return P.first->second;
5855 }
5956
6966 if (auto EC = Writer.writeCString(StringRef()))
7067 return EC;
7168
72 for (auto &Pair : StringToId) {
69 for (auto &Pair : Strings) {
7370 StringRef S = Pair.getKey();
7471 uint32_t Offset = Begin + Pair.getValue();
7572 Writer.setOffset(Offset);
8380 return Error::success();
8481 }
8582
86 uint32_t DebugStringTableSubsection::size() const { return StringToId.size(); }
83 uint32_t DebugStringTableSubsection::size() const { return Strings.size(); }
8784
88 uint32_t DebugStringTableSubsection::getIdForString(StringRef S) const {
89 auto Iter = StringToId.find(S);
90 assert(Iter != StringToId.end());
85 uint32_t DebugStringTableSubsection::getStringId(StringRef S) const {
86 auto Iter = Strings.find(S);
87 assert(Iter != Strings.end());
9188 return Iter->second;
9289 }
93
94 StringRef DebugStringTableSubsection::getStringForId(uint32_t Id) const {
95 auto Iter = IdToString.find(Id);
96 assert(Iter != IdToString.end());
97 return Iter->second;
98 }
2929 if (S_OK != Enumerator->Item(Index, &Item))
3030 return nullptr;
3131
32 return std::unique_ptr(new DIAInjectedSource(Item));
32 return std::unique_ptr(
33 new DIAInjectedSource(Session, Item));
3334 }
3435
3536 std::unique_ptr DIAEnumInjectedSources::getNext() {
3839 if (S_OK != Enumerator->Next(1, &Item, &NumFetched))
3940 return nullptr;
4041
41 return std::unique_ptr(new DIAInjectedSource(Item));
42 return std::unique_ptr(
43 new DIAInjectedSource(Session, Item));
4244 }
4345
4446 void DIAEnumInjectedSources::reset() { Enumerator->Reset(); }
1515 using namespace llvm;
1616 using namespace llvm::pdb;
1717
18 DIAInjectedSource::DIAInjectedSource(CComPtr DiaSourceFile)
19 : SourceFile(DiaSourceFile) {}
18 DIAInjectedSource::DIAInjectedSource(const DIASession &Session,
19 CComPtr DiaSourceFile)
20 : Session(Session), SourceFile(DiaSourceFile) {}
2021
2122 uint32_t DIAInjectedSource::getCrc32() const {
2223 DWORD Crc;
7272 if (auto EC = Writer.writeEnum(E))
7373 return EC;
7474 }
75 assert(Writer.bytesRemaining() == 0);
7675 return Error::success();
7776 }
2323 #include "llvm/DebugInfo/PDB/Native/TpiStreamBuilder.h"
2424 #include "llvm/Support/BinaryStream.h"
2525 #include "llvm/Support/BinaryStreamWriter.h"
26 #include "llvm/Support/JamCRC.h"
27 #include "llvm/Support/Path.h"
2826
2927 using namespace llvm;
3028 using namespace llvm::codeview;
3331 using namespace llvm::support;
3432
3533 PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
36 : Allocator(Allocator), InjectedSourceHashTraits(Strings),
37 InjectedSourceTable(2, InjectedSourceHashTraits) {}
34 : Allocator(Allocator) {}
3835
3936 PDBFileBuilder::~PDBFileBuilder() {}
4037
8279 return *Gsi;
8380 }
8481
85 Expected PDBFileBuilder::allocateNamedStream(StringRef Name,
86 uint32_t Size) {
82 Error PDBFileBuilder::addNamedStream(StringRef Name, uint32_t Size) {
8783 auto ExpectedStream = Msf->addStream(Size);
88 if (ExpectedStream)
89 NamedStreams.set(Name, *ExpectedStream);
90 return ExpectedStream;
91 }
92
93 Error PDBFileBuilder::addNamedStream(StringRef Name, StringRef Data) {
94 Expected ExpectedIndex = allocateNamedStream(Name, Data.size());
95 if (!ExpectedIndex)
96 return ExpectedIndex.takeError();
97 assert(NamedStreamData.count(*ExpectedIndex) == 0);
98 NamedStreamData[*ExpectedIndex] = Data;
84 if (!ExpectedStream)
85 return ExpectedStream.takeError();
86 NamedStreams.set(Name, *ExpectedStream);
9987 return Error::success();
100 }
101
102 void PDBFileBuilder::addInjectedSource(StringRef Name,
103 std::unique_ptr Buffer) {
104 // Stream names must be exact matches, since they get looked up in a hash
105 // table and the hash value is dependent on the exact contents of the string.
106 // link.exe lowercases a path and converts / to \, so we must do the same.
107 SmallString<64> VName;
108 sys::path::native(Name.lower(), VName);
109
110 uint32_t NI = getStringTableBuilder().insert(Name);
111 uint32_t VNI = getStringTableBuilder().insert(VName);
112
113 InjectedSourceDescriptor Desc;
114 Desc.Content = std::move(Buffer);
115 Desc.NameIndex = NI;
116 Desc.VNameIndex = VNI;
117 Desc.StreamName = "/src/files/";
118
119 Desc.StreamName += VName;
120
121 InjectedSources.push_back(std::move(Desc));
12288 }
12389
12490 Expected PDBFileBuilder::finalizeMsfLayout() {
134100
135101 uint32_t StringsLen = Strings.calculateSerializedSize();
136102
137 Expected SN = allocateNamedStream("/names", StringsLen);
138 if (!SN)
139 return SN.takeError();
140 SN = allocateNamedStream("/LinkInfo", 0);
141 if (!SN)
142 return SN.takeError();
143
103 if (auto EC = addNamedStream("/names", StringsLen))
104 return std::move(EC);
105 if (auto EC = addNamedStream("/LinkInfo", 0))
106 return std::move(EC);
107
108 if (Info) {
109 if (auto EC = Info->finalizeMsfLayout())
110 return std::move(EC);
111 }
144112 if (Dbi) {
145113 if (auto EC = Dbi->finalizeMsfLayout())
146114 return std::move(EC);
161129 Dbi->setGlobalsStreamIndex(Gsi->getGlobalsStreamIndex());
162130 Dbi->setSymbolRecordStreamIndex(Gsi->getRecordStreamIdx());
163131 }
164 }
165
166 if (!InjectedSources.empty()) {
167 for (const auto &IS : InjectedSources) {
168 JamCRC CRC(0);
169 CRC.update(makeArrayRef(IS.Content->getBufferStart(),
170 IS.Content->getBufferSize()));
171
172 SrcHeaderBlockEntry Entry;
173 ::memset(&Entry, 0, sizeof(SrcHeaderBlockEntry));
174 Entry.Size = sizeof(SrcHeaderBlockEntry);
175 Entry.FileSize = IS.Content->getBufferSize();
176 Entry.FileNI = IS.NameIndex;
177 Entry.VFileNI = IS.VNameIndex;
178 Entry.IsVirtual = 0;
179 Entry.Version =
180 static_cast(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
181 Entry.CRC = CRC.getCRC();
182 StringRef VName = getStringTableBuilder().getStringForId(IS.VNameIndex);
183 InjectedSourceTable.set_as(VName, std::move(Entry));
184 }
185
186 uint32_t SrcHeaderBlockSize =
187 sizeof(SrcHeaderBlockHeader) +
188 InjectedSourceTable.calculateSerializedLength();
189 SN = allocateNamedStream("/src/headerblock", SrcHeaderBlockSize);
190 if (!SN)
191 return SN.takeError();
192 for (const auto &IS : InjectedSources) {
193 SN = allocateNamedStream(IS.StreamName, IS.Content->getBufferSize());
194 if (!SN)
195 return SN.takeError();
196 }
197 }
198
199 // Do this last, since it relies on the named stream map being complete, and
200 // that can be updated by previous steps in the finalization.
201 if (Info) {
202 if (auto EC = Info->finalizeMsfLayout())
203 return std::move(EC);
204132 }
205133
206134 return Msf->build();
238166 assert(FpmWriter.bytesRemaining() == 0);
239167 }
240168
241 void PDBFileBuilder::commitSrcHeaderBlock(WritableBinaryStream &MsfBuffer,
242 const msf::MSFLayout &Layout) {
243 assert(!InjectedSourceTable.empty());
244
245 uint32_t SN = cantFail(getNamedStreamIndex("/src/headerblock"));
246 auto Stream = WritableMappedBlockStream::createIndexedStream(
247 Layout, MsfBuffer, SN, Allocator);
248 BinaryStreamWriter Writer(*Stream);
249
250 SrcHeaderBlockHeader Header;
251 ::memset(&Header, 0, sizeof(Header));
252 Header.Version = static_cast(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
253 Header.Size = Writer.bytesRemaining();
254
255 cantFail(Writer.writeObject(Header));
256 cantFail(InjectedSourceTable.commit(Writer));
257
258 assert(Writer.bytesRemaining() == 0);
259 }
260
261 void PDBFileBuilder::commitInjectedSources(WritableBinaryStream &MsfBuffer,
262 const msf::MSFLayout &Layout) {
263 if (InjectedSourceTable.empty())
264 return;
265
266 commitSrcHeaderBlock(MsfBuffer, Layout);
267
268 for (const auto &IS : InjectedSources) {
269 uint32_t SN = cantFail(getNamedStreamIndex(IS.StreamName));
270
271 auto SourceStream = WritableMappedBlockStream::createIndexedStream(
272 Layout, MsfBuffer, SN, Allocator);
273 BinaryStreamWriter SourceWriter(*SourceStream);
274 assert(SourceWriter.bytesRemaining() == IS.Content->getBufferSize());
275 cantFail(SourceWriter.writeBytes(
276 arrayRefFromStringRef(IS.Content->getBuffer())));
277 }
278 }
279
280169 Error PDBFileBuilder::commit(StringRef Filename) {
281170 assert(!Filename.empty());
282171 auto ExpectedLayout = finalizeMsfLayout();
329218 if (auto EC = Strings.commit(NSWriter))
330219 return EC;
331220
332 for (const auto &NSE : NamedStreamData) {
333 if (NSE.second.empty())
334 continue;
335
336 auto NS = WritableMappedBlockStream::createIndexedStream(
337 Layout, Buffer, NSE.first, Allocator);
338 BinaryStreamWriter NSW(*NS);
339 if (auto EC = NSW.writeBytes(arrayRefFromStringRef(NSE.second)))
340 return EC;
341 }
342
343221 if (Info) {
344222 if (auto EC = Info->commit(Layout, Buffer))
345223 return EC;
371249 blockToOffset(InfoStreamBlocks.front(), Layout.SB->BlockSize);
372250 InfoStreamHeader *H = reinterpret_cast(
373251 FOB->getBufferStart() + InfoStreamFileOffset);
374
375 commitInjectedSources(Buffer, Layout);
376252
377253 // Set the build id at the very end, after every other byte of the PDB
378254 // has been written.
2020 using namespace llvm::support::endian;
2121 using namespace llvm::pdb;
2222
23 StringTableHashTraits::StringTableHashTraits(PDBStringTableBuilder &Table)
24 : Table(&Table) {}
25
26 uint32_t StringTableHashTraits::hashLookupKey(StringRef S) const {
27 return Table->getIdForString(S);
28 }
29
30 StringRef StringTableHashTraits::storageKeyToLookupKey(uint32_t Offset) const {
31 return Table->getStringForId(Offset);
32 }
33
34 uint32_t StringTableHashTraits::lookupKeyToStorageKey(StringRef S) {
35 return Table->insert(S);
36 }
37
3823 uint32_t PDBStringTableBuilder::insert(StringRef S) {
3924 return Strings.insert(S);
40 }
41
42 uint32_t PDBStringTableBuilder::getIdForString(StringRef S) const {
43 return Strings.getIdForString(S);
44 }
45
46 StringRef PDBStringTableBuilder::getStringForId(uint32_t Id) const {
47 return Strings.getStringForId(Id);
4825 }
4926
5027 static uint32_t computeBucketCount(uint32_t NumStrings) {
8989 P.NewLine();
9090 }
9191
92 if (opts::dump::DumpNamedStreams) {
93 if (auto EC = dumpNamedStreams())
94 return EC;
95 P.NewLine();
96 }
97
9892 if (opts::dump::DumpStringTable) {
9993 if (auto EC = dumpStringTable())
10094 return EC;
914908 return Error::success();
915909 }
916910
917 Error DumpOutputStyle::dumpNamedStreams() {
918 printHeader(P, "Named Streams");
919 AutoIndent Indent(P, 2);
920
921 if (File.isObj()) {
922 P.formatLine("Dumping Named Streams is only supported for PDB files.");
923 return Error::success();
924 }
925 ExitOnError Err("Invalid PDB File: ");
926
927 auto &IS = Err(File.pdb().getPDBInfoStream());
928 const NamedStreamMap &NS = IS.getNamedStreams();
929 for (const auto &Entry : NS.entries()) {
930 P.printLine(Entry.getKey());
931 AutoIndent Indent2(P, 2);
932 P.formatLine("Index: {0}", Entry.getValue());
933 P.formatLine("Size in bytes: {0}",
934 File.pdb().getStreamByteSize(Entry.getValue()));
935 }
936
937 return Error::success();
938 }
939
940911 Error DumpOutputStyle::dumpStringTable() {
941912 printHeader(P, "String Table");
942913
7373 Error dumpStreamSummary();
7474 Error dumpSymbolStats();
7575 Error dumpUdtStats();
76 Error dumpNamedStreams();
7776 Error dumpStringTable();
7877 Error dumpStringTableFromPdb();
7978 Error dumpStringTableFromObj();
533533 cl::cat(FileOptions), cl::sub(DumpSubcommand));
534534
535535 // MISCELLANEOUS OPTIONS
536 cl::opt DumpNamedStreams("named-streams",
537 cl::desc("dump PDB named stream table"),
538 cl::cat(MiscOptions), cl::sub(DumpSubcommand));
539
540536 cl::opt DumpStringTable("string-table", cl::desc("dump PDB String Table"),
541537 cl::cat(MiscOptions), cl::sub(DumpSubcommand));
542538
141141 extern llvm::cl::opt DumpInlineeLines;
142142 extern llvm::cl::opt DumpXmi;
143143 extern llvm::cl::opt DumpXme;
144 extern llvm::cl::opt DumpNamedStreams;
145144 extern llvm::cl::opt DumpStringTable;
146145 extern llvm::cl::opt DumpTypes;
147146 extern llvm::cl::opt DumpTypeData;