llvm.org GIT mirror llvm / e5f15a2
pdbdump: print out TPI hashes. Differential Revision: http://reviews.llvm.org/D20945 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271736 91177308-0d34-0410-b5e6-96231b3b80d8 Rui Ueyama 4 years ago
8 changed file(s) with 92 addition(s) and 27 deletion(s). Raw diff Collapse all Expand all
220220 return FixedStreamArrayIterator(*this, 0);
221221 }
222222 FixedStreamArrayIterator end() const {
223 return FixedStreamArrayIterator(*this);
223 return FixedStreamArrayIterator(*this, size());
224224 }
225225
226226 private:
229229
230230 template class FixedStreamArrayIterator {
231231 public:
232 FixedStreamArrayIterator(const FixedStreamArray &Array)
233 : Array(Array), Index(uint32_t(-1)) {}
234 FixedStreamArrayIterator(const FixedStreamArray &Array, uint32_t ArrayIndex)
235 : Array(Array), Index(ArrayIndex) {
236 if (Array.size() <= Index)
237 Index = uint32_t(-1);
238 }
232 FixedStreamArrayIterator(const FixedStreamArray &Array, uint32_t Index)
233 : Array(Array), Index(Index) {}
239234
240235 bool operator==(const FixedStreamArrayIterator &R) {
241236 assert(&Array == &R.Array);
249244 const T &operator*() const { return Array[Index]; }
250245
251246 FixedStreamArrayIterator &operator++() {
252 if (Index == uint32_t(-1))
253 return *this;
254 if (++Index >= Array.size())
255 Index = uint32_t(-1);
247 assert(Index < Array.size());
248 ++Index;
256249 return *this;
257250 }
258251
99 #ifndef LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
1010 #define LLVM_DEBUGINFO_PDB_RAW_RAWTYPES_H
1111
12 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1213 #include "llvm/Support/Endian.h"
1314
1415 namespace llvm {
7172 support::ulittle32_t SecByteLength; // Byte count of the segment or group.
7273 };
7374
75 // Used for serialized hash table in TPI stream.
76 // In the reference, it is an array of TI and cbOff pair.
77 struct TypeIndexOffset {
78 codeview::TypeIndex Type;
79 support::ulittle32_t Offset;
80 };
81
7482 } // namespace pdb
7583 } // namespace llvm
7684
1515 #include "llvm/DebugInfo/PDB/PDBTypes.h"
1616 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
1717 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
18 #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
19 #include "llvm/Support/raw_ostream.h"
1820
1921 #include "llvm/Support/Error.h"
2022
4042 uint16_t getTypeHashStreamIndex() const;
4143 uint16_t getTypeHashStreamAuxIndex() const;
4244
45 codeview::FixedStreamArray getHashValues() const;
46 codeview::FixedStreamArray getTypeIndexOffsets() const;
47 codeview::FixedStreamArray getHashAdjustments() const;
48
4349 iterator_range types(bool *HadError) const;
4450
4551 private:
4854 HashFunctionType HashFunction;
4955
5056 codeview::CVTypeArray TypeRecords;
51 codeview::StreamRef TypeIndexOffsetBuffer;
52 codeview::StreamRef HashValuesBuffer;
53 codeview::StreamRef HashAdjBuffer;
57
58 std::unique_ptr HashStream;
59 codeview::FixedStreamArray HashValues;
60 codeview::FixedStreamArray TypeIndexOffsets;
61 codeview::FixedStreamArray HashAdjustments;
5462
5563 const HeaderInfo *Header;
5664 };
1010
1111 #include "llvm/DebugInfo/CodeView/CodeView.h"
1212 #include "llvm/DebugInfo/CodeView/StreamReader.h"
13 #include "llvm/DebugInfo/CodeView/TypeIndex.h"
1314 #include "llvm/DebugInfo/CodeView/TypeRecord.h"
1415 #include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
1516 #include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
1617 #include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
1718 #include "llvm/DebugInfo/PDB/Raw/RawError.h"
19 #include "llvm/DebugInfo/PDB/Raw/RawTypes.h"
1820
1921 #include "llvm/Support/Endian.h"
2022
98100 return EC;
99101
100102 // Hash indices, hash values, etc come from the hash stream.
101 MappedBlockStream HS(Header->HashStreamIndex, Pdb);
102 codeview::StreamReader HSR(HS);
103 HashStream.reset(new MappedBlockStream(Header->HashStreamIndex, Pdb));
104 codeview::StreamReader HSR(*HashStream);
105 uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
103106 HSR.setOffset(Header->HashValueBuffer.Off);
104 if (auto EC =
105 HSR.readStreamRef(HashValuesBuffer, Header->HashValueBuffer.Length))
107 if (auto EC = HSR.readArray(HashValues, NumHashValues))
108 return EC;
109
110 HSR.setOffset(Header->IndexOffsetBuffer.Off);
111 uint32_t NumTypeIndexOffsets =
112 Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
113 if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
106114 return EC;
107115
108116 HSR.setOffset(Header->HashAdjBuffer.Off);
109 if (auto EC = HSR.readStreamRef(HashAdjBuffer, Header->HashAdjBuffer.Length))
110 return EC;
111
112 HSR.setOffset(Header->IndexOffsetBuffer.Off);
113 if (auto EC = HSR.readStreamRef(TypeIndexOffsetBuffer,
114 Header->IndexOffsetBuffer.Length))
117 uint32_t NumHashAdjustments =
118 Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
119 if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
115120 return EC;
116121
117122 return Error::success();
138143 return Header->HashAuxStreamIndex;
139144 }
140145
146 codeview::FixedStreamArray
147 TpiStream::getHashValues() const {
148 return HashValues;
149 }
150
151 codeview::FixedStreamArray
152 TpiStream::getTypeIndexOffsets() const {
153 return TypeIndexOffsets;
154 }
155
156 codeview::FixedStreamArray
157 TpiStream::getHashAdjustments() const {
158 return HashAdjustments;
159 }
160
141161 iterator_range
142162 TpiStream::types(bool *HadError) const {
143163 return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
11 ; RUN: -raw-sym-record-bytes -raw-publics -raw-module-files -raw-stream-name=/names \
22 ; RUN: -raw-stream-summary -raw-stream-blocks -raw-ipi-records -raw-ipi-record-bytes \
33 ; RUN: -raw-section-contribs -raw-section-map -raw-section-headers -raw-line-info \
4 ; RUN: %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
4 ; RUN: -raw-tpi-hash %p/Inputs/empty.pdb | FileCheck -check-prefix=EMPTY %s
55 ; RUN: llvm-pdbdump -raw-all %p/Inputs/empty.pdb | FileCheck -check-prefix=ALL %s
66 ; RUN: llvm-pdbdump -raw-headers -raw-stream-name=/names -raw-modules -raw-module-files \
77 ; RUN: %p/Inputs/big-read.pdb | FileCheck -check-prefix=BIG %s
140140 ; EMPTY-NEXT: 0040: 0500626F 746800F1 |..both..|
141141 ; EMPTY-NEXT: )
142142 ; EMPTY-NEXT: }
143 ; EMPTY: Hash {
144 ; EMPTY-NEXT: Values: [205956, 163561, 59811, 208239, 16377, 247078, 194342, 254156, 194536, 167492, 185421, 119540, 261871, 198119, 48056, 251486, 134580, 148190, 113636, 53336, 55779, 220695, 198114, 148734, 81128, 60158, 217249, 174209, 159978, 249504, 141941, 238785, 6214, 94935, 151449, 135589, 73373, 96512, 254299, 17744, 239514, 173189, 130544, 204437, 238560, 144673, 115151, 197306, 256035, 101096, 231280, 52156, 48854, 170035, 177041, 102745, 16947, 183703, 98548, 35693, 171328, 203640, 139292, 49018, 43821, 202555, 165040, 215835, 142625, 52534, 44186, 103930, 110942, 17991, 213215]
145 ; EMPTY-NEXT: Type Index Offsets: [{4096, 0}]
146 ; EMPTY-NEXT: Hash Adjustments: []
147 ; EMPTY-NEXT: }
143148 ; EMPTY: Type Info Stream (IPI) {
144149 ; EMPTY-NEXT: IPI Version: 20040203
145150 ; EMPTY-NEXT: Record count: 15
216221 ; EMPTY-NEXT: 0000: 42100000 01000000 6C000000 0100F2F1 |B.......l.......|
217222 ; EMPTY-NEXT: )
218223 ; EMPTY-NEXT: }
224 ; EMPTY: Hash {
225 ; EMPTY-NEXT: Values: [7186, 7198, 7180, 7191, 7201, 7241, 7249, 80727, 154177, 75189, 253662, 193467, 222705, 186099, 257108]
226 ; EMPTY-NEXT: Type Index Offsets: [{4096, 0}]
227 ; EMPTY-NEXT: Hash Adjustments: []
228 ; EMPTY-NEXT: }
219229 ; EMPTY: DBI Stream {
220230 ; EMPTY-NEXT: Dbi Version: 19990903
221231 ; EMPTY-NEXT: Age: 1
263263 return Error::success();
264264 }
265265
266 static void printTypeIndexOffset(raw_ostream &OS,
267 const TypeIndexOffset &TIOff) {
268 OS << "{" << TIOff.Type.getIndex() << ", " << TIOff.Offset << "}";
269 }
270
271 static void dumpTpiHash(ScopedPrinter &P, TpiStream &Tpi) {
272 if (!opts::DumpTpiHash)
273 return;
274 DictScope DD(P, "Hash");
275 codeview::FixedStreamArray S = Tpi.getHashValues();
276 P.printList("Values", Tpi.getHashValues());
277 P.printList("Type Index Offsets", Tpi.getTypeIndexOffsets(),
278 printTypeIndexOffset);
279 P.printList("Hash Adjustments", Tpi.getHashAdjustments(),
280 printTypeIndexOffset);
281 }
282
266283 Error LLVMOutputStyle::dumpTpiStream(uint32_t StreamIdx) {
267284 assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
268285
308325 if (DumpRecordBytes)
309326 P.printBinaryBlock("Bytes", Type.Data);
310327 }
328 dumpTpiHash(P, Tpi);
311329 if (HadError)
312330 return make_error(raw_error_code::corrupt_file,
313331 "TPI stream contained corrupt record");
324342 TD.dump(Type);
325343
326344 TD.setPrinter(OldP);
345 dumpTpiHash(P, Tpi);
327346 if (HadError)
328347 return make_error(raw_error_code::corrupt_file,
329348 "TPI stream contained corrupt record");
112112 "raw-tpi-record-bytes",
113113 cl::desc("dump CodeView type record raw bytes from TPI stream"),
114114 cl::cat(NativeOptions));
115 cl::opt DumpTpiHash("raw-tpi-hash",
116 cl::desc("dump CodeView TPI hash stream"),
117 cl::cat(NativeOptions));
115118 cl::opt
116119 DumpIpiRecords("raw-ipi-records",
117120 cl::desc("dump CodeView type records from IPI stream"),
275278 return true;
276279 if (opts::DumpTpiRecords)
277280 return true;
281 if (opts::DumpTpiHash)
282 return true;
278283 if (opts::DumpIpiRecords)
279284 return true;
280285 if (opts::DumpIpiRecordBytes)
449454 opts::DumpStreamSummary = true;
450455 opts::DumpStreamBlocks = true;
451456 opts::DumpTpiRecords = true;
457 opts::DumpTpiHash = true;
452458 opts::DumpIpiRecords = true;
453459 opts::DumpSectionMap = true;
454460 opts::DumpSectionContribs = true;
2626 extern llvm::cl::opt DumpHeaders;
2727 extern llvm::cl::opt DumpStreamBlocks;
2828 extern llvm::cl::opt DumpStreamSummary;
29 extern llvm::cl::opt DumpTpiHash;
30 extern llvm::cl::opt DumpTpiRecordBytes;
2931 extern llvm::cl::opt DumpTpiRecords;
30 extern llvm::cl::opt DumpTpiRecordBytes;
3132 extern llvm::cl::opt DumpIpiRecords;
3233 extern llvm::cl::opt DumpIpiRecordBytes;
3334 extern llvm::cl::opt DumpStreamDataIdx;