llvm.org GIT mirror llvm / f45b56d
llvm-pdbdump: Fix several smaller issues with injected source compression handling - getCompression() used to return a PDB_SourceCompression even though the docs for IDiaInjectedSource are explicit about the return value being compiler-dependent. Return an uint32_t instead, and make the printing code handle unknown values better by printing "Unknown" and the int value instead of not printing any compression. - Print compressed contents as hex dump, not as string. - Add compression type "DotNet", which is used (at least) by csc.exe, the C# compiler. Also add a lengthy comment describing the stream contents (derived from looking at the raw hex contents long enough to see the GUIDs, which led me to the roslyn and mono implementations for handling this). - The native injected source dumper was dumping the contents of the whole data stream -- but csc.exe writes a stream that's padded with zero bytes to the next 512 boundary, and the dia api doesn't display those padding bytes. So make NativeInjectedSource::getCode() do the same thing. Differential Revision: https://reviews.llvm.org/D64879 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@366386 91177308-0d34-0410-b5e6-96231b3b80d8 Nico Weber a month ago
14 changed file(s) with 181 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
2424 std::string getFileName() const override;
2525 std::string getObjectFileName() const override;
2626 std::string getVirtualFileName() const override;
27 PDB_SourceCompression getCompression() const override;
27 uint32_t getCompression() const override;
2828 std::string getCode() const override;
2929
3030 private:
88 #ifndef LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
99 #define LLVM_DEBUGINFO_PDB_IPDBINJECTEDSOURCE_H
1010
11 #include "PDBTypes.h"
1211 #include "llvm/Support/raw_ostream.h"
1312 #include
1413 #include
3130 virtual std::string getFileName() const = 0;
3231 virtual std::string getObjectFileName() const = 0;
3332 virtual std::string getVirtualFileName() const = 0;
34 virtual PDB_SourceCompression getCompression() const = 0;
33 // The returned value depends on the PDB producer,
34 // but 0 is guaranteed to mean "no compression".
35 // The enum PDB_SourceCompression lists known return values.
36 virtual uint32_t getCompression() const = 0;
3537 virtual std::string getCode() const = 0;
3638 };
3739 } // namespace pdb
3636 raw_ostream &operator<<(raw_ostream &OS, const PDB_MemberAccess &Access);
3737 raw_ostream &operator<<(raw_ostream &OS, const PDB_UdtType &Type);
3838 raw_ostream &operator<<(raw_ostream &OS, const PDB_Machine &Machine);
39 raw_ostream &operator<<(raw_ostream &OS,
40 const PDB_SourceCompression &Compression);
4139
4240 raw_ostream &operator<<(raw_ostream &OS, const Variant &Value);
4341 raw_ostream &operator<<(raw_ostream &OS, const VersionInfo &Version);
4442 raw_ostream &operator<<(raw_ostream &OS, const TagStats &Stats);
4543
44 raw_ostream& dumpPDBSourceCompression(raw_ostream& OS, uint32_t Compression);
4645
4746 template
4847 void dumpSymbolField(raw_ostream &OS, StringRef Name, T Value, int Indent) {
145145 WceMipsV2 = 0x169
146146 };
147147
148 enum class PDB_SourceCompression {
149 None,
150 RunLengthEncoded,
151 Huffman,
152 LZ,
148 // A struct with an inner unnamed enum with explicit underlying type resuls
149 // in an enum class that can implicitly convert to the underlying type, which
150 // is convenient for this enum.
151 struct PDB_SourceCompression {
152 enum : uint32_t {
153 // No compression. Produced e.g. by `link.exe /natvis:foo.natvis`.
154 None,
155 // Not known what produces this.
156 RunLengthEncoded,
157 // Not known what produces this.
158 Huffman,
159 // Not known what produces this.
160 LZ,
161 // Produced e.g. by `csc /debug`. The encoded data is its own mini-stream
162 // with the following layout (in little endian):
163 // GUID LanguageTypeGuid;
164 // GUID LanguageVendorGuid;
165 // GUID DocumentTypeGuid;
166 // GUID HashFunctionGuid;
167 // uint32_t HashDataSize;
168 // uint32_t CompressedDataSize;
169 // Followed by HashDataSize bytes containing a hash checksum,
170 // followed by CompressedDataSize bytes containing source contents.
171 //
172 // CompressedDataSize can be 0, in this case only the hash data is present.
173 // (CompressedDataSize is != 0 e.g. if `/embed` is passed to csc.exe.)
174 // The compressed data format is:
175 // uint32_t UncompressedDataSize;
176 // If UncompressedDataSize is 0, the data is stored uncompressed and
177 // CompressedDataSize stores the uncompressed size.
178 // If UncompressedDataSize is != 0, then the data is in raw deflate
179 // encoding as described in rfc1951.
180 //
181 // A GUID is 16 bytes, stored in the usual
182 // uint32_t
183 // uint16_t
184 // uint16_t
185 // uint8_t[24]
186 // layout.
187 //
188 // Well-known GUIDs for LanguageTypeGuid are:
189 // 63a08714-fc37-11d2-904c-00c04fa302a1 C
190 // 3a12d0b7-c26c-11d0-b442-00a0244a1dd2 C++
191 // 3f5162f8-07c6-11d3-9053-00c04fa302a1 C#
192 // af046cd1-d0e1-11d2-977c-00a0c9b4d50c Cobol
193 // ab4f38c9-b6e6-43ba-be3b-58080b2ccce3 F#
194 // 3a12d0b4-c26c-11d0-b442-00a0244a1dd2 Java
195 // 3a12d0b6-c26c-11d0-b442-00a0244a1dd2 JScript
196 // af046cd2-d0e1-11d2-977c-00a0c9b4d50c Pascal
197 // 3a12d0b8-c26c-11d0-b442-00a0244a1dd2 Visual Basic
198 //
199 // Well-known GUIDs for LanguageVendorGuid are:
200 // 994b45c4-e6e9-11d2-903f-00c04fa302a1 Microsoft
201 //
202 // Well-known GUIDs for DocumentTypeGuid are:
203 // 5a869d0b-6611-11d3-bd2a-0000f80849bd Text
204 //
205 // Well-known GUIDs for HashFunctionGuid are:
206 // 406ea660-64cf-4c82-b6f0-42d48172a799 MD5 (HashDataSize is 16)
207 // ff1816ec-aa5e-4d10-87f7-6f4963833460 SHA1 (HashDataSize is 20)
208 // 8829d00f-11b8-4213-878b-770e8597ac16 SHA256 (HashDataSize is 32)
209 DotNet = 101,
210 };
153211 };
154212
155213 /// These values correspond to the CV_call_e enumeration, and are documented
4040 &IDiaInjectedSource::get_virtualFilename);
4141 }
4242
43 PDB_SourceCompression DIAInjectedSource::getCompression() const {
43 uint32_t DIAInjectedSource::getCompression() const {
4444 DWORD Compression = 0;
4545 if (S_OK != SourceFile->get_sourceCompression(&Compression))
4646 return PDB_SourceCompression::None;
47 return static_cast<PDB_SourceCompression>(Compression);
47 return static_cast<uint32_t>(Compression);
4848 }
4949
5050 std::string DIAInjectedSource::getCode() const {
1616
1717 namespace {
1818
19 Expected readStreamData(BinaryStream &Stream) {
20 uint32_t Offset = 0, DataLength = Stream.getLength();
19 Expected readStreamData(BinaryStream &Stream, uint32_t Limit) {
20 uint32_t Offset = 0, DataLength = std::min(Limit, Stream.getLength());
2121 std::string Result;
2222 Result.reserve(DataLength);
2323 while (Offset < DataLength) {
2424 ArrayRef Data;
2525 if (auto E = Stream.readLongestContiguousChunk(Offset, Data))
2626 return std::move(E);
27 Data = Data.take_front(DataLength - Offset);
2728 Offset += Data.size();
2829 Result += toStringRef(Data);
2930 }
6162 return *VName;
6263 }
6364
64 PDB_SourceCompression getCompression() const override {
65 return static_cast(Entry.Compression);
66 }
65 uint32_t getCompression() const override { return Entry.Compression; }
6766
6867 std::string getCode() const override {
6968 // Get name of stream storing the data.
8079 return "(failed to open data stream)";
8180 }
8281
83 auto Data = readStreamData(**ExpectedFileStream);
82 auto Data = readStreamData(**ExpectedFileStream, Entry.FileSize);
8483 if (!Data) {
8584 consumeError(Data.takeError());
8685 return "(failed to read data)";
319319 return OS;
320320 }
321321
322 raw_ostream &llvm::pdb::operator<<(raw_ostream &OS,
323 const PDB_SourceCompression &Compression) {
322 raw_ostream &llvm::pdb::dumpPDBSourceCompression(raw_ostream &OS,
323 uint32_t Compression) {
324324 switch (Compression) {
325325 CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, None, OS)
326326 CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, Huffman, OS)
327327 CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, LZ, OS)
328328 CASE_OUTPUT_ENUM_CLASS_STR(PDB_SourceCompression, RunLengthEncoded, "RLE",
329329 OS)
330 CASE_OUTPUT_ENUM_CLASS_NAME(PDB_SourceCompression, DotNet, OS)
331 default:
332 OS << "Unknown (" << Compression << ")";
330333 }
331334 return OS;
332335 }
2727
2828 ; NEGATIVE: ---INJECTED SOURCES---
2929 ; NEGATIVE-NEXT: There are no injected sources.
30
31 ; PDB created by running `csc /debug Hello.cs`
32 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
33 ; RUN: %p/Inputs/dotnet_hashonly.pdb | FileCheck --check-prefix=HASH %s
34
35 ; HASH: ---INJECTED SOURCES---
36 ; HASH: C:\src\llvm-mono\Hello.cs (92 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=269413292, compression=DotNet
37 ; HASH-NEXT: Compressed data (
38 ; HASH-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
39 ; HASH-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
40 ; HASH-NEXT: 0040: 14000000 00000000 17299CBE 74FDDF66 FFCD5E08 CE34A775 D464C611 |.........)..t..f..^..4.u.d..|
41 ; HASH-NEXT: )
42
43 ; PDB created by running `csc /debug Hello.cs` with Hello.cs smaller than 200 bytes.
44 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
45 ; RUN: %p/Inputs/dotnet_contents_uncompressed.pdb | FileCheck --check-prefix=UNCOMP %s
46
47 ; UNCOMP: ---INJECTED SOURCES---
48 ; UNCOMP: C:\src\llvm-mono\Hello.cs (232 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=323787205, compression=DotNet
49 ; UNCOMP-NEXT: Compressed data (
50 ; UNCOMP-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
51 ; UNCOMP-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
52 ; UNCOMP-NEXT: 0040: 14000000 8C000000 17299CBE 74FDDF66 FFCD5E08 CE34A775 D464C611 00000000 |.........)..t..f..^..4.u.d......|
53 ; UNCOMP-NEXT: 0060: 6E616D65 73706163 65204865 6C6C6F57 6F726C64 207B0D0A 636C6173 73204865 |namespace HelloWorld {..class He|
54 ; UNCOMP-NEXT: 0080: 6C6C6F20 7B0D0A20 20737461 74696320 766F6964 204D6169 6E282920 7B205379 |llo {.. static void Main() { Sy|
55 ; UNCOMP-NEXT: 00A0: 7374656D 2E436F6E 736F6C65 2E577269 74654C69 6E652822 48656C6C 6F206173 |stem.Console.WriteLine("Hello as|
56 ; UNCOMP-NEXT: 00C0: 64666A6B 6C777763 6F697762 72796669 75667566 20576F72 6C642122 293B207D |dfjklwwcoiwbryfiufuf World!"); }|
57 ; UNCOMP-NEXT: 00E0: 0D0A7D0D 0A7D0D0A |..}..}..|
58 ; UNCOMP-NEXT: )
59
60 ; PDB created by running `csc /debug Hello.cs` with Hello.cs larger than 200 bytes.
61 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
62 ; RUN: %p/Inputs/dotnet_contents_compressed.pdb | FileCheck --check-prefix=COMP %s
63
64 ; COMP: ---INJECTED SOURCES---
65 ; COMP: C:\src\llvm-mono\Hello.cs (218 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=616104201, compression=DotNet
66 ; COMP-NEXT: Compressed data (
67 ; COMP-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
68 ; COMP-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
69 ; COMP-NEXT: 0040: 14000000 7E000000 52CD36A0 6A9824CD A3034543 7FA9765E D572DA21 FB000000 |....~...R.6.j.$...EC..v^.r.!....|
70 ; COMP-NEXT: 0060: CB4BCC4D 2D2E484C 4E55F048 CDC9C90F CF2FCA49 51A8E6E5 4ACE492C 2E868881 |.K.M-.HLNU.H...../.IQ...J.I,....|
71 ; COMP-NEXT: 0080: B80A0AC5 25892599 C90A65F9 99290ABE 8999791A 9A0AD50A C195C525 A9B97ACE |....%.%...e..)....y........%..z.|
72 ; COMP-NEXT: 00A0: F979C5F9 39A97AE1 459925A9 3E9979A9 1A4A109D 89C52969 59D939E5 E5C9F999 |.y..9.z.E.%.>.y..J....)iY.9.....|
73 ; COMP-NEXT: 00C0: E5494595 6999A569 A5690321 0CF698A2 92A6B542 2D2F1704 0100 |.IE.i..i.i.!.......B-/....|
74 ; COMP-NEXT: )
2626
2727 ; NEGATIVE: ---INJECTED SOURCES---
2828 ; NEGATIVE-NEXT: There are no injected sources.
29
30 ; PDB created by running `csc /debug Hello.cs`
31 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
32 ; RUN: %p/Inputs/dotnet_hashonly.pdb | FileCheck --check-prefix=HASH %s
33
34 ; HASH: ---INJECTED SOURCES---
35 ; HASH: C:\src\llvm-mono\Hello.cs (92 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=269413292, compression=DotNet
36 ; HASH-NEXT: Compressed data (
37 ; HASH-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
38 ; HASH-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
39 ; HASH-NEXT: 0040: 14000000 00000000 17299CBE 74FDDF66 FFCD5E08 CE34A775 D464C611 |.........)..t..f..^..4.u.d..|
40 ; HASH-NEXT: )
41
42 ; PDB created by running `csc /debug Hello.cs` with Hello.cs smaller than 200 bytes.
43 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
44 ; RUN: %p/Inputs/dotnet_contents_uncompressed.pdb | FileCheck --check-prefix=UNCOMP %s
45
46 ; UNCOMP: ---INJECTED SOURCES---
47 ; UNCOMP: C:\src\llvm-mono\Hello.cs (232 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=323787205, compression=DotNet
48 ; UNCOMP-NEXT: Compressed data (
49 ; UNCOMP-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
50 ; UNCOMP-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
51 ; UNCOMP-NEXT: 0040: 14000000 8C000000 17299CBE 74FDDF66 FFCD5E08 CE34A775 D464C611 00000000 |.........)..t..f..^..4.u.d......|
52 ; UNCOMP-NEXT: 0060: 6E616D65 73706163 65204865 6C6C6F57 6F726C64 207B0D0A 636C6173 73204865 |namespace HelloWorld {..class He|
53 ; UNCOMP-NEXT: 0080: 6C6C6F20 7B0D0A20 20737461 74696320 766F6964 204D6169 6E282920 7B205379 |llo {.. static void Main() { Sy|
54 ; UNCOMP-NEXT: 00A0: 7374656D 2E436F6E 736F6C65 2E577269 74654C69 6E652822 48656C6C 6F206173 |stem.Console.WriteLine("Hello as|
55 ; UNCOMP-NEXT: 00C0: 64666A6B 6C777763 6F697762 72796669 75667566 20576F72 6C642122 293B207D |dfjklwwcoiwbryfiufuf World!"); }|
56 ; UNCOMP-NEXT: 00E0: 0D0A7D0D 0A7D0D0A |..}..}..|
57 ; UNCOMP-NEXT: )
58
59 ; PDB created by running `csc /debug Hello.cs` with Hello.cs larger than 200 bytes.
60 ; RUN: llvm-pdbutil pretty -native -injected-sources -injected-source-content \
61 ; RUN: %p/Inputs/dotnet_contents_compressed.pdb | FileCheck --check-prefix=COMP %s
62
63 ; COMP: ---INJECTED SOURCES---
64 ; COMP: C:\src\llvm-mono\Hello.cs (218 bytes): obj=, vname=c:\src\llvm-mono\hello.cs, crc=616104201, compression=DotNet
65 ; COMP-NEXT: Compressed data (
66 ; COMP-NEXT: 0000: F862513F C607D311 905300C0 4FA302A1 C4454B99 E9E6D211 903F00C0 4FA302A1 |.bQ?.....S..O....EK......?..O...|
67 ; COMP-NEXT: 0020: 0B9D865A 1166D311 BD2A0000 F80849BD EC1618FF 5EAA104D 87F76F49 63833460 |...Z.f...*....I.....^..M..oIc.4`|
68 ; COMP-NEXT: 0040: 14000000 7E000000 52CD36A0 6A9824CD A3034543 7FA9765E D572DA21 FB000000 |....~...R.6.j.$...EC..v^.r.!....|
69 ; COMP-NEXT: 0060: CB4BCC4D 2D2E484C 4E55F048 CDC9C90F CF2FCA49 51A8E6E5 4ACE492C 2E868881 |.K.M-.HLNU.H...../.IQ...J.I,....|
70 ; COMP-NEXT: 0080: B80A0AC5 25892599 C90A65F9 99290ABE 8999791A 9A0AD50A C195C525 A9B97ACE |....%.%...e..)....y........%..z.|
71 ; COMP-NEXT: 00A0: F979C5F9 39A97AE1 459925A9 3E9979A9 1A4A109D 89C52969 59D939E5 E5C9F999 |.y..9.z.E.%.>.y..J....)iY.9.....|
72 ; COMP-NEXT: 00C0: E5494595 6999A569 A5690321 0CF698A2 92A6B542 2D2F1704 0100 |.IE.i..i.i.!.......B-/....|
73 ; COMP-NEXT: )
131131
132132 template
133133 inline raw_ostream &operator<<(LinePrinter &Printer, const T &Item) {
134 Printer.getStream() << Item;
135 return Printer.getStream();
134 return Printer.getStream() << Item;
136135 }
137136
138137 enum class PDB_ColorItem {
946946 std::string VFName = stringOr(IS->getVirtualFileName(), "");
947947 uint32_t CRC = IS->getCrc32();
948948
949 std::string CompressionStr;
950 llvm::raw_string_ostream Stream(CompressionStr);
951 Stream << IS->getCompression();
952949 WithColor(Printer, PDB_ColorItem::Path).get() << File;
953950 Printer << " (";
954951 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Size;
967964 Printer << ", ";
968965 WithColor(Printer, PDB_ColorItem::Keyword).get() << "compression";
969966 Printer << "=";
970 WithColor(Printer, PDB_ColorItem::LiteralValue).get() << Stream.str();
967 dumpPDBSourceCompression(
968 WithColor(Printer, PDB_ColorItem::LiteralValue).get(),
969 IS->getCompression());
971970
972971 if (!opts::pretty::ShowInjectedSourceContent)
973972 continue;
976975 int Indent = Printer.getIndentLevel();
977976 Printer.Unindent(Indent);
978977
979 Printer.printLine(IS->getCode());
978 if (IS->getCompression() == PDB_SourceCompression::None)
979 Printer.printLine(IS->getCode());
980 else
981 Printer.formatBinary("Compressed data",
982 arrayRefFromStringRef(IS->getCode()),
983 /*StartOffset=*/0);
980984
981985 // Re-indent back to the original level.
982986 Printer.Indent(Indent);