blob: 60a3b8156b61d23cf44b279767c0bd473dfe817e [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"
14#include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
15#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
16#include "llvm/DebugInfo/CodeView/TypeDumper.h"
17#include "llvm/DebugInfo/CodeView/TypeIndex.h"
18#include "llvm/Support/ScopedPrinter.h"
19
20#include <system_error>
21
22using namespace llvm;
23using namespace llvm::codeview;
24
25static const EnumEntry<SymbolKind> SymbolTypeNames[] = {
26#define CV_SYMBOL(enum, val) {#enum, enum},
27#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
28};
29
30namespace {
31#define CV_ENUM_CLASS_ENT(enum_class, enum) \
32 { #enum, std::underlying_type < enum_class > ::type(enum_class::enum) }
33
34#define CV_ENUM_ENT(ns, enum) \
35 { #enum, ns::enum }
36
37static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
38 CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
39 CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
40 CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
41 CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
42 CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
43 CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
44 CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
45 CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
46};
47
48static const EnumEntry<uint16_t> LocalFlags[] = {
49 CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
50 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
51 CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
52 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
53 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
54 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
55 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
56 CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
57 CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
58 CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
59 CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
60};
61
62static const EnumEntry<uint32_t> FrameCookieKinds[] = {
63 CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
64 CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
65 CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
66 CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
67};
68
69static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
70 CV_ENUM_ENT(SourceLanguage, C), CV_ENUM_ENT(SourceLanguage, Cpp),
71 CV_ENUM_ENT(SourceLanguage, Fortran), CV_ENUM_ENT(SourceLanguage, Masm),
72 CV_ENUM_ENT(SourceLanguage, Pascal), CV_ENUM_ENT(SourceLanguage, Basic),
73 CV_ENUM_ENT(SourceLanguage, Cobol), CV_ENUM_ENT(SourceLanguage, Link),
74 CV_ENUM_ENT(SourceLanguage, Cvtres), CV_ENUM_ENT(SourceLanguage, Cvtpgd),
75 CV_ENUM_ENT(SourceLanguage, CSharp), CV_ENUM_ENT(SourceLanguage, VB),
76 CV_ENUM_ENT(SourceLanguage, ILAsm), CV_ENUM_ENT(SourceLanguage, Java),
77 CV_ENUM_ENT(SourceLanguage, JScript), CV_ENUM_ENT(SourceLanguage, MSIL),
78 CV_ENUM_ENT(SourceLanguage, HLSL),
79};
80
81static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
82 CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
83 CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
84 CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
85 CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
86 CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
87 CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
88 CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
89 CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
90 CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
91 CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
92 CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
93 CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
94};
95
96static const EnumEntry<unsigned> CPUTypeNames[] = {
97 CV_ENUM_CLASS_ENT(CPUType, Intel8080),
98 CV_ENUM_CLASS_ENT(CPUType, Intel8086),
99 CV_ENUM_CLASS_ENT(CPUType, Intel80286),
100 CV_ENUM_CLASS_ENT(CPUType, Intel80386),
101 CV_ENUM_CLASS_ENT(CPUType, Intel80486),
102 CV_ENUM_CLASS_ENT(CPUType, Pentium),
103 CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
104 CV_ENUM_CLASS_ENT(CPUType, Pentium3),
105 CV_ENUM_CLASS_ENT(CPUType, MIPS),
106 CV_ENUM_CLASS_ENT(CPUType, MIPS16),
107 CV_ENUM_CLASS_ENT(CPUType, MIPS32),
108 CV_ENUM_CLASS_ENT(CPUType, MIPS64),
109 CV_ENUM_CLASS_ENT(CPUType, MIPSI),
110 CV_ENUM_CLASS_ENT(CPUType, MIPSII),
111 CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
112 CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
113 CV_ENUM_CLASS_ENT(CPUType, MIPSV),
114 CV_ENUM_CLASS_ENT(CPUType, M68000),
115 CV_ENUM_CLASS_ENT(CPUType, M68010),
116 CV_ENUM_CLASS_ENT(CPUType, M68020),
117 CV_ENUM_CLASS_ENT(CPUType, M68030),
118 CV_ENUM_CLASS_ENT(CPUType, M68040),
119 CV_ENUM_CLASS_ENT(CPUType, Alpha),
120 CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
121 CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
122 CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
123 CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
124 CV_ENUM_CLASS_ENT(CPUType, PPC601),
125 CV_ENUM_CLASS_ENT(CPUType, PPC603),
126 CV_ENUM_CLASS_ENT(CPUType, PPC604),
127 CV_ENUM_CLASS_ENT(CPUType, PPC620),
128 CV_ENUM_CLASS_ENT(CPUType, PPCFP),
129 CV_ENUM_CLASS_ENT(CPUType, PPCBE),
130 CV_ENUM_CLASS_ENT(CPUType, SH3),
131 CV_ENUM_CLASS_ENT(CPUType, SH3E),
132 CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
133 CV_ENUM_CLASS_ENT(CPUType, SH4),
134 CV_ENUM_CLASS_ENT(CPUType, SHMedia),
135 CV_ENUM_CLASS_ENT(CPUType, ARM3),
136 CV_ENUM_CLASS_ENT(CPUType, ARM4),
137 CV_ENUM_CLASS_ENT(CPUType, ARM4T),
138 CV_ENUM_CLASS_ENT(CPUType, ARM5),
139 CV_ENUM_CLASS_ENT(CPUType, ARM5T),
140 CV_ENUM_CLASS_ENT(CPUType, ARM6),
141 CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
142 CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
143 CV_ENUM_CLASS_ENT(CPUType, ARM7),
144 CV_ENUM_CLASS_ENT(CPUType, Omni),
145 CV_ENUM_CLASS_ENT(CPUType, Ia64),
146 CV_ENUM_CLASS_ENT(CPUType, Ia64_2),
147 CV_ENUM_CLASS_ENT(CPUType, CEE),
148 CV_ENUM_CLASS_ENT(CPUType, AM33),
149 CV_ENUM_CLASS_ENT(CPUType, M32R),
150 CV_ENUM_CLASS_ENT(CPUType, TriCore),
151 CV_ENUM_CLASS_ENT(CPUType, X64),
152 CV_ENUM_CLASS_ENT(CPUType, EBC),
153 CV_ENUM_CLASS_ENT(CPUType, Thumb),
154 CV_ENUM_CLASS_ENT(CPUType, ARMNT),
155 CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
156};
157
158static const EnumEntry<uint32_t> FrameProcSymFlags[] = {
159 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
160 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
161 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
162 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
163 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
164 CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
165 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
166 CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
167 CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
168 CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
169 CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
170 CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
171 CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
172 CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
173 CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
174 CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
175 CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
176 CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
177 CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
178};
179
180/// Use this private dumper implementation to keep implementation details about
181/// the visitor out of SymbolDumper.h.
182class CVSymbolDumperImpl : public CVSymbolVisitor<CVSymbolDumperImpl> {
183public:
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000184 CVSymbolDumperImpl(CVTypeDumper &CVTD, SymbolDumpDelegate *ObjDelegate,
185 ScopedPrinter &W, bool PrintRecordBytes)
186 : CVSymbolVisitor(ObjDelegate), CVTD(CVTD), ObjDelegate(ObjDelegate),
187 W(W), PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
Zachary Turneraaad5742016-05-23 23:41:13 +0000188
189/// CVSymbolVisitor overrides.
190#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
191 void visit##Name(SymbolKind Kind, Name &Record);
192#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
193#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
194
195 void visitSymbolBegin(SymbolKind Kind, ArrayRef<uint8_t> Data);
196 void visitSymbolEnd(SymbolKind Kind, ArrayRef<uint8_t> OriginalSymData);
197 void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data);
198
199private:
200 void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
201 uint32_t RelocationOffset);
202 void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
203
Zachary Turneraaad5742016-05-23 23:41:13 +0000204 CVTypeDumper &CVTD;
205 SymbolDumpDelegate *ObjDelegate;
206 ScopedPrinter &W;
207
208 bool PrintRecordBytes;
209 bool InFunctionScope;
210};
211}
212
213void CVSymbolDumperImpl::printLocalVariableAddrRange(
214 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
215 DictScope S(W, "LocalVariableAddrRange");
216 if (ObjDelegate)
217 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
218 Range.OffsetStart);
219 W.printHex("ISectStart", Range.ISectStart);
220 W.printHex("Range", Range.Range);
221}
222
223void CVSymbolDumperImpl::printLocalVariableAddrGap(
224 ArrayRef<LocalVariableAddrGap> Gaps) {
225 for (auto &Gap : Gaps) {
226 ListScope S(W, "LocalVariableAddrGap");
227 W.printHex("GapStartOffset", Gap.GapStartOffset);
228 W.printHex("Range", Gap.Range);
229 }
230}
231
232void CVSymbolDumperImpl::visitSymbolBegin(SymbolKind Kind,
233 ArrayRef<uint8_t> Data) {}
234
235void CVSymbolDumperImpl::visitSymbolEnd(SymbolKind Kind,
236 ArrayRef<uint8_t> OriginalSymData) {
237 if (PrintRecordBytes && ObjDelegate)
238 ObjDelegate->printBinaryBlockWithRelocs("SymData", OriginalSymData);
239}
240
241void CVSymbolDumperImpl::visitBlockSym(SymbolKind Kind, BlockSym &Block) {
242 DictScope S(W, "BlockStart");
243
244 StringRef LinkageName;
245 W.printHex("PtrParent", Block.Header.PtrParent);
246 W.printHex("PtrEnd", Block.Header.PtrEnd);
247 W.printHex("CodeSize", Block.Header.CodeSize);
248 if (ObjDelegate) {
249 ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
250 Block.Header.CodeOffset, &LinkageName);
251 }
252 W.printHex("Segment", Block.Header.Segment);
253 W.printString("BlockName", Block.Name);
254 W.printString("LinkageName", LinkageName);
255}
256
257void CVSymbolDumperImpl::visitBPRelativeSym(SymbolKind Kind,
258 BPRelativeSym &BPRel) {
259 DictScope S(W, "BPRelativeSym");
260
261 W.printNumber("Offset", BPRel.Header.Offset);
262 CVTD.printTypeIndex("Type", BPRel.Header.Type);
263 W.printString("VarName", BPRel.Name);
264}
265
266void CVSymbolDumperImpl::visitBuildInfoSym(SymbolKind Kind,
267 BuildInfoSym &BuildInfo) {
268 DictScope S(W, "BuildInfo");
269
270 W.printNumber("BuildId", BuildInfo.Header.BuildId);
271}
272
273void CVSymbolDumperImpl::visitCallSiteInfoSym(SymbolKind Kind,
274 CallSiteInfoSym &CallSiteInfo) {
275 DictScope S(W, "CallSiteInfo");
276
277 StringRef LinkageName;
278 if (ObjDelegate) {
279 ObjDelegate->printRelocatedField(
280 "CodeOffset", CallSiteInfo.getRelocationOffset(),
281 CallSiteInfo.Header.CodeOffset, &LinkageName);
282 }
283 W.printHex("Segment", CallSiteInfo.Header.Segment);
284 W.printHex("Reserved", CallSiteInfo.Header.Reserved);
285 CVTD.printTypeIndex("Type", CallSiteInfo.Header.Type);
286 if (!LinkageName.empty())
287 W.printString("LinkageName", LinkageName);
288}
289
290void CVSymbolDumperImpl::visitCompile3Sym(SymbolKind Kind,
291 Compile3Sym &Compile3) {
292 DictScope S(W, "CompilerFlags");
293
294 W.printEnum("Language", Compile3.Header.getLanguage(),
295 makeArrayRef(SourceLanguages));
296 W.printFlags("Flags", Compile3.Header.flags & ~0xff,
297 makeArrayRef(CompileSym3FlagNames));
298 W.printEnum("Machine", unsigned(Compile3.Header.Machine),
299 makeArrayRef(CPUTypeNames));
300 std::string FrontendVersion;
301 {
302 raw_string_ostream Out(FrontendVersion);
303 Out << Compile3.Header.VersionFrontendMajor << '.'
304 << Compile3.Header.VersionFrontendMinor << '.'
305 << Compile3.Header.VersionFrontendBuild << '.'
306 << Compile3.Header.VersionFrontendQFE;
307 }
308 std::string BackendVersion;
309 {
310 raw_string_ostream Out(BackendVersion);
311 Out << Compile3.Header.VersionBackendMajor << '.'
312 << Compile3.Header.VersionBackendMinor << '.'
313 << Compile3.Header.VersionBackendBuild << '.'
314 << Compile3.Header.VersionBackendQFE;
315 }
316 W.printString("FrontendVersion", FrontendVersion);
317 W.printString("BackendVersion", BackendVersion);
318 W.printString("VersionName", Compile3.Version);
319}
320
321void CVSymbolDumperImpl::visitConstantSym(SymbolKind Kind,
322 ConstantSym &Constant) {
323 DictScope S(W, "Constant");
324
325 CVTD.printTypeIndex("Type", Constant.Header.Type);
326 W.printNumber("Value", Constant.Value);
327 W.printString("Name", Constant.Name);
328}
329
330void CVSymbolDumperImpl::visitDataSym(SymbolKind Kind, DataSym &Data) {
331 DictScope S(W, "DataSym");
332
333 StringRef LinkageName;
334 if (ObjDelegate) {
335 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
336 Data.Header.DataOffset, &LinkageName);
337 }
338 CVTD.printTypeIndex("Type", Data.Header.Type);
339 W.printString("DisplayName", Data.Name);
340 if (!LinkageName.empty())
341 W.printString("LinkageName", LinkageName);
342}
343
344void CVSymbolDumperImpl::visitDefRangeFramePointerRelFullScopeSym(
345 SymbolKind Kind,
346 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
347 DictScope S(W, "DefRangeFramePointerRelFullScope");
348 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Header.Offset);
349}
350
351void CVSymbolDumperImpl::visitDefRangeFramePointerRelSym(
352 SymbolKind Kind, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
353 DictScope S(W, "DefRangeFramePointerRel");
354
355 W.printNumber("Offset", DefRangeFramePointerRel.Header.Offset);
356 printLocalVariableAddrRange(DefRangeFramePointerRel.Header.Range,
357 DefRangeFramePointerRel.getRelocationOffset());
358 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
359}
360
361void CVSymbolDumperImpl::visitDefRangeRegisterRelSym(
362 SymbolKind Kind, DefRangeRegisterRelSym &DefRangeRegisterRel) {
363 DictScope S(W, "DefRangeRegisterRel");
364
365 W.printNumber("BaseRegister", DefRangeRegisterRel.Header.BaseRegister);
366 W.printBoolean("HasSpilledUDTMember",
367 DefRangeRegisterRel.hasSpilledUDTMember());
368 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
369 W.printNumber("BasePointerOffset",
370 DefRangeRegisterRel.Header.BasePointerOffset);
371 printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range,
372 DefRangeRegisterRel.getRelocationOffset());
373 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
374}
375
376void CVSymbolDumperImpl::visitDefRangeRegisterSym(
377 SymbolKind Kind, DefRangeRegisterSym &DefRangeRegister) {
378 DictScope S(W, "DefRangeRegister");
379
380 W.printNumber("Register", DefRangeRegister.Header.Register);
381 W.printNumber("MayHaveNoName", DefRangeRegister.Header.MayHaveNoName);
382 printLocalVariableAddrRange(DefRangeRegister.Header.Range,
383 DefRangeRegister.getRelocationOffset());
384 printLocalVariableAddrGap(DefRangeRegister.Gaps);
385}
386
387void CVSymbolDumperImpl::visitDefRangeSubfieldRegisterSym(
388 SymbolKind Kind, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
389 DictScope S(W, "DefRangeSubfieldRegister");
390
391 W.printNumber("Register", DefRangeSubfieldRegister.Header.Register);
392 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Header.MayHaveNoName);
393 W.printNumber("OffsetInParent",
394 DefRangeSubfieldRegister.Header.OffsetInParent);
395 printLocalVariableAddrRange(DefRangeSubfieldRegister.Header.Range,
396 DefRangeSubfieldRegister.getRelocationOffset());
397 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
398}
399
400void CVSymbolDumperImpl::visitDefRangeSubfieldSym(
401 SymbolKind Kind, DefRangeSubfieldSym &DefRangeSubfield) {
402 DictScope S(W, "DefRangeSubfield");
403
404 if (ObjDelegate) {
405 StringRef StringTable = ObjDelegate->getStringTable();
406 if (!StringTable.empty()) {
407 W.printString("Program",
408 StringTable.drop_front(DefRangeSubfield.Header.Program)
409 .split('\0')
410 .first);
411 }
412 }
413 W.printNumber("OffsetInParent", DefRangeSubfield.Header.OffsetInParent);
414 printLocalVariableAddrRange(DefRangeSubfield.Header.Range,
415 DefRangeSubfield.getRelocationOffset());
416 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
417}
418
419void CVSymbolDumperImpl::visitDefRangeSym(SymbolKind Kind,
420 DefRangeSym &DefRange) {
421 DictScope S(W, "DefRange");
422
423 if (ObjDelegate) {
424 StringRef StringTable = ObjDelegate->getStringTable();
425 if (!StringTable.empty()) {
426 W.printString(
427 "Program",
428 StringTable.drop_front(DefRange.Header.Program).split('\0').first);
429 }
430 }
431 printLocalVariableAddrRange(DefRange.Header.Range,
432 DefRange.getRelocationOffset());
433 printLocalVariableAddrGap(DefRange.Gaps);
434}
435
436void CVSymbolDumperImpl::visitFrameCookieSym(SymbolKind Kind,
437 FrameCookieSym &FrameCookie) {
438 DictScope S(W, "FrameCookie");
439
440 StringRef LinkageName;
441 if (ObjDelegate) {
442 ObjDelegate->printRelocatedField(
443 "CodeOffset", FrameCookie.getRelocationOffset(),
444 FrameCookie.Header.CodeOffset, &LinkageName);
445 }
446 W.printHex("Register", FrameCookie.Header.Register);
447 W.printEnum("CookieKind", uint16_t(FrameCookie.Header.CookieKind),
448 makeArrayRef(FrameCookieKinds));
449}
450
451void CVSymbolDumperImpl::visitFrameProcSym(SymbolKind Kind,
452 FrameProcSym &FrameProc) {
453 DictScope S(W, "FrameProc");
454
455 W.printHex("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
456 W.printHex("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
457 W.printHex("OffsetToPadding", FrameProc.Header.OffsetToPadding);
458 W.printHex("BytesOfCalleeSavedRegisters",
459 FrameProc.Header.BytesOfCalleeSavedRegisters);
460 W.printHex("OffsetOfExceptionHandler",
461 FrameProc.Header.OffsetOfExceptionHandler);
462 W.printHex("SectionIdOfExceptionHandler",
463 FrameProc.Header.SectionIdOfExceptionHandler);
464 W.printFlags("Flags", FrameProc.Header.Flags,
465 makeArrayRef(FrameProcSymFlags));
466}
467
468void CVSymbolDumperImpl::visitHeapAllocationSiteSym(
469 SymbolKind Kind, HeapAllocationSiteSym &HeapAllocSite) {
470 DictScope S(W, "HeapAllocationSite");
471
472 StringRef LinkageName;
473 if (ObjDelegate) {
474 ObjDelegate->printRelocatedField(
475 "CodeOffset", HeapAllocSite.getRelocationOffset(),
476 HeapAllocSite.Header.CodeOffset, &LinkageName);
477 }
478 W.printHex("Segment", HeapAllocSite.Header.Segment);
479 W.printHex("CallInstructionSize", HeapAllocSite.Header.CallInstructionSize);
480 CVTD.printTypeIndex("Type", HeapAllocSite.Header.Type);
481 if (!LinkageName.empty())
482 W.printString("LinkageName", LinkageName);
483}
484
485void CVSymbolDumperImpl::visitInlineSiteSym(SymbolKind Kind,
486 InlineSiteSym &InlineSite) {
487 DictScope S(W, "InlineSite");
488
489 W.printHex("PtrParent", InlineSite.Header.PtrParent);
490 W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
491 CVTD.printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
492
493 ListScope BinaryAnnotations(W, "BinaryAnnotations");
494 for (auto &Annotation : InlineSite.annotations()) {
495 switch (Annotation.OpCode) {
496 case BinaryAnnotationsOpCode::Invalid:
497 return parseError();
498 case BinaryAnnotationsOpCode::CodeOffset:
499 case BinaryAnnotationsOpCode::ChangeCodeOffset:
500 case BinaryAnnotationsOpCode::ChangeCodeLength:
501 W.printHex(Annotation.Name, Annotation.U1);
502 break;
503 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
504 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
505 case BinaryAnnotationsOpCode::ChangeRangeKind:
506 case BinaryAnnotationsOpCode::ChangeColumnStart:
507 case BinaryAnnotationsOpCode::ChangeColumnEnd:
508 W.printNumber(Annotation.Name, Annotation.U1);
509 break;
510 case BinaryAnnotationsOpCode::ChangeLineOffset:
511 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
512 W.printNumber(Annotation.Name, Annotation.S1);
513 break;
514 case BinaryAnnotationsOpCode::ChangeFile:
515 if (ObjDelegate) {
516 W.printHex("ChangeFile",
517 ObjDelegate->getFileNameForFileOffset(Annotation.U1),
518 Annotation.U1);
519 } else {
520 W.printHex("ChangeFile", Annotation.U1);
521 }
522
523 break;
524 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
525 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
526 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
527 << "}\n";
528 break;
529 }
530 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
531 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
532 << W.hex(Annotation.U2)
533 << ", Length: " << W.hex(Annotation.U1) << "}\n";
534 break;
535 }
536 }
537 }
538}
539
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000540void CVSymbolDumperImpl::visitPublicSym32(SymbolKind Kind,
541 PublicSym32 &Public) {
542 DictScope S(W, "PublicSym");
543 W.printNumber("Type", Public.Header.Index);
544 W.printNumber("Seg", Public.Header.Seg);
545 W.printNumber("Off", Public.Header.Off);
546 W.printString("Name", Public.Name);
547}
548
549void CVSymbolDumperImpl::visitProcRefSym(SymbolKind Kind, ProcRefSym &ProcRef) {
550 DictScope S(W, "ProcRef");
551 W.printNumber("SumName", ProcRef.Header.SumName);
552 W.printNumber("SymOffset", ProcRef.Header.SymOffset);
553 W.printNumber("Mod", ProcRef.Header.Mod);
554 W.printString("Name", ProcRef.Name);
555}
556
Zachary Turneraaad5742016-05-23 23:41:13 +0000557void CVSymbolDumperImpl::visitLabelSym(SymbolKind Kind, LabelSym &Label) {
558 DictScope S(W, "Label");
559
560 StringRef LinkageName;
561 if (ObjDelegate) {
562 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
563 Label.Header.CodeOffset, &LinkageName);
564 }
565 W.printHex("Segment", Label.Header.Segment);
566 W.printHex("Flags", Label.Header.Flags);
567 W.printFlags("Flags", Label.Header.Flags, makeArrayRef(ProcSymFlagNames));
568 W.printString("DisplayName", Label.Name);
569 if (!LinkageName.empty())
570 W.printString("LinkageName", LinkageName);
571}
572
573void CVSymbolDumperImpl::visitLocalSym(SymbolKind Kind, LocalSym &Local) {
574 DictScope S(W, "Local");
575
576 CVTD.printTypeIndex("Type", Local.Header.Type);
577 W.printFlags("Flags", uint16_t(Local.Header.Flags), makeArrayRef(LocalFlags));
578 W.printString("VarName", Local.Name);
579}
580
581void CVSymbolDumperImpl::visitObjNameSym(SymbolKind Kind, ObjNameSym &ObjName) {
582 DictScope S(W, "ObjectName");
583
584 W.printHex("Signature", ObjName.Header.Signature);
585 W.printString("ObjectName", ObjName.Name);
586}
587
588void CVSymbolDumperImpl::visitProcSym(SymbolKind Kind, ProcSym &Proc) {
589 DictScope S(W, "ProcStart");
590
591 if (InFunctionScope)
592 return parseError();
593
594 InFunctionScope = true;
595
596 StringRef LinkageName;
597 W.printHex("PtrParent", Proc.Header.PtrParent);
598 W.printHex("PtrEnd", Proc.Header.PtrEnd);
599 W.printHex("PtrNext", Proc.Header.PtrNext);
600 W.printHex("CodeSize", Proc.Header.CodeSize);
601 W.printHex("DbgStart", Proc.Header.DbgStart);
602 W.printHex("DbgEnd", Proc.Header.DbgEnd);
603 CVTD.printTypeIndex("FunctionType", Proc.Header.FunctionType);
604 if (ObjDelegate) {
605 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
606 Proc.Header.CodeOffset, &LinkageName);
607 }
608 W.printHex("Segment", Proc.Header.Segment);
609 W.printFlags("Flags", static_cast<uint8_t>(Proc.Header.Flags),
610 makeArrayRef(ProcSymFlagNames));
611 W.printString("DisplayName", Proc.Name);
612 if (!LinkageName.empty())
613 W.printString("LinkageName", LinkageName);
614}
615
616void CVSymbolDumperImpl::visitScopeEndSym(SymbolKind Kind,
617 ScopeEndSym &ScopeEnd) {
618 if (Kind == SymbolKind::S_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000619 DictScope S(W, "BlockEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000620 else if (Kind == SymbolKind::S_PROC_ID_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000621 DictScope S(W, "ProcEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000622 else if (Kind == SymbolKind::S_INLINESITE_END)
623 DictScope S(W, "InlineSiteEnd");
624
625 InFunctionScope = false;
626}
627
628void CVSymbolDumperImpl::visitCallerSym(SymbolKind Kind, CallerSym &Caller) {
629 ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
630 for (auto FuncID : Caller.Indices)
631 CVTD.printTypeIndex("FuncID", FuncID);
632}
633
634void CVSymbolDumperImpl::visitRegRelativeSym(SymbolKind Kind,
635 RegRelativeSym &RegRel) {
636 DictScope S(W, "RegRelativeSym");
637
638 W.printHex("Offset", RegRel.Header.Offset);
639 CVTD.printTypeIndex("Type", RegRel.Header.Type);
640 W.printHex("Register", RegRel.Header.Register);
641 W.printString("VarName", RegRel.Name);
642}
643
644void CVSymbolDumperImpl::visitThreadLocalDataSym(SymbolKind Kind,
645 ThreadLocalDataSym &Data) {
646 DictScope S(W, "ThreadLocalDataSym");
647
648 StringRef LinkageName;
649 if (ObjDelegate) {
650 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
651 Data.Header.DataOffset, &LinkageName);
652 }
653 CVTD.printTypeIndex("Type", Data.Header.Type);
654 W.printString("DisplayName", Data.Name);
655 if (!LinkageName.empty())
656 W.printString("LinkageName", LinkageName);
657}
658
659void CVSymbolDumperImpl::visitUDTSym(SymbolKind Kind, UDTSym &UDT) {
660 DictScope S(W, "UDT");
661 CVTD.printTypeIndex("Type", UDT.Header.Type);
662 W.printString("UDTName", UDT.Name);
663}
664
665void CVSymbolDumperImpl::visitUnknownSymbol(SymbolKind Kind,
666 ArrayRef<uint8_t> Data) {
667 DictScope S(W, "UnknownSym");
Zachary Turner00d847b2016-05-24 17:44:29 +0000668 W.printEnum("Kind", uint16_t(Kind), makeArrayRef(SymbolTypeNames));
669 W.printNumber("Length", uint32_t(Data.size()));
Zachary Turneraaad5742016-05-23 23:41:13 +0000670}
671
672bool CVSymbolDumper::dump(const SymbolIterator::Record &Record) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000673 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turneraaad5742016-05-23 23:41:13 +0000674 Dumper.visitSymbolRecord(Record);
675 return !Dumper.hadError();
676}
677
678bool CVSymbolDumper::dump(ArrayRef<uint8_t> Data) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000679 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turneraaad5742016-05-23 23:41:13 +0000680 Dumper.visitSymbolStream(Data);
681 return !Dumper.hadError();
682}