blob: 133f9fac19f96078a7d0fc82d40f684b89558a01 [file] [log] [blame]
Zachary Turneraaad5742016-05-23 23:41:13 +00001//===-- SymbolDumper.cpp - CodeView symbol info dumper ----------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "llvm/DebugInfo/CodeView/SymbolDumper.h"
11#include "llvm/ADT/DenseMap.h"
12#include "llvm/ADT/SmallString.h"
13#include "llvm/DebugInfo/CodeView/CVSymbolVisitor.h"
Zachary Turner93839cb2016-06-02 05:07:49 +000014#include "llvm/DebugInfo/CodeView/EnumTables.h"
Zachary Turneraaad5742016-05-23 23:41:13 +000015#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
16#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
17#include "llvm/DebugInfo/CodeView/TypeDumper.h"
18#include "llvm/DebugInfo/CodeView/TypeIndex.h"
19#include "llvm/Support/ScopedPrinter.h"
20
21#include <system_error>
22
23using namespace llvm;
24using namespace llvm::codeview;
25
Zachary Turneraaad5742016-05-23 23:41:13 +000026namespace {
Zachary Turneraaad5742016-05-23 23:41:13 +000027/// Use this private dumper implementation to keep implementation details about
28/// the visitor out of SymbolDumper.h.
29class CVSymbolDumperImpl : public CVSymbolVisitor<CVSymbolDumperImpl> {
30public:
Zachary Turner3e78e2d2016-05-24 00:06:04 +000031 CVSymbolDumperImpl(CVTypeDumper &CVTD, SymbolDumpDelegate *ObjDelegate,
32 ScopedPrinter &W, bool PrintRecordBytes)
33 : CVSymbolVisitor(ObjDelegate), CVTD(CVTD), ObjDelegate(ObjDelegate),
34 W(W), PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
Zachary Turneraaad5742016-05-23 23:41:13 +000035
36/// CVSymbolVisitor overrides.
37#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
38 void visit##Name(SymbolKind Kind, Name &Record);
39#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
40#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
41
42 void visitSymbolBegin(SymbolKind Kind, ArrayRef<uint8_t> Data);
43 void visitSymbolEnd(SymbolKind Kind, ArrayRef<uint8_t> OriginalSymData);
44 void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data);
45
46private:
47 void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
48 uint32_t RelocationOffset);
49 void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
50
Zachary Turneraaad5742016-05-23 23:41:13 +000051 CVTypeDumper &CVTD;
52 SymbolDumpDelegate *ObjDelegate;
53 ScopedPrinter &W;
54
55 bool PrintRecordBytes;
56 bool InFunctionScope;
57};
58}
59
60void CVSymbolDumperImpl::printLocalVariableAddrRange(
61 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
62 DictScope S(W, "LocalVariableAddrRange");
63 if (ObjDelegate)
64 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
65 Range.OffsetStart);
66 W.printHex("ISectStart", Range.ISectStart);
67 W.printHex("Range", Range.Range);
68}
69
70void CVSymbolDumperImpl::printLocalVariableAddrGap(
71 ArrayRef<LocalVariableAddrGap> Gaps) {
72 for (auto &Gap : Gaps) {
73 ListScope S(W, "LocalVariableAddrGap");
74 W.printHex("GapStartOffset", Gap.GapStartOffset);
75 W.printHex("Range", Gap.Range);
76 }
77}
78
79void CVSymbolDumperImpl::visitSymbolBegin(SymbolKind Kind,
80 ArrayRef<uint8_t> Data) {}
81
82void CVSymbolDumperImpl::visitSymbolEnd(SymbolKind Kind,
83 ArrayRef<uint8_t> OriginalSymData) {
84 if (PrintRecordBytes && ObjDelegate)
85 ObjDelegate->printBinaryBlockWithRelocs("SymData", OriginalSymData);
86}
87
88void CVSymbolDumperImpl::visitBlockSym(SymbolKind Kind, BlockSym &Block) {
89 DictScope S(W, "BlockStart");
90
91 StringRef LinkageName;
92 W.printHex("PtrParent", Block.Header.PtrParent);
93 W.printHex("PtrEnd", Block.Header.PtrEnd);
94 W.printHex("CodeSize", Block.Header.CodeSize);
95 if (ObjDelegate) {
96 ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
97 Block.Header.CodeOffset, &LinkageName);
98 }
99 W.printHex("Segment", Block.Header.Segment);
100 W.printString("BlockName", Block.Name);
101 W.printString("LinkageName", LinkageName);
102}
103
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000104void CVSymbolDumperImpl::visitThunk32Sym(SymbolKind Kind, Thunk32Sym &Thunk) {
105 DictScope S(W, "Thunk32");
106 W.printNumber("Parent", Thunk.Header.Parent);
107 W.printNumber("End", Thunk.Header.End);
108 W.printNumber("Next", Thunk.Header.Next);
109 W.printNumber("Off", Thunk.Header.Off);
110 W.printNumber("Seg", Thunk.Header.Seg);
111 W.printNumber("Len", Thunk.Header.Len);
Zachary Turner93839cb2016-06-02 05:07:49 +0000112 W.printEnum("Ordinal", Thunk.Header.Ord, getThunkOrdinalNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000113}
114
115void CVSymbolDumperImpl::visitTrampolineSym(SymbolKind Kind,
116 TrampolineSym &Tramp) {
117 DictScope S(W, "Trampoline");
Zachary Turner93839cb2016-06-02 05:07:49 +0000118 W.printEnum("Type", Tramp.Header.Type, getTrampolineNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000119 W.printNumber("Size", Tramp.Header.Size);
120 W.printNumber("ThunkOff", Tramp.Header.ThunkOff);
121 W.printNumber("TargetOff", Tramp.Header.TargetOff);
122 W.printNumber("ThunkSection", Tramp.Header.ThunkSection);
123 W.printNumber("TargetSection", Tramp.Header.TargetSection);
124}
125
126void CVSymbolDumperImpl::visitSectionSym(SymbolKind Kind, SectionSym &Section) {
127 DictScope S(W, "Section");
128 W.printNumber("SectionNumber", Section.Header.SectionNumber);
129 W.printNumber("Alignment", Section.Header.Alignment);
130 W.printNumber("Reserved", Section.Header.Reserved);
131 W.printNumber("Rva", Section.Header.Rva);
132 W.printNumber("Length", Section.Header.Length);
Zachary Turner93839cb2016-06-02 05:07:49 +0000133 W.printFlags("Characteristics", Section.Header.Characteristics,
134 getImageSectionCharacteristicNames(),
135 COFF::SectionCharacteristics(0x00F00000));
136
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000137 W.printString("Name", Section.Name);
138}
139
140void CVSymbolDumperImpl::visitCoffGroupSym(SymbolKind Kind,
141 CoffGroupSym &CoffGroup) {
142 DictScope S(W, "COFF Group");
143 W.printNumber("Size", CoffGroup.Header.Size);
Zachary Turner93839cb2016-06-02 05:07:49 +0000144 W.printFlags("Characteristics", CoffGroup.Header.Characteristics,
145 getImageSectionCharacteristicNames(),
146 COFF::SectionCharacteristics(0x00F00000));
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000147 W.printNumber("Offset", CoffGroup.Header.Offset);
148 W.printNumber("Segment", CoffGroup.Header.Segment);
149 W.printString("Name", CoffGroup.Name);
150}
151
Zachary Turneraaad5742016-05-23 23:41:13 +0000152void CVSymbolDumperImpl::visitBPRelativeSym(SymbolKind Kind,
153 BPRelativeSym &BPRel) {
154 DictScope S(W, "BPRelativeSym");
155
156 W.printNumber("Offset", BPRel.Header.Offset);
157 CVTD.printTypeIndex("Type", BPRel.Header.Type);
158 W.printString("VarName", BPRel.Name);
159}
160
161void CVSymbolDumperImpl::visitBuildInfoSym(SymbolKind Kind,
162 BuildInfoSym &BuildInfo) {
163 DictScope S(W, "BuildInfo");
164
165 W.printNumber("BuildId", BuildInfo.Header.BuildId);
166}
167
168void CVSymbolDumperImpl::visitCallSiteInfoSym(SymbolKind Kind,
169 CallSiteInfoSym &CallSiteInfo) {
170 DictScope S(W, "CallSiteInfo");
171
172 StringRef LinkageName;
173 if (ObjDelegate) {
174 ObjDelegate->printRelocatedField(
175 "CodeOffset", CallSiteInfo.getRelocationOffset(),
176 CallSiteInfo.Header.CodeOffset, &LinkageName);
177 }
178 W.printHex("Segment", CallSiteInfo.Header.Segment);
179 W.printHex("Reserved", CallSiteInfo.Header.Reserved);
180 CVTD.printTypeIndex("Type", CallSiteInfo.Header.Type);
181 if (!LinkageName.empty())
182 W.printString("LinkageName", LinkageName);
183}
184
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000185void CVSymbolDumperImpl::visitEnvBlockSym(SymbolKind Kind,
186 EnvBlockSym &EnvBlock) {
187 DictScope S(W, "EnvBlock");
188
189 W.printNumber("Reserved", EnvBlock.Header.Reserved);
190 ListScope L(W, "Entries");
191 for (auto Entry : EnvBlock.Fields) {
192 W.printString(Entry);
193 }
194}
195
196void CVSymbolDumperImpl::visitFileStaticSym(SymbolKind Kind,
197 FileStaticSym &FileStatic) {
198 DictScope S(W, "FileStatic");
199 W.printNumber("Index", FileStatic.Header.Index);
200 W.printNumber("ModFilenameOffset", FileStatic.Header.ModFilenameOffset);
Zachary Turner93839cb2016-06-02 05:07:49 +0000201 W.printFlags("Flags", uint16_t(FileStatic.Header.Flags), getLocalFlagNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000202 W.printString("Name", FileStatic.Name);
203}
204
Zachary Turner9f054d42016-05-25 00:12:40 +0000205void CVSymbolDumperImpl::visitExportSym(SymbolKind Kind, ExportSym &Export) {
206 DictScope S(W, "Export");
207 W.printNumber("Ordinal", Export.Header.Ordinal);
Zachary Turner93839cb2016-06-02 05:07:49 +0000208 W.printFlags("Flags", Export.Header.Flags, getExportSymFlagNames());
Zachary Turner9f054d42016-05-25 00:12:40 +0000209 W.printString("Name", Export.Name);
210}
211
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000212void CVSymbolDumperImpl::visitCompile2Sym(SymbolKind Kind,
213 Compile2Sym &Compile2) {
214 DictScope S(W, "CompilerFlags2");
215
216 W.printEnum("Language", Compile2.Header.getLanguage(),
Zachary Turner93839cb2016-06-02 05:07:49 +0000217 getSourceLanguageNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000218 W.printFlags("Flags", Compile2.Header.flags & ~0xff,
Zachary Turner93839cb2016-06-02 05:07:49 +0000219 getCompileSym2FlagNames());
220 W.printEnum("Machine", unsigned(Compile2.Header.Machine), getCPUTypeNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000221 std::string FrontendVersion;
222 {
223 raw_string_ostream Out(FrontendVersion);
224 Out << Compile2.Header.VersionFrontendMajor << '.'
225 << Compile2.Header.VersionFrontendMinor << '.'
226 << Compile2.Header.VersionFrontendBuild;
227 }
228 std::string BackendVersion;
229 {
230 raw_string_ostream Out(BackendVersion);
231 Out << Compile2.Header.VersionBackendMajor << '.'
232 << Compile2.Header.VersionBackendMinor << '.'
233 << Compile2.Header.VersionBackendBuild;
234 }
235 W.printString("FrontendVersion", FrontendVersion);
236 W.printString("BackendVersion", BackendVersion);
237 W.printString("VersionName", Compile2.Version);
238}
239
Zachary Turneraaad5742016-05-23 23:41:13 +0000240void CVSymbolDumperImpl::visitCompile3Sym(SymbolKind Kind,
241 Compile3Sym &Compile3) {
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000242 DictScope S(W, "CompilerFlags3");
Zachary Turneraaad5742016-05-23 23:41:13 +0000243
244 W.printEnum("Language", Compile3.Header.getLanguage(),
Zachary Turner93839cb2016-06-02 05:07:49 +0000245 getSourceLanguageNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000246 W.printFlags("Flags", Compile3.Header.flags & ~0xff,
Zachary Turner93839cb2016-06-02 05:07:49 +0000247 getCompileSym3FlagNames());
248 W.printEnum("Machine", unsigned(Compile3.Header.Machine), getCPUTypeNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000249 std::string FrontendVersion;
250 {
251 raw_string_ostream Out(FrontendVersion);
252 Out << Compile3.Header.VersionFrontendMajor << '.'
253 << Compile3.Header.VersionFrontendMinor << '.'
254 << Compile3.Header.VersionFrontendBuild << '.'
255 << Compile3.Header.VersionFrontendQFE;
256 }
257 std::string BackendVersion;
258 {
259 raw_string_ostream Out(BackendVersion);
260 Out << Compile3.Header.VersionBackendMajor << '.'
261 << Compile3.Header.VersionBackendMinor << '.'
262 << Compile3.Header.VersionBackendBuild << '.'
263 << Compile3.Header.VersionBackendQFE;
264 }
265 W.printString("FrontendVersion", FrontendVersion);
266 W.printString("BackendVersion", BackendVersion);
267 W.printString("VersionName", Compile3.Version);
268}
269
270void CVSymbolDumperImpl::visitConstantSym(SymbolKind Kind,
271 ConstantSym &Constant) {
272 DictScope S(W, "Constant");
273
274 CVTD.printTypeIndex("Type", Constant.Header.Type);
275 W.printNumber("Value", Constant.Value);
276 W.printString("Name", Constant.Name);
277}
278
279void CVSymbolDumperImpl::visitDataSym(SymbolKind Kind, DataSym &Data) {
280 DictScope S(W, "DataSym");
281
282 StringRef LinkageName;
283 if (ObjDelegate) {
284 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
285 Data.Header.DataOffset, &LinkageName);
286 }
287 CVTD.printTypeIndex("Type", Data.Header.Type);
288 W.printString("DisplayName", Data.Name);
289 if (!LinkageName.empty())
290 W.printString("LinkageName", LinkageName);
291}
292
293void CVSymbolDumperImpl::visitDefRangeFramePointerRelFullScopeSym(
294 SymbolKind Kind,
295 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
296 DictScope S(W, "DefRangeFramePointerRelFullScope");
297 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Header.Offset);
298}
299
300void CVSymbolDumperImpl::visitDefRangeFramePointerRelSym(
301 SymbolKind Kind, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
302 DictScope S(W, "DefRangeFramePointerRel");
303
304 W.printNumber("Offset", DefRangeFramePointerRel.Header.Offset);
305 printLocalVariableAddrRange(DefRangeFramePointerRel.Header.Range,
306 DefRangeFramePointerRel.getRelocationOffset());
307 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
308}
309
310void CVSymbolDumperImpl::visitDefRangeRegisterRelSym(
311 SymbolKind Kind, DefRangeRegisterRelSym &DefRangeRegisterRel) {
312 DictScope S(W, "DefRangeRegisterRel");
313
314 W.printNumber("BaseRegister", DefRangeRegisterRel.Header.BaseRegister);
315 W.printBoolean("HasSpilledUDTMember",
316 DefRangeRegisterRel.hasSpilledUDTMember());
317 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
318 W.printNumber("BasePointerOffset",
319 DefRangeRegisterRel.Header.BasePointerOffset);
320 printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range,
321 DefRangeRegisterRel.getRelocationOffset());
322 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
323}
324
325void CVSymbolDumperImpl::visitDefRangeRegisterSym(
326 SymbolKind Kind, DefRangeRegisterSym &DefRangeRegister) {
327 DictScope S(W, "DefRangeRegister");
328
329 W.printNumber("Register", DefRangeRegister.Header.Register);
330 W.printNumber("MayHaveNoName", DefRangeRegister.Header.MayHaveNoName);
331 printLocalVariableAddrRange(DefRangeRegister.Header.Range,
332 DefRangeRegister.getRelocationOffset());
333 printLocalVariableAddrGap(DefRangeRegister.Gaps);
334}
335
336void CVSymbolDumperImpl::visitDefRangeSubfieldRegisterSym(
337 SymbolKind Kind, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
338 DictScope S(W, "DefRangeSubfieldRegister");
339
340 W.printNumber("Register", DefRangeSubfieldRegister.Header.Register);
341 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Header.MayHaveNoName);
342 W.printNumber("OffsetInParent",
343 DefRangeSubfieldRegister.Header.OffsetInParent);
344 printLocalVariableAddrRange(DefRangeSubfieldRegister.Header.Range,
345 DefRangeSubfieldRegister.getRelocationOffset());
346 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
347}
348
349void CVSymbolDumperImpl::visitDefRangeSubfieldSym(
350 SymbolKind Kind, DefRangeSubfieldSym &DefRangeSubfield) {
351 DictScope S(W, "DefRangeSubfield");
352
353 if (ObjDelegate) {
354 StringRef StringTable = ObjDelegate->getStringTable();
David Majnemerc6cb2ec2016-05-28 20:04:46 +0000355 auto ProgramStringTableOffset = DefRangeSubfield.Header.Program;
356 if (ProgramStringTableOffset >= StringTable.size())
357 return parseError();
358 StringRef Program =
359 StringTable.drop_front(ProgramStringTableOffset).split('\0').first;
360 W.printString("Program", Program);
Zachary Turneraaad5742016-05-23 23:41:13 +0000361 }
362 W.printNumber("OffsetInParent", DefRangeSubfield.Header.OffsetInParent);
363 printLocalVariableAddrRange(DefRangeSubfield.Header.Range,
364 DefRangeSubfield.getRelocationOffset());
365 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
366}
367
368void CVSymbolDumperImpl::visitDefRangeSym(SymbolKind Kind,
369 DefRangeSym &DefRange) {
370 DictScope S(W, "DefRange");
371
372 if (ObjDelegate) {
373 StringRef StringTable = ObjDelegate->getStringTable();
David Majnemerb3433102016-05-28 19:45:56 +0000374 auto ProgramStringTableOffset = DefRange.Header.Program;
375 if (ProgramStringTableOffset >= StringTable.size())
376 return parseError();
377 StringRef Program =
378 StringTable.drop_front(ProgramStringTableOffset).split('\0').first;
379 W.printString("Program", Program);
Zachary Turneraaad5742016-05-23 23:41:13 +0000380 }
381 printLocalVariableAddrRange(DefRange.Header.Range,
382 DefRange.getRelocationOffset());
383 printLocalVariableAddrGap(DefRange.Gaps);
384}
385
386void CVSymbolDumperImpl::visitFrameCookieSym(SymbolKind Kind,
387 FrameCookieSym &FrameCookie) {
388 DictScope S(W, "FrameCookie");
389
390 StringRef LinkageName;
391 if (ObjDelegate) {
392 ObjDelegate->printRelocatedField(
393 "CodeOffset", FrameCookie.getRelocationOffset(),
394 FrameCookie.Header.CodeOffset, &LinkageName);
395 }
396 W.printHex("Register", FrameCookie.Header.Register);
397 W.printEnum("CookieKind", uint16_t(FrameCookie.Header.CookieKind),
Zachary Turner93839cb2016-06-02 05:07:49 +0000398 getFrameCookieKindNames());
Reid Kleckner33848fa2016-06-24 17:23:49 +0000399 W.printHex("Flags", FrameCookie.Header.Flags);
Zachary Turneraaad5742016-05-23 23:41:13 +0000400}
401
402void CVSymbolDumperImpl::visitFrameProcSym(SymbolKind Kind,
403 FrameProcSym &FrameProc) {
404 DictScope S(W, "FrameProc");
405
406 W.printHex("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
407 W.printHex("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
408 W.printHex("OffsetToPadding", FrameProc.Header.OffsetToPadding);
409 W.printHex("BytesOfCalleeSavedRegisters",
410 FrameProc.Header.BytesOfCalleeSavedRegisters);
411 W.printHex("OffsetOfExceptionHandler",
412 FrameProc.Header.OffsetOfExceptionHandler);
413 W.printHex("SectionIdOfExceptionHandler",
414 FrameProc.Header.SectionIdOfExceptionHandler);
Zachary Turner93839cb2016-06-02 05:07:49 +0000415 W.printFlags("Flags", FrameProc.Header.Flags, getFrameProcSymFlagNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000416}
417
418void CVSymbolDumperImpl::visitHeapAllocationSiteSym(
419 SymbolKind Kind, HeapAllocationSiteSym &HeapAllocSite) {
420 DictScope S(W, "HeapAllocationSite");
421
422 StringRef LinkageName;
423 if (ObjDelegate) {
424 ObjDelegate->printRelocatedField(
425 "CodeOffset", HeapAllocSite.getRelocationOffset(),
426 HeapAllocSite.Header.CodeOffset, &LinkageName);
427 }
428 W.printHex("Segment", HeapAllocSite.Header.Segment);
429 W.printHex("CallInstructionSize", HeapAllocSite.Header.CallInstructionSize);
430 CVTD.printTypeIndex("Type", HeapAllocSite.Header.Type);
431 if (!LinkageName.empty())
432 W.printString("LinkageName", LinkageName);
433}
434
435void CVSymbolDumperImpl::visitInlineSiteSym(SymbolKind Kind,
436 InlineSiteSym &InlineSite) {
437 DictScope S(W, "InlineSite");
438
439 W.printHex("PtrParent", InlineSite.Header.PtrParent);
440 W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
441 CVTD.printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
442
443 ListScope BinaryAnnotations(W, "BinaryAnnotations");
444 for (auto &Annotation : InlineSite.annotations()) {
445 switch (Annotation.OpCode) {
446 case BinaryAnnotationsOpCode::Invalid:
447 return parseError();
448 case BinaryAnnotationsOpCode::CodeOffset:
449 case BinaryAnnotationsOpCode::ChangeCodeOffset:
450 case BinaryAnnotationsOpCode::ChangeCodeLength:
451 W.printHex(Annotation.Name, Annotation.U1);
452 break;
453 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
454 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
455 case BinaryAnnotationsOpCode::ChangeRangeKind:
456 case BinaryAnnotationsOpCode::ChangeColumnStart:
457 case BinaryAnnotationsOpCode::ChangeColumnEnd:
458 W.printNumber(Annotation.Name, Annotation.U1);
459 break;
460 case BinaryAnnotationsOpCode::ChangeLineOffset:
461 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
462 W.printNumber(Annotation.Name, Annotation.S1);
463 break;
464 case BinaryAnnotationsOpCode::ChangeFile:
465 if (ObjDelegate) {
466 W.printHex("ChangeFile",
467 ObjDelegate->getFileNameForFileOffset(Annotation.U1),
468 Annotation.U1);
469 } else {
470 W.printHex("ChangeFile", Annotation.U1);
471 }
472
473 break;
474 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
475 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
476 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
477 << "}\n";
478 break;
479 }
480 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
481 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
482 << W.hex(Annotation.U2)
483 << ", Length: " << W.hex(Annotation.U1) << "}\n";
484 break;
485 }
486 }
487 }
488}
489
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000490void CVSymbolDumperImpl::visitRegisterSym(SymbolKind Kind,
491 RegisterSym &Register) {
492 DictScope S(W, "RegisterSym");
493 W.printNumber("Type", Register.Header.Index);
Zachary Turner93839cb2016-06-02 05:07:49 +0000494 W.printEnum("Seg", uint16_t(Register.Header.Register), getRegisterNames());
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000495 W.printString("Name", Register.Name);
496}
497
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000498void CVSymbolDumperImpl::visitPublicSym32(SymbolKind Kind,
499 PublicSym32 &Public) {
500 DictScope S(W, "PublicSym");
501 W.printNumber("Type", Public.Header.Index);
502 W.printNumber("Seg", Public.Header.Seg);
503 W.printNumber("Off", Public.Header.Off);
504 W.printString("Name", Public.Name);
505}
506
507void CVSymbolDumperImpl::visitProcRefSym(SymbolKind Kind, ProcRefSym &ProcRef) {
508 DictScope S(W, "ProcRef");
509 W.printNumber("SumName", ProcRef.Header.SumName);
510 W.printNumber("SymOffset", ProcRef.Header.SymOffset);
511 W.printNumber("Mod", ProcRef.Header.Mod);
512 W.printString("Name", ProcRef.Name);
513}
514
Zachary Turneraaad5742016-05-23 23:41:13 +0000515void CVSymbolDumperImpl::visitLabelSym(SymbolKind Kind, LabelSym &Label) {
516 DictScope S(W, "Label");
517
518 StringRef LinkageName;
519 if (ObjDelegate) {
520 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
521 Label.Header.CodeOffset, &LinkageName);
522 }
523 W.printHex("Segment", Label.Header.Segment);
524 W.printHex("Flags", Label.Header.Flags);
Zachary Turner93839cb2016-06-02 05:07:49 +0000525 W.printFlags("Flags", Label.Header.Flags, getProcSymFlagNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000526 W.printString("DisplayName", Label.Name);
527 if (!LinkageName.empty())
528 W.printString("LinkageName", LinkageName);
529}
530
531void CVSymbolDumperImpl::visitLocalSym(SymbolKind Kind, LocalSym &Local) {
532 DictScope S(W, "Local");
533
534 CVTD.printTypeIndex("Type", Local.Header.Type);
Zachary Turner93839cb2016-06-02 05:07:49 +0000535 W.printFlags("Flags", uint16_t(Local.Header.Flags), getLocalFlagNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000536 W.printString("VarName", Local.Name);
537}
538
539void CVSymbolDumperImpl::visitObjNameSym(SymbolKind Kind, ObjNameSym &ObjName) {
540 DictScope S(W, "ObjectName");
541
542 W.printHex("Signature", ObjName.Header.Signature);
543 W.printString("ObjectName", ObjName.Name);
544}
545
546void CVSymbolDumperImpl::visitProcSym(SymbolKind Kind, ProcSym &Proc) {
547 DictScope S(W, "ProcStart");
548
549 if (InFunctionScope)
550 return parseError();
551
552 InFunctionScope = true;
553
554 StringRef LinkageName;
555 W.printHex("PtrParent", Proc.Header.PtrParent);
556 W.printHex("PtrEnd", Proc.Header.PtrEnd);
557 W.printHex("PtrNext", Proc.Header.PtrNext);
558 W.printHex("CodeSize", Proc.Header.CodeSize);
559 W.printHex("DbgStart", Proc.Header.DbgStart);
560 W.printHex("DbgEnd", Proc.Header.DbgEnd);
561 CVTD.printTypeIndex("FunctionType", Proc.Header.FunctionType);
562 if (ObjDelegate) {
563 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
564 Proc.Header.CodeOffset, &LinkageName);
565 }
566 W.printHex("Segment", Proc.Header.Segment);
567 W.printFlags("Flags", static_cast<uint8_t>(Proc.Header.Flags),
Zachary Turner93839cb2016-06-02 05:07:49 +0000568 getProcSymFlagNames());
Zachary Turneraaad5742016-05-23 23:41:13 +0000569 W.printString("DisplayName", Proc.Name);
570 if (!LinkageName.empty())
571 W.printString("LinkageName", LinkageName);
572}
573
574void CVSymbolDumperImpl::visitScopeEndSym(SymbolKind Kind,
575 ScopeEndSym &ScopeEnd) {
576 if (Kind == SymbolKind::S_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000577 DictScope S(W, "BlockEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000578 else if (Kind == SymbolKind::S_PROC_ID_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000579 DictScope S(W, "ProcEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000580 else if (Kind == SymbolKind::S_INLINESITE_END)
581 DictScope S(W, "InlineSiteEnd");
582
583 InFunctionScope = false;
584}
585
586void CVSymbolDumperImpl::visitCallerSym(SymbolKind Kind, CallerSym &Caller) {
587 ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
588 for (auto FuncID : Caller.Indices)
589 CVTD.printTypeIndex("FuncID", FuncID);
590}
591
592void CVSymbolDumperImpl::visitRegRelativeSym(SymbolKind Kind,
593 RegRelativeSym &RegRel) {
594 DictScope S(W, "RegRelativeSym");
595
596 W.printHex("Offset", RegRel.Header.Offset);
597 CVTD.printTypeIndex("Type", RegRel.Header.Type);
598 W.printHex("Register", RegRel.Header.Register);
599 W.printString("VarName", RegRel.Name);
600}
601
602void CVSymbolDumperImpl::visitThreadLocalDataSym(SymbolKind Kind,
603 ThreadLocalDataSym &Data) {
604 DictScope S(W, "ThreadLocalDataSym");
605
606 StringRef LinkageName;
607 if (ObjDelegate) {
608 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
609 Data.Header.DataOffset, &LinkageName);
610 }
611 CVTD.printTypeIndex("Type", Data.Header.Type);
612 W.printString("DisplayName", Data.Name);
613 if (!LinkageName.empty())
614 W.printString("LinkageName", LinkageName);
615}
616
617void CVSymbolDumperImpl::visitUDTSym(SymbolKind Kind, UDTSym &UDT) {
618 DictScope S(W, "UDT");
619 CVTD.printTypeIndex("Type", UDT.Header.Type);
620 W.printString("UDTName", UDT.Name);
621}
622
623void CVSymbolDumperImpl::visitUnknownSymbol(SymbolKind Kind,
624 ArrayRef<uint8_t> Data) {
625 DictScope S(W, "UnknownSym");
Zachary Turner93839cb2016-06-02 05:07:49 +0000626 W.printEnum("Kind", uint16_t(Kind), getSymbolTypeNames());
Zachary Turner00d847b2016-05-24 17:44:29 +0000627 W.printNumber("Length", uint32_t(Data.size()));
Zachary Turneraaad5742016-05-23 23:41:13 +0000628}
629
Zachary Turner1de49c92016-05-27 18:47:20 +0000630bool CVSymbolDumper::dump(const CVRecord<SymbolKind> &Record) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000631 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turneraaad5742016-05-23 23:41:13 +0000632 Dumper.visitSymbolRecord(Record);
633 return !Dumper.hadError();
634}
635
Zachary Turner0d43c1c2016-05-28 05:21:57 +0000636bool CVSymbolDumper::dump(const CVSymbolArray &Symbols) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000637 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turner0d43c1c2016-05-28 05:21:57 +0000638 Dumper.visitSymbolStream(Symbols);
Zachary Turneraaad5742016-05-23 23:41:13 +0000639 return !Dumper.hadError();
640}