llvm.org GIT mirror llvm / 5d2c917
[llvm-pdbutil] Dump raw bytes of type and id records. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@306167 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 2 years ago
10 changed file(s) with 146 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
6060 void reset(ArrayRef Data, uint32_t RecordCountHint);
6161 void reset(StringRef Data, uint32_t RecordCountHint);
6262
63 uint32_t getOffsetOfType(TypeIndex Index);
64
6365 CVType getType(TypeIndex Index) override;
6466 StringRef getTypeName(TypeIndex Index) override;
6567 bool contains(TypeIndex Index) override;
1515 #include "llvm/DebugInfo/PDB/Native/RawTypes.h"
1616 #include "llvm/DebugInfo/PDB/PDBTypes.h"
1717 #include "llvm/Support/BinaryStreamArray.h"
18 #include "llvm/Support/BinaryStreamRef.h"
1819 #include "llvm/Support/raw_ostream.h"
1920
2021 #include "llvm/Support/Error.h"
5657
5758 codeview::LazyRandomTypeCollection &typeCollection() { return *Types; }
5859
60 BinarySubstreamRef getTypeRecordsSubstream() const;
61
5962 Error commit();
6063
6164 private:
6366 std::unique_ptr Stream;
6467
6568 std::unique_ptr Types;
69
70 BinarySubstreamRef TypeRecordsSubstream;
6671
6772 codeview::CVTypeArray TypeRecords;
6873
169169 uint32_t Offset; // Offset in the parent stream
170170 BinaryStreamRef StreamData; // Stream Data
171171
172 BinarySubstreamRef slice(uint32_t Off, uint32_t Size) const {
173 BinaryStreamRef SubSub = StreamData.slice(Off, Size);
174 return {Off + Offset, SubSub};
175 }
172176 uint32_t size() const { return StreamData.getLength(); }
173177 bool empty() const { return size() == 0; }
174178 };
6464 void LazyRandomTypeCollection::reset(ArrayRef Data,
6565 uint32_t RecordCountHint) {
6666 reset(toStringRef(Data), RecordCountHint);
67 }
68
69 uint32_t LazyRandomTypeCollection::getOffsetOfType(TypeIndex Index) {
70 error(ensureTypeExists(Index));
71 assert(contains(Index));
72
73 return Records[Index.toArrayIndex()].Offset;
6774 }
6875
6976 CVType LazyRandomTypeCollection::getType(TypeIndex Index) {
6565 "TPI Stream Invalid number of hash buckets.");
6666
6767 // The actual type records themselves come from this stream
68 if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
68 if (auto EC =
69 Reader.readSubstream(TypeRecordsSubstream, Header->TypeRecordBytes))
70 return EC;
71
72 BinaryStreamReader RecordReader(TypeRecordsSubstream.StreamData);
73 if (auto EC =
74 RecordReader.readArray(TypeRecords, TypeRecordsSubstream.size()))
6975 return EC;
7076
7177 // Hash indices, hash values, etc come from the hash stream.
134140 uint32_t TpiStream::getNumHashBuckets() const { return Header->NumHashBuckets; }
135141 uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }
136142
143 BinarySubstreamRef TpiStream::getTypeRecordsSubstream() const {
144 return TypeRecordsSubstream;
145 }
146
137147 FixedStreamArray TpiStream::getHashValues() const {
138148 return HashValues;
139149 }
0 ; RUN: llvm-pdbutil bytes -type=0x1002 %p/Inputs/empty.pdb | FileCheck --check-prefix=TYPE %s
1 ; RUN: llvm-pdbutil bytes -id=0x1007 %p/Inputs/empty.pdb | FileCheck --check-prefix=ID %s
2 ; RUN: llvm-pdbutil bytes -type=0x2000 %p/Inputs/empty.pdb | FileCheck --check-prefix=INVALID-TYPE %s
3 ; RUN: llvm-pdbutil bytes -id=0x2000 %p/Inputs/empty.pdb | FileCheck --check-prefix=INVALID-ID %s
4
5 TYPE: Type (TPI) Records
6 TYPE-NEXT: ============================================================
7 TYPE-NEXT: Type 0x1002 (
8 TYPE-NEXT: 12050: 4A000312 02150300 01006170 6172746D 656E7400 02150300 02007369 6E676C65 |J.........apartment.......single|
9 TYPE-NEXT: 12070: 00F3F2F1 02150300 03006672 656500F1 02150300 04006E65 75747261 6C00F2F1 |..........free........neutral...|
10 TYPE-NEXT: 12090: 02150300 0500626F 746800F1 |......both..|
11 TYPE-NEXT: )
12
13 ID: Index (IPI) Records
14 ID-NEXT: ============================================================
15 ID-NEXT: Type 0x1007 (
16 ID-NEXT: 140C4: 2E000516 00000000 643A5C73 72635C6C 6C766D5C 74657374 5C446562 7567496E |........d:\src\llvm\test\DebugIn|
17 ID-NEXT: 140E4: 666F5C50 44425C49 6E707574 7300F2F1 |fo\PDB\Inputs...|
18 ID-NEXT: )
19
20 INVALID-TYPE: Type (TPI) Records
21 INVALID-TYPE-NEXT: ============================================================
22 INVALID-TYPE-NEXT: Error: TypeIndex 0x2000 does not exist
23
24 INVALID-ID: Index (IPI) Records
25 INVALID-ID-NEXT: ============================================================
26 INVALID-ID-NEXT: Error: TypeIndex 0x2000 does not exist
1111 #include "StreamUtil.h"
1212 #include "llvm-pdbutil.h"
1313
14 #include "llvm/DebugInfo/CodeView/Formatters.h"
15 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
1416 #include "llvm/DebugInfo/MSF/MappedBlockStream.h"
1517 #include "llvm/DebugInfo/PDB/Native/DbiStream.h"
1618 #include "llvm/DebugInfo/PDB/Native/InfoStream.h"
1719 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
1820 #include "llvm/DebugInfo/PDB/Native/RawError.h"
21 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
1922 #include "llvm/Support/BinaryStreamReader.h"
2023 #include "llvm/Support/FormatAdapters.h"
2124 #include "llvm/Support/FormatVariadic.h"
2225
2326 using namespace llvm;
27 using namespace llvm::codeview;
2428 using namespace llvm::msf;
2529 using namespace llvm::pdb;
2630
153157 P.NewLine();
154158 }
155159
160 if (!opts::bytes::TypeIndex.empty()) {
161 dumpTypeIndex(StreamTPI, opts::bytes::TypeIndex);
162 P.NewLine();
163 }
164
165 if (!opts::bytes::IdIndex.empty()) {
166 dumpTypeIndex(StreamIPI, opts::bytes::IdIndex);
167 P.NewLine();
168 }
169
156170 return Error::success();
157171 }
158172
252266 P.formatMsfStreamData("Edit and Continue Data", File, Layout, NS);
253267 }
254268
269 void BytesOutputStyle::dumpTypeIndex(uint32_t StreamIdx,
270 ArrayRef Indices) {
271 assert(StreamIdx == StreamTPI || StreamIdx == StreamIPI);
272 assert(!Indices.empty());
273
274 bool IsTpi = (StreamIdx == StreamTPI);
275
276 StringRef Label = IsTpi ? "Type (TPI) Records" : "Index (IPI) Records";
277 printHeader(P, Label);
278 auto &Stream = Err(IsTpi ? File.getPDBTpiStream() : File.getPDBIpiStream());
279
280 AutoIndent Indent(P);
281
282 auto Substream = Stream.getTypeRecordsSubstream();
283 auto &Types = Err(initializeTypes(StreamIdx));
284 auto Layout = File.getStreamLayout(StreamIdx);
285 for (const auto &Id : Indices) {
286 TypeIndex TI(Id);
287 if (TI.toArrayIndex() >= Types.capacity()) {
288 P.formatLine("Error: TypeIndex {0} does not exist", TI);
289 continue;
290 }
291
292 auto Type = Types.getType(TI);
293 uint32_t Offset = Types.getOffsetOfType(TI);
294 auto OneType = Substream.slice(Offset, Type.length());
295 P.formatMsfStreamData(formatv("Type {0}", TI).str(), File, Layout, OneType);
296 }
297 }
298
255299 void BytesOutputStyle::dumpByteRanges(uint32_t Min, uint32_t Max) {
256300 printHeader(P, "MSF Bytes");
257301
267311 P.formatBinary("Bytes", Data, Min);
268312 }
269313
314 Expected
315 BytesOutputStyle::initializeTypes(uint32_t StreamIdx) {
316 auto &TypeCollection = (StreamIdx == StreamTPI) ? TpiTypes : IpiTypes;
317 if (TypeCollection)
318 return *TypeCollection;
319
320 auto Tpi = (StreamIdx == StreamTPI) ? File.getPDBTpiStream()
321 : File.getPDBIpiStream();
322 if (!Tpi)
323 return Tpi.takeError();
324
325 auto &Types = Tpi->typeArray();
326 uint32_t Count = Tpi->getNumTypeRecords();
327 auto Offsets = Tpi->getTypeIndexOffsets();
328 TypeCollection =
329 llvm::make_unique(Types, Count, Offsets);
330
331 return *TypeCollection;
332 }
333
270334 void BytesOutputStyle::dumpStreamBytes() {
271335 if (StreamPurposes.empty())
272336 discoverStreamPurposes(File, StreamPurposes);
1515 #include "llvm/Support/Error.h"
1616
1717 namespace llvm {
18
19 namespace codeview {
20 class LazyRandomTypeCollection;
21 }
1822
1923 namespace pdb {
2024
3943 void dumpTypeServerMap();
4044 void dumpECData();
4145
46 void dumpTypeIndex(uint32_t StreamIdx, ArrayRef Indices);
47
48 Expected
49 initializeTypes(uint32_t StreamIdx);
50
51 std::unique_ptr TpiTypes;
52 std::unique_ptr IpiTypes;
53
4254 PDBFile &File;
4355 LinePrinter P;
4456 ExitOnError Err;
269269 cl::OptionCategory MsfBytes("MSF File Options");
270270 cl::OptionCategory DbiBytes("Dbi Stream Options");
271271 cl::OptionCategory PdbBytes("PDB Stream Options");
272 cl::OptionCategory Types("Type Options");
272273
273274 llvm::Optional DumpBlockRange;
274275 llvm::Optional DumpByteRange;
304305 cl::sub(BytesSubcommand), cl::cat(DbiBytes));
305306 cl::opt ECData("ec", cl::desc("Dump edit and continue map"),
306307 cl::sub(BytesSubcommand), cl::cat(DbiBytes));
308
309 cl::list
310 TypeIndex("type",
311 cl::desc("Dump the type record with the given type index"),
312 cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand),
313 cl::cat(TypeCategory));
314 cl::list
315 IdIndex("id", cl::desc("Dump the id record with the given type index"),
316 cl::ZeroOrMore, cl::CommaSeparated, cl::sub(BytesSubcommand),
317 cl::cat(TypeCategory));
307318
308319 cl::list InputFilenames(cl::Positional,
309320 cl::desc(""),
109109 extern llvm::cl::opt TypeServerMap;
110110 extern llvm::cl::opt ECData;
111111
112 extern llvm::cl::list TypeIndex;
113 extern llvm::cl::list IdIndex;
114
112115 } // namespace bytes
113116
114117 namespace dump {