llvm.org GIT mirror llvm / 50d692d
Teach `llvm-pdbutil pretty -native` about `-injected-sources` `pretty -native -injected-sources -injected-source-content` works with this patch, and produces identical output to the dia version. Differential Revision: https://reviews.llvm.org/D64428 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366236 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber a month ago
12 changed file(s) with 383 addition(s) and 21 deletion(s). Raw diff Collapse all Expand all
7171 assert(Map->Present.test(Index));
7272 return Map->Buckets[Index];
7373 }
74
75 // Implement postfix op++ in terms of prefix op++ by using the superclass
76 // implementation.
77 using iterator_facade_base,
78 std::forward_iterator_tag,
79 const std::pair>::operator++;
7480 HashTableIterator &operator++() {
7581 while (Index < Map->Buckets.size()) {
7682 ++Index;
9399
94100 template
95101 class HashTable {
96 using const_iterator = HashTableIterator;
97 friend const_iterator;
98
99102 struct Header {
100103 support::ulittle32_t Size;
101104 support::ulittle32_t Capacity;
104107 using BucketList = std::vector>;
105108
106109 public:
110 using const_iterator = HashTableIterator;
111 friend const_iterator;
112
107113 HashTable() { Buckets.resize(8); }
108114 explicit HashTable(uint32_t Capacity) {
109115 Buckets.resize(Capacity);
0 //===- InjectedSourceStream.h - PDB Headerblock Stream Access ---*- C++ -*-===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_DEBUGINFO_PDB_RAW_PDBINJECTEDSOURCESTREAM_H
9 #define LLVM_DEBUGINFO_PDB_RAW_PDBINJECTEDSOURCESTREAM_H
10
11 #include "llvm/DebugInfo/PDB/Native/HashTable.h"
12 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
13 #include "llvm/Support/Error.h"
14
15 namespace llvm {
16 namespace msf {
17 class MappedBlockStream;
18 }
19 namespace pdb {
20 class PDBFile;
21 class PDBStringTable;
22
23 class InjectedSourceStream {
24 public:
25 InjectedSourceStream(std::unique_ptr Stream);
26 Error reload(const PDBStringTable &Strings);
27
28 using const_iterator = HashTable::const_iterator;
29 const_iterator begin() const { return InjectedSourceTable.begin(); }
30 const_iterator end() const { return InjectedSourceTable.end(); }
31
32 uint32_t size() const { return InjectedSourceTable.size(); }
33
34 private:
35 std::unique_ptr Stream;
36
37 const SrcHeaderBlockHeader* Header;
38 HashTable InjectedSourceTable;
39 };
40 }
41 }
42
43 #endif
0 //==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #ifndef LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMINJECTEDSOURCES_H
9 #define LLVM_DEBUGINFO_PDB_NATIVE_NATIVEENUMINJECTEDSOURCES_H
10
11 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
12 #include "llvm/DebugInfo/PDB/IPDBInjectedSource.h"
13 #include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
14
15 namespace llvm {
16 namespace pdb {
17
18 class InjectedSourceStream;
19 class PDBStringTable;
20
21 class NativeEnumInjectedSources : public IPDBEnumChildren {
22 public:
23 NativeEnumInjectedSources(PDBFile &File, const InjectedSourceStream &IJS,
24 const PDBStringTable &Strings);
25
26 uint32_t getChildCount() const override;
27 std::unique_ptr
28 getChildAtIndex(uint32_t Index) const override;
29 std::unique_ptr getNext() override;
30 void reset() override;
31
32 private:
33 PDBFile &File;
34 const InjectedSourceStream &Stream;
35 const PDBStringTable &Strings;
36 InjectedSourceStream::const_iterator Cur;
37 };
38
39 } // namespace pdb
40 } // namespace llvm
41
42 #endif
3131 class DbiStream;
3232 class GlobalsStream;
3333 class InfoStream;
34 class InjectedSourceStream;
3435 class PDBStringTable;
3536 class PDBFileBuilder;
3637 class PublicsStream;
8687 createIndexedStream(uint16_t SN) const;
8788 Expected>
8889 safelyCreateIndexedStream(uint32_t StreamIndex) const;
90 Expected>
91 safelyCreateNamedStream(StringRef Name);
8992
9093 msf::MSFStreamLayout getStreamLayout(uint32_t StreamIdx) const;
9194 msf::MSFStreamLayout getFpmStreamLayout() const;
101104 Expected getPDBPublicsStream();
102105 Expected getPDBSymbolStream();
103106 Expected getStringTable();
107 Expected getInjectedSourceStream();
104108
105109 BumpPtrAllocator &getAllocator() { return Allocator; }
106110
112116 bool hasPDBSymbolStream();
113117 bool hasPDBTpiStream() const;
114118 bool hasPDBStringTable();
119 bool hasPDBInjectedSourceStream();
115120
116121 uint32_t getPointerSize();
117122
132137 std::unique_ptr Symbols;
133138 std::unique_ptr DirectoryStream;
134139 std::unique_ptr StringTableStream;
140 std::unique_ptr InjectedSources;
135141 std::unique_ptr Strings;
136142 };
137143 }
4646 Native/HashTable.cpp
4747 Native/InfoStream.cpp
4848 Native/InfoStreamBuilder.cpp
49 Native/InjectedSourceStream.cpp
4950 Native/ModuleDebugStream.cpp
5051 Native/NativeCompilandSymbol.cpp
5152 Native/NativeEnumGlobals.cpp
53 Native/NativeEnumInjectedSources.cpp
5254 Native/NativeEnumModules.cpp
5355 Native/NativeEnumTypes.cpp
5456 Native/NativeExeSymbol.cpp
0 //===- InjectedSourceStream.cpp - PDB Headerblock Stream Access -----------===//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
9
10 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
11 #include "llvm/DebugInfo/PDB/Native/Hash.h"
12 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
13 #include "llvm/DebugInfo/PDB/Native/RawConstants.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::msf;
20 using namespace llvm::support;
21 using namespace llvm::pdb;
22
23 InjectedSourceStream::InjectedSourceStream(
24 std::unique_ptr Stream)
25 : Stream(std::move(Stream)) {}
26
27 Error InjectedSourceStream::reload(const PDBStringTable &Strings) {
28 BinaryStreamReader Reader(*Stream);
29
30 if (auto EC = Reader.readObject(Header))
31 return EC;
32
33 if (Header->Version !=
34 static_cast(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
35 return make_error(raw_error_code::corrupt_file,
36 "Invalid headerblock header version");
37
38 if (auto EC = InjectedSourceTable.load(Reader))
39 return EC;
40
41 for (const auto& Entry : *this) {
42 if (Entry.second.Size != sizeof(SrcHeaderBlockEntry))
43 return make_error(raw_error_code::corrupt_file,
44 "Invalid headerbock entry size");
45 if (Entry.second.Version !=
46 static_cast(PdbRaw_SrcHeaderBlockVer::SrcVerOne))
47 return make_error(raw_error_code::corrupt_file,
48 "Invalid headerbock entry version");
49
50 // Check that all name references are valid.
51 auto Name = Strings.getStringForID(Entry.second.FileNI);
52 if (!Name)
53 return Name.takeError();
54 auto ObjName = Strings.getStringForID(Entry.second.ObjNI);
55 if (!ObjName)
56 return ObjName.takeError();
57 auto VName = Strings.getStringForID(Entry.second.VFileNI);
58 if (!VName)
59 return VName.takeError();
60 }
61
62 assert(Reader.bytesRemaining() == 0);
63 return Error::success();
64 }
0 //==- NativeEnumInjectedSources.cpp - Native Injected Source Enumerator --*-==//
1 //
2 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3 // See https://llvm.org/LICENSE.txt for license information.
4 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5 //
6 //===----------------------------------------------------------------------===//
7
8 #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
9
10 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
11 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
12 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
13
14 namespace llvm {
15 namespace pdb {
16
17 namespace {
18
19 Expected readStreamData(BinaryStream &Stream) {
20 uint32_t Offset = 0, DataLength = Stream.getLength();
21 std::string Result;
22 Result.reserve(DataLength);
23 while (Offset < DataLength) {
24 ArrayRef Data;
25 if (auto E = Stream.readLongestContiguousChunk(Offset, Data))
26 return std::move(E);
27 Offset += Data.size();
28 Result += toStringRef(Data);
29 }
30 return Result;
31 }
32
33 class NativeInjectedSource final : public IPDBInjectedSource {
34 const SrcHeaderBlockEntry &Entry;
35 const PDBStringTable &Strings;
36 PDBFile &File;
37
38 public:
39 NativeInjectedSource(const SrcHeaderBlockEntry &Entry,
40 PDBFile &File, const PDBStringTable &Strings)
41 : Entry(Entry), Strings(Strings), File(File) {}
42
43 uint32_t getCrc32() const override { return Entry.CRC; }
44 uint64_t getCodeByteSize() const override { return Entry.FileSize; }
45
46 std::string getFileName() const override {
47 auto Name = Strings.getStringForID(Entry.FileNI);
48 assert(Name && "InjectedSourceStream should have rejected this");
49 return *Name;
50 }
51
52 std::string getObjectFileName() const override {
53 auto ObjName = Strings.getStringForID(Entry.ObjNI);
54 assert(ObjName && "InjectedSourceStream should have rejected this");
55 return *ObjName;
56 }
57
58 std::string getVirtualFileName() const override {
59 auto VName = Strings.getStringForID(Entry.VFileNI);
60 assert(VName && "InjectedSourceStream should have rejected this");
61 return *VName;
62 }
63
64 PDB_SourceCompression getCompression() const override {
65 return static_cast(Entry.Compression);
66 }
67
68 std::string getCode() const override {
69 // Get name of stream storing the data.
70 auto VName = Strings.getStringForID(Entry.VFileNI);
71 assert(VName && "InjectedSourceStream should have rejected this");
72 std::string StreamName = ("/src/files/" + *VName).str();
73
74 // Find stream with that name and read its data.
75 // FIXME: Consider validating (or even loading) all this in
76 // InjectedSourceStream so that no error can happen here.
77 auto ExpectedFileStream = File.safelyCreateNamedStream(StreamName);
78 if (!ExpectedFileStream) {
79 consumeError(ExpectedFileStream.takeError());
80 return "(failed to open data stream)";
81 }
82
83 auto Data = readStreamData(**ExpectedFileStream);
84 if (!Data) {
85 consumeError(Data.takeError());
86 return "(failed to read data)";
87 }
88 return *Data;
89 }
90 };
91
92 } // namespace
93
94 NativeEnumInjectedSources::NativeEnumInjectedSources(
95 PDBFile &File, const InjectedSourceStream &IJS,
96 const PDBStringTable &Strings)
97 : File(File), Stream(IJS), Strings(Strings), Cur(Stream.begin()) {}
98
99 uint32_t NativeEnumInjectedSources::getChildCount() const {
100 return static_cast(Stream.size());
101 }
102
103 std::unique_ptr
104 NativeEnumInjectedSources::getChildAtIndex(uint32_t N) const {
105 if (N >= getChildCount())
106 return nullptr;
107 return make_unique(std::next(Stream.begin(), N)->second,
108 File, Strings);
109 }
110
111 std::unique_ptr NativeEnumInjectedSources::getNext() {
112 if (Cur == Stream.end())
113 return nullptr;
114 return make_unique((Cur++)->second, File, Strings);
115 }
116
117 void NativeEnumInjectedSources::reset() { Cur = Stream.begin(); }
118
119 }
120 }
1212 #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h"
1313 #include "llvm/DebugInfo/PDB/IPDBSourceFile.h"
1414 #include "llvm/DebugInfo/PDB/Native/NativeCompilandSymbol.h"
15 #include "llvm/DebugInfo/PDB/Native/NativeEnumInjectedSources.h"
1516 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
1617 #include "llvm/DebugInfo/PDB/Native/NativeExeSymbol.h"
1718 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
190191
191192 std::unique_ptr
192193 NativeSession::getInjectedSources() const {
193 return nullptr;
194 auto ISS = Pdb->getInjectedSourceStream();
195 if (!ISS) {
196 consumeError(ISS.takeError());
197 return nullptr;
198 }
199 auto Strings = Pdb->getStringTable();
200 if (!Strings) {
201 consumeError(Strings.takeError());
202 return nullptr;
203 }
204 return make_unique(*Pdb, *ISS, *Strings);
194205 }
195206
196207 std::unique_ptr
1313 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1414 #include "llvm/DebugInfo/PDB/Native/GlobalsStream.h"
1515 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
16 #include "llvm/DebugInfo/PDB/Native/InjectedSourceStream.h"
1617 #include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
1718 #include "llvm/DebugInfo/PDB/Native/PublicsStream.h"
1819 #include "llvm/DebugInfo/PDB/Native/RawError.h"
364365
365366 Expected PDBFile::getStringTable() {
366367 if (!Strings) {
367 auto IS = getPDBInfoStream();
368 if (!IS)
369 return IS.takeError();
370
371 Expected ExpectedNSI = IS->getNamedStreamIndex("/names");
372 if (!ExpectedNSI)
373 return ExpectedNSI.takeError();
374 uint32_t NameStreamIndex = *ExpectedNSI;
375
376 auto NS = safelyCreateIndexedStream(NameStreamIndex);
368 auto NS = safelyCreateNamedStream("/names");
377369 if (!NS)
378370 return NS.takeError();
379371
386378 Strings = std::move(N);
387379 }
388380 return *Strings;
381 }
382
383 Expected PDBFile::getInjectedSourceStream() {
384 if (!InjectedSources) {
385 auto IJS = safelyCreateNamedStream("/src/headerblock");
386 if (!IJS)
387 return IJS.takeError();
388
389 auto Strings = getStringTable();
390 if (!Strings)
391 return Strings.takeError();
392
393 auto IJ = llvm::make_unique(std::move(*IJS));
394 if (auto EC = IJ->reload(*Strings))
395 return std::move(EC);
396 InjectedSources = std::move(IJ);
397 }
398 return *InjectedSources;
389399 }
390400
391401 uint32_t PDBFile::getPointerSize() {
448458 if (!IS)
449459 return false;
450460 Expected ExpectedNSI = IS->getNamedStreamIndex("/names");
461 if (!ExpectedNSI) {
462 consumeError(ExpectedNSI.takeError());
463 return false;
464 }
465 assert(*ExpectedNSI < getNumStreams());
466 return true;
467 }
468
469 bool PDBFile::hasPDBInjectedSourceStream() {
470 auto IS = getPDBInfoStream();
471 if (!IS)
472 return false;
473 Expected ExpectedNSI = IS->getNamedStreamIndex("/src/headerblock");
451474 if (!ExpectedNSI) {
452475 consumeError(ExpectedNSI.takeError());
453476 return false;
467490 return make_error(raw_error_code::no_stream);
468491 return createIndexedStream(StreamIndex);
469492 }
493
494 Expected>
495 PDBFile::safelyCreateNamedStream(StringRef Name) {
496 auto IS = getPDBInfoStream();
497 if (!IS)
498 return IS.takeError();
499
500 Expected ExpectedNSI = IS->getNamedStreamIndex(Name);
501 if (!ExpectedNSI)
502 return ExpectedNSI.takeError();
503 uint32_t NameStreamIndex = *ExpectedNSI;
504
505 return safelyCreateIndexedStream(NameStreamIndex);
506 }
0 ; This is identical to injected-sources.test, except that it uses the -native
1 ; mode of pretty (and hence doesn't require diasdk and runs on all platforms).
2
3 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
4 ; RUN: %p/Inputs/InjectedSource.pdb | FileCheck %s
5 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
6 ; RUN: %p/Inputs/ClassLayoutTest.pdb | FileCheck --check-prefix=NEGATIVE %s
7
8 ; CHECK: ---INJECTED SOURCES---
9 ; CHECK: c.natvis (140 bytes): obj=, vname=c.natvis, crc=334478030, compression=None
10 ; CHECK-NEXT:
11 ; CHECK-NEXT:
12 ; CHECK-NEXT:
13 ; CHECK: a.natvis (140 bytes): obj=, vname=a.natvis, crc=334478030, compression=None
14 ; CHECK-NEXT:
15 ; CHECK-NEXT:
16 ; CHECK-NEXT:
17 ; CHECK: b.natvis (294 bytes): obj=, vname=b.natvis, crc=2059731902, compression=None
18 ; CHECK-NEXT:
19 ; CHECK-NEXT:
20 ; CHECK-NEXT:
21 ; CHECK-NEXT: Third test
22 ; CHECK-NEXT:
23 ; CHECK-NEXT:
24 ; CHECK-NEXT: Fourth test
25 ; CHECK-NEXT:
26 ; CHECK-NEXT:
27
28 ; NEGATIVE: ---INJECTED SOURCES---
29 ; NEGATIVE-NEXT: There are no injected sources.
933933
934934 static void dumpInjectedSources(LinePrinter &Printer, IPDBSession &Session) {
935935 auto Sources = Session.getInjectedSources();
936 if (0 == Sources->getChildCount()) {
936 if (!Sources || !Sources->getChildCount()) {
937937 Printer.printLine("There are no injected sources.");
938938 return;
939939 }
12781278 WithColor(Printer, PDB_ColorItem::SectionHeader).get()
12791279 << "---INJECTED SOURCES---";
12801280 AutoIndent Indent1(Printer);
1281
1282 if (ReaderType == PDB_ReaderType::Native)
1283 Printer.printLine(
1284 "Injected sources are not supported with the native reader.");
1285 else
1286 dumpInjectedSources(Printer, *Session);
1281 dumpInjectedSources(Printer, *Session);
12871282 }
12881283
12891284 Printer.NewLine();
2323 "Native/HashTable.cpp",
2424 "Native/InfoStream.cpp",
2525 "Native/InfoStreamBuilder.cpp",
26 "Native/InjectedSourceStream.cpp",
2627 "Native/ModuleDebugStream.cpp",
2728 "Native/NamedStreamMap.cpp",
2829 "Native/NativeCompilandSymbol.cpp",
2930 "Native/NativeEnumGlobals.cpp",
31 "Native/NativeEnumInjectedSources.cpp",
3032 "Native/NativeEnumModules.cpp",
3133 "Native/NativeEnumTypes.cpp",
3234 "Native/NativeExeSymbol.cpp",