blob: 989772b8fb29372a0480ae2ae844f96c35026681 [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
Zachary Turner4caa1bf2016-05-24 22:58:46 +000037static const EnumEntry<uint16_t> RegisterNames[] = {
38 CV_ENUM_CLASS_ENT(RegisterId, Unknown),
39 CV_ENUM_CLASS_ENT(RegisterId, VFrame),
40 CV_ENUM_CLASS_ENT(RegisterId, AL),
41 CV_ENUM_CLASS_ENT(RegisterId, CL),
42 CV_ENUM_CLASS_ENT(RegisterId, DL),
43 CV_ENUM_CLASS_ENT(RegisterId, BL),
44 CV_ENUM_CLASS_ENT(RegisterId, AH),
45 CV_ENUM_CLASS_ENT(RegisterId, CH),
46 CV_ENUM_CLASS_ENT(RegisterId, DH),
47 CV_ENUM_CLASS_ENT(RegisterId, BH),
48 CV_ENUM_CLASS_ENT(RegisterId, AX),
49 CV_ENUM_CLASS_ENT(RegisterId, CX),
50 CV_ENUM_CLASS_ENT(RegisterId, DX),
51 CV_ENUM_CLASS_ENT(RegisterId, BX),
52 CV_ENUM_CLASS_ENT(RegisterId, SP),
53 CV_ENUM_CLASS_ENT(RegisterId, BP),
54 CV_ENUM_CLASS_ENT(RegisterId, SI),
55 CV_ENUM_CLASS_ENT(RegisterId, DI),
56 CV_ENUM_CLASS_ENT(RegisterId, EAX),
57 CV_ENUM_CLASS_ENT(RegisterId, ECX),
58 CV_ENUM_CLASS_ENT(RegisterId, EDX),
59 CV_ENUM_CLASS_ENT(RegisterId, EBX),
60 CV_ENUM_CLASS_ENT(RegisterId, ESP),
61 CV_ENUM_CLASS_ENT(RegisterId, EBP),
62 CV_ENUM_CLASS_ENT(RegisterId, ESI),
63 CV_ENUM_CLASS_ENT(RegisterId, EDI),
64 CV_ENUM_CLASS_ENT(RegisterId, ES),
65 CV_ENUM_CLASS_ENT(RegisterId, CS),
66 CV_ENUM_CLASS_ENT(RegisterId, SS),
67 CV_ENUM_CLASS_ENT(RegisterId, DS),
68 CV_ENUM_CLASS_ENT(RegisterId, FS),
69 CV_ENUM_CLASS_ENT(RegisterId, GS),
70 CV_ENUM_CLASS_ENT(RegisterId, IP),
71 CV_ENUM_CLASS_ENT(RegisterId, RAX),
72 CV_ENUM_CLASS_ENT(RegisterId, RBX),
73 CV_ENUM_CLASS_ENT(RegisterId, RCX),
74 CV_ENUM_CLASS_ENT(RegisterId, RDX),
75 CV_ENUM_CLASS_ENT(RegisterId, RSI),
76 CV_ENUM_CLASS_ENT(RegisterId, RDI),
77 CV_ENUM_CLASS_ENT(RegisterId, RBP),
78 CV_ENUM_CLASS_ENT(RegisterId, RSP),
79 CV_ENUM_CLASS_ENT(RegisterId, R8),
80 CV_ENUM_CLASS_ENT(RegisterId, R9),
81 CV_ENUM_CLASS_ENT(RegisterId, R10),
82 CV_ENUM_CLASS_ENT(RegisterId, R11),
83 CV_ENUM_CLASS_ENT(RegisterId, R12),
84 CV_ENUM_CLASS_ENT(RegisterId, R13),
85 CV_ENUM_CLASS_ENT(RegisterId, R14),
86 CV_ENUM_CLASS_ENT(RegisterId, R15),
87};
88
Zachary Turneraaad5742016-05-23 23:41:13 +000089static const EnumEntry<uint8_t> ProcSymFlagNames[] = {
90 CV_ENUM_CLASS_ENT(ProcSymFlags, HasFP),
91 CV_ENUM_CLASS_ENT(ProcSymFlags, HasIRET),
92 CV_ENUM_CLASS_ENT(ProcSymFlags, HasFRET),
93 CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoReturn),
94 CV_ENUM_CLASS_ENT(ProcSymFlags, IsUnreachable),
95 CV_ENUM_CLASS_ENT(ProcSymFlags, HasCustomCallingConv),
96 CV_ENUM_CLASS_ENT(ProcSymFlags, IsNoInline),
97 CV_ENUM_CLASS_ENT(ProcSymFlags, HasOptimizedDebugInfo),
98};
99
100static const EnumEntry<uint16_t> LocalFlags[] = {
101 CV_ENUM_CLASS_ENT(LocalSymFlags, IsParameter),
102 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAddressTaken),
103 CV_ENUM_CLASS_ENT(LocalSymFlags, IsCompilerGenerated),
104 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregate),
105 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAggregated),
106 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAliased),
107 CV_ENUM_CLASS_ENT(LocalSymFlags, IsAlias),
108 CV_ENUM_CLASS_ENT(LocalSymFlags, IsReturnValue),
109 CV_ENUM_CLASS_ENT(LocalSymFlags, IsOptimizedOut),
110 CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredGlobal),
111 CV_ENUM_CLASS_ENT(LocalSymFlags, IsEnregisteredStatic),
112};
113
114static const EnumEntry<uint32_t> FrameCookieKinds[] = {
115 CV_ENUM_CLASS_ENT(FrameCookieKind, Copy),
116 CV_ENUM_CLASS_ENT(FrameCookieKind, XorStackPointer),
117 CV_ENUM_CLASS_ENT(FrameCookieKind, XorFramePointer),
118 CV_ENUM_CLASS_ENT(FrameCookieKind, XorR13),
119};
120
121static const EnumEntry<codeview::SourceLanguage> SourceLanguages[] = {
122 CV_ENUM_ENT(SourceLanguage, C), CV_ENUM_ENT(SourceLanguage, Cpp),
123 CV_ENUM_ENT(SourceLanguage, Fortran), CV_ENUM_ENT(SourceLanguage, Masm),
124 CV_ENUM_ENT(SourceLanguage, Pascal), CV_ENUM_ENT(SourceLanguage, Basic),
125 CV_ENUM_ENT(SourceLanguage, Cobol), CV_ENUM_ENT(SourceLanguage, Link),
126 CV_ENUM_ENT(SourceLanguage, Cvtres), CV_ENUM_ENT(SourceLanguage, Cvtpgd),
127 CV_ENUM_ENT(SourceLanguage, CSharp), CV_ENUM_ENT(SourceLanguage, VB),
128 CV_ENUM_ENT(SourceLanguage, ILAsm), CV_ENUM_ENT(SourceLanguage, Java),
129 CV_ENUM_ENT(SourceLanguage, JScript), CV_ENUM_ENT(SourceLanguage, MSIL),
130 CV_ENUM_ENT(SourceLanguage, HLSL),
131};
132
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000133static const EnumEntry<uint32_t> CompileSym2FlagNames[] = {
134 CV_ENUM_CLASS_ENT(CompileSym2Flags, EC),
135 CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDbgInfo),
136 CV_ENUM_CLASS_ENT(CompileSym2Flags, LTCG),
137 CV_ENUM_CLASS_ENT(CompileSym2Flags, NoDataAlign),
138 CV_ENUM_CLASS_ENT(CompileSym2Flags, ManagedPresent),
139 CV_ENUM_CLASS_ENT(CompileSym2Flags, SecurityChecks),
140 CV_ENUM_CLASS_ENT(CompileSym2Flags, HotPatch),
141 CV_ENUM_CLASS_ENT(CompileSym2Flags, CVTCIL),
142 CV_ENUM_CLASS_ENT(CompileSym2Flags, MSILModule),
143};
144
Zachary Turneraaad5742016-05-23 23:41:13 +0000145static const EnumEntry<uint32_t> CompileSym3FlagNames[] = {
146 CV_ENUM_CLASS_ENT(CompileSym3Flags, EC),
147 CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDbgInfo),
148 CV_ENUM_CLASS_ENT(CompileSym3Flags, LTCG),
149 CV_ENUM_CLASS_ENT(CompileSym3Flags, NoDataAlign),
150 CV_ENUM_CLASS_ENT(CompileSym3Flags, ManagedPresent),
151 CV_ENUM_CLASS_ENT(CompileSym3Flags, SecurityChecks),
152 CV_ENUM_CLASS_ENT(CompileSym3Flags, HotPatch),
153 CV_ENUM_CLASS_ENT(CompileSym3Flags, CVTCIL),
154 CV_ENUM_CLASS_ENT(CompileSym3Flags, MSILModule),
155 CV_ENUM_CLASS_ENT(CompileSym3Flags, Sdl),
156 CV_ENUM_CLASS_ENT(CompileSym3Flags, PGO),
157 CV_ENUM_CLASS_ENT(CompileSym3Flags, Exp),
158};
159
160static const EnumEntry<unsigned> CPUTypeNames[] = {
161 CV_ENUM_CLASS_ENT(CPUType, Intel8080),
162 CV_ENUM_CLASS_ENT(CPUType, Intel8086),
163 CV_ENUM_CLASS_ENT(CPUType, Intel80286),
164 CV_ENUM_CLASS_ENT(CPUType, Intel80386),
165 CV_ENUM_CLASS_ENT(CPUType, Intel80486),
166 CV_ENUM_CLASS_ENT(CPUType, Pentium),
167 CV_ENUM_CLASS_ENT(CPUType, PentiumPro),
168 CV_ENUM_CLASS_ENT(CPUType, Pentium3),
169 CV_ENUM_CLASS_ENT(CPUType, MIPS),
170 CV_ENUM_CLASS_ENT(CPUType, MIPS16),
171 CV_ENUM_CLASS_ENT(CPUType, MIPS32),
172 CV_ENUM_CLASS_ENT(CPUType, MIPS64),
173 CV_ENUM_CLASS_ENT(CPUType, MIPSI),
174 CV_ENUM_CLASS_ENT(CPUType, MIPSII),
175 CV_ENUM_CLASS_ENT(CPUType, MIPSIII),
176 CV_ENUM_CLASS_ENT(CPUType, MIPSIV),
177 CV_ENUM_CLASS_ENT(CPUType, MIPSV),
178 CV_ENUM_CLASS_ENT(CPUType, M68000),
179 CV_ENUM_CLASS_ENT(CPUType, M68010),
180 CV_ENUM_CLASS_ENT(CPUType, M68020),
181 CV_ENUM_CLASS_ENT(CPUType, M68030),
182 CV_ENUM_CLASS_ENT(CPUType, M68040),
183 CV_ENUM_CLASS_ENT(CPUType, Alpha),
184 CV_ENUM_CLASS_ENT(CPUType, Alpha21164),
185 CV_ENUM_CLASS_ENT(CPUType, Alpha21164A),
186 CV_ENUM_CLASS_ENT(CPUType, Alpha21264),
187 CV_ENUM_CLASS_ENT(CPUType, Alpha21364),
188 CV_ENUM_CLASS_ENT(CPUType, PPC601),
189 CV_ENUM_CLASS_ENT(CPUType, PPC603),
190 CV_ENUM_CLASS_ENT(CPUType, PPC604),
191 CV_ENUM_CLASS_ENT(CPUType, PPC620),
192 CV_ENUM_CLASS_ENT(CPUType, PPCFP),
193 CV_ENUM_CLASS_ENT(CPUType, PPCBE),
194 CV_ENUM_CLASS_ENT(CPUType, SH3),
195 CV_ENUM_CLASS_ENT(CPUType, SH3E),
196 CV_ENUM_CLASS_ENT(CPUType, SH3DSP),
197 CV_ENUM_CLASS_ENT(CPUType, SH4),
198 CV_ENUM_CLASS_ENT(CPUType, SHMedia),
199 CV_ENUM_CLASS_ENT(CPUType, ARM3),
200 CV_ENUM_CLASS_ENT(CPUType, ARM4),
201 CV_ENUM_CLASS_ENT(CPUType, ARM4T),
202 CV_ENUM_CLASS_ENT(CPUType, ARM5),
203 CV_ENUM_CLASS_ENT(CPUType, ARM5T),
204 CV_ENUM_CLASS_ENT(CPUType, ARM6),
205 CV_ENUM_CLASS_ENT(CPUType, ARM_XMAC),
206 CV_ENUM_CLASS_ENT(CPUType, ARM_WMMX),
207 CV_ENUM_CLASS_ENT(CPUType, ARM7),
208 CV_ENUM_CLASS_ENT(CPUType, Omni),
209 CV_ENUM_CLASS_ENT(CPUType, Ia64),
210 CV_ENUM_CLASS_ENT(CPUType, Ia64_2),
211 CV_ENUM_CLASS_ENT(CPUType, CEE),
212 CV_ENUM_CLASS_ENT(CPUType, AM33),
213 CV_ENUM_CLASS_ENT(CPUType, M32R),
214 CV_ENUM_CLASS_ENT(CPUType, TriCore),
215 CV_ENUM_CLASS_ENT(CPUType, X64),
216 CV_ENUM_CLASS_ENT(CPUType, EBC),
217 CV_ENUM_CLASS_ENT(CPUType, Thumb),
218 CV_ENUM_CLASS_ENT(CPUType, ARMNT),
219 CV_ENUM_CLASS_ENT(CPUType, D3D11_Shader),
220};
221
222static const EnumEntry<uint32_t> FrameProcSymFlags[] = {
223 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasAlloca),
224 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasSetJmp),
225 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasLongJmp),
226 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasInlineAssembly),
227 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasExceptionHandling),
228 CV_ENUM_CLASS_ENT(FrameProcedureOptions, MarkedInline),
229 CV_ENUM_CLASS_ENT(FrameProcedureOptions, HasStructuredExceptionHandling),
230 CV_ENUM_CLASS_ENT(FrameProcedureOptions, Naked),
231 CV_ENUM_CLASS_ENT(FrameProcedureOptions, SecurityChecks),
232 CV_ENUM_CLASS_ENT(FrameProcedureOptions, AsynchronousExceptionHandling),
233 CV_ENUM_CLASS_ENT(FrameProcedureOptions, NoStackOrderingForSecurityChecks),
234 CV_ENUM_CLASS_ENT(FrameProcedureOptions, Inlined),
235 CV_ENUM_CLASS_ENT(FrameProcedureOptions, StrictSecurityChecks),
236 CV_ENUM_CLASS_ENT(FrameProcedureOptions, SafeBuffers),
237 CV_ENUM_CLASS_ENT(FrameProcedureOptions, ProfileGuidedOptimization),
238 CV_ENUM_CLASS_ENT(FrameProcedureOptions, ValidProfileCounts),
239 CV_ENUM_CLASS_ENT(FrameProcedureOptions, OptimizedForSpeed),
240 CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfg),
241 CV_ENUM_CLASS_ENT(FrameProcedureOptions, GuardCfw),
242};
243
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000244static const EnumEntry<uint8_t> ThunkOrdinalNames[] = {
245 CV_ENUM_CLASS_ENT(ThunkOrdinal, Standard),
246 CV_ENUM_CLASS_ENT(ThunkOrdinal, ThisAdjustor),
247 CV_ENUM_CLASS_ENT(ThunkOrdinal, Vcall),
248 CV_ENUM_CLASS_ENT(ThunkOrdinal, Pcode),
249 CV_ENUM_CLASS_ENT(ThunkOrdinal, UnknownLoad),
250 CV_ENUM_CLASS_ENT(ThunkOrdinal, TrampIncremental),
251 CV_ENUM_CLASS_ENT(ThunkOrdinal, BranchIsland),
252};
253
254static const EnumEntry<uint16_t> TrampolineNames[] = {
255 CV_ENUM_CLASS_ENT(TrampolineType, TrampIncremental),
256 CV_ENUM_CLASS_ENT(TrampolineType, BranchIsland),
257};
258
Zachary Turneraaad5742016-05-23 23:41:13 +0000259/// Use this private dumper implementation to keep implementation details about
260/// the visitor out of SymbolDumper.h.
261class CVSymbolDumperImpl : public CVSymbolVisitor<CVSymbolDumperImpl> {
262public:
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000263 CVSymbolDumperImpl(CVTypeDumper &CVTD, SymbolDumpDelegate *ObjDelegate,
264 ScopedPrinter &W, bool PrintRecordBytes)
265 : CVSymbolVisitor(ObjDelegate), CVTD(CVTD), ObjDelegate(ObjDelegate),
266 W(W), PrintRecordBytes(PrintRecordBytes), InFunctionScope(false) {}
Zachary Turneraaad5742016-05-23 23:41:13 +0000267
268/// CVSymbolVisitor overrides.
269#define SYMBOL_RECORD(EnumName, EnumVal, Name) \
270 void visit##Name(SymbolKind Kind, Name &Record);
271#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName)
272#include "llvm/DebugInfo/CodeView/CVSymbolTypes.def"
273
274 void visitSymbolBegin(SymbolKind Kind, ArrayRef<uint8_t> Data);
275 void visitSymbolEnd(SymbolKind Kind, ArrayRef<uint8_t> OriginalSymData);
276 void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data);
277
278private:
279 void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
280 uint32_t RelocationOffset);
281 void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
282
Zachary Turneraaad5742016-05-23 23:41:13 +0000283 CVTypeDumper &CVTD;
284 SymbolDumpDelegate *ObjDelegate;
285 ScopedPrinter &W;
286
287 bool PrintRecordBytes;
288 bool InFunctionScope;
289};
290}
291
292void CVSymbolDumperImpl::printLocalVariableAddrRange(
293 const LocalVariableAddrRange &Range, uint32_t RelocationOffset) {
294 DictScope S(W, "LocalVariableAddrRange");
295 if (ObjDelegate)
296 ObjDelegate->printRelocatedField("OffsetStart", RelocationOffset,
297 Range.OffsetStart);
298 W.printHex("ISectStart", Range.ISectStart);
299 W.printHex("Range", Range.Range);
300}
301
302void CVSymbolDumperImpl::printLocalVariableAddrGap(
303 ArrayRef<LocalVariableAddrGap> Gaps) {
304 for (auto &Gap : Gaps) {
305 ListScope S(W, "LocalVariableAddrGap");
306 W.printHex("GapStartOffset", Gap.GapStartOffset);
307 W.printHex("Range", Gap.Range);
308 }
309}
310
311void CVSymbolDumperImpl::visitSymbolBegin(SymbolKind Kind,
312 ArrayRef<uint8_t> Data) {}
313
314void CVSymbolDumperImpl::visitSymbolEnd(SymbolKind Kind,
315 ArrayRef<uint8_t> OriginalSymData) {
316 if (PrintRecordBytes && ObjDelegate)
317 ObjDelegate->printBinaryBlockWithRelocs("SymData", OriginalSymData);
318}
319
320void CVSymbolDumperImpl::visitBlockSym(SymbolKind Kind, BlockSym &Block) {
321 DictScope S(W, "BlockStart");
322
323 StringRef LinkageName;
324 W.printHex("PtrParent", Block.Header.PtrParent);
325 W.printHex("PtrEnd", Block.Header.PtrEnd);
326 W.printHex("CodeSize", Block.Header.CodeSize);
327 if (ObjDelegate) {
328 ObjDelegate->printRelocatedField("CodeOffset", Block.getRelocationOffset(),
329 Block.Header.CodeOffset, &LinkageName);
330 }
331 W.printHex("Segment", Block.Header.Segment);
332 W.printString("BlockName", Block.Name);
333 W.printString("LinkageName", LinkageName);
334}
335
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000336void CVSymbolDumperImpl::visitThunk32Sym(SymbolKind Kind, Thunk32Sym &Thunk) {
337 DictScope S(W, "Thunk32");
338 W.printNumber("Parent", Thunk.Header.Parent);
339 W.printNumber("End", Thunk.Header.End);
340 W.printNumber("Next", Thunk.Header.Next);
341 W.printNumber("Off", Thunk.Header.Off);
342 W.printNumber("Seg", Thunk.Header.Seg);
343 W.printNumber("Len", Thunk.Header.Len);
344 W.printEnum("Ordinal", Thunk.Header.Ord, makeArrayRef(ThunkOrdinalNames));
345}
346
347void CVSymbolDumperImpl::visitTrampolineSym(SymbolKind Kind,
348 TrampolineSym &Tramp) {
349 DictScope S(W, "Trampoline");
350 W.printEnum("Type", Tramp.Header.Type, makeArrayRef(TrampolineNames));
351 W.printNumber("Size", Tramp.Header.Size);
352 W.printNumber("ThunkOff", Tramp.Header.ThunkOff);
353 W.printNumber("TargetOff", Tramp.Header.TargetOff);
354 W.printNumber("ThunkSection", Tramp.Header.ThunkSection);
355 W.printNumber("TargetSection", Tramp.Header.TargetSection);
356}
357
358void CVSymbolDumperImpl::visitSectionSym(SymbolKind Kind, SectionSym &Section) {
359 DictScope S(W, "Section");
360 W.printNumber("SectionNumber", Section.Header.SectionNumber);
361 W.printNumber("Alignment", Section.Header.Alignment);
362 W.printNumber("Reserved", Section.Header.Reserved);
363 W.printNumber("Rva", Section.Header.Rva);
364 W.printNumber("Length", Section.Header.Length);
365 W.printHex("Characteristics", Section.Header.Characteristics);
366 W.printString("Name", Section.Name);
367}
368
369void CVSymbolDumperImpl::visitCoffGroupSym(SymbolKind Kind,
370 CoffGroupSym &CoffGroup) {
371 DictScope S(W, "COFF Group");
372 W.printNumber("Size", CoffGroup.Header.Size);
373 W.printHex("Characteristics", CoffGroup.Header.Characteristics);
374 W.printNumber("Offset", CoffGroup.Header.Offset);
375 W.printNumber("Segment", CoffGroup.Header.Segment);
376 W.printString("Name", CoffGroup.Name);
377}
378
Zachary Turneraaad5742016-05-23 23:41:13 +0000379void CVSymbolDumperImpl::visitBPRelativeSym(SymbolKind Kind,
380 BPRelativeSym &BPRel) {
381 DictScope S(W, "BPRelativeSym");
382
383 W.printNumber("Offset", BPRel.Header.Offset);
384 CVTD.printTypeIndex("Type", BPRel.Header.Type);
385 W.printString("VarName", BPRel.Name);
386}
387
388void CVSymbolDumperImpl::visitBuildInfoSym(SymbolKind Kind,
389 BuildInfoSym &BuildInfo) {
390 DictScope S(W, "BuildInfo");
391
392 W.printNumber("BuildId", BuildInfo.Header.BuildId);
393}
394
395void CVSymbolDumperImpl::visitCallSiteInfoSym(SymbolKind Kind,
396 CallSiteInfoSym &CallSiteInfo) {
397 DictScope S(W, "CallSiteInfo");
398
399 StringRef LinkageName;
400 if (ObjDelegate) {
401 ObjDelegate->printRelocatedField(
402 "CodeOffset", CallSiteInfo.getRelocationOffset(),
403 CallSiteInfo.Header.CodeOffset, &LinkageName);
404 }
405 W.printHex("Segment", CallSiteInfo.Header.Segment);
406 W.printHex("Reserved", CallSiteInfo.Header.Reserved);
407 CVTD.printTypeIndex("Type", CallSiteInfo.Header.Type);
408 if (!LinkageName.empty())
409 W.printString("LinkageName", LinkageName);
410}
411
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000412void CVSymbolDumperImpl::visitEnvBlockSym(SymbolKind Kind,
413 EnvBlockSym &EnvBlock) {
414 DictScope S(W, "EnvBlock");
415
416 W.printNumber("Reserved", EnvBlock.Header.Reserved);
417 ListScope L(W, "Entries");
418 for (auto Entry : EnvBlock.Fields) {
419 W.printString(Entry);
420 }
421}
422
423void CVSymbolDumperImpl::visitFileStaticSym(SymbolKind Kind,
424 FileStaticSym &FileStatic) {
425 DictScope S(W, "FileStatic");
426 W.printNumber("Index", FileStatic.Header.Index);
427 W.printNumber("ModFilenameOffset", FileStatic.Header.ModFilenameOffset);
428 W.printFlags("Flags", uint16_t(FileStatic.Header.Flags),
429 makeArrayRef(LocalFlags));
430 W.printString("Name", FileStatic.Name);
431}
432
433void CVSymbolDumperImpl::visitCompile2Sym(SymbolKind Kind,
434 Compile2Sym &Compile2) {
435 DictScope S(W, "CompilerFlags2");
436
437 W.printEnum("Language", Compile2.Header.getLanguage(),
438 makeArrayRef(SourceLanguages));
439 W.printFlags("Flags", Compile2.Header.flags & ~0xff,
440 makeArrayRef(CompileSym2FlagNames));
441 W.printEnum("Machine", unsigned(Compile2.Header.Machine),
442 makeArrayRef(CPUTypeNames));
443 std::string FrontendVersion;
444 {
445 raw_string_ostream Out(FrontendVersion);
446 Out << Compile2.Header.VersionFrontendMajor << '.'
447 << Compile2.Header.VersionFrontendMinor << '.'
448 << Compile2.Header.VersionFrontendBuild;
449 }
450 std::string BackendVersion;
451 {
452 raw_string_ostream Out(BackendVersion);
453 Out << Compile2.Header.VersionBackendMajor << '.'
454 << Compile2.Header.VersionBackendMinor << '.'
455 << Compile2.Header.VersionBackendBuild;
456 }
457 W.printString("FrontendVersion", FrontendVersion);
458 W.printString("BackendVersion", BackendVersion);
459 W.printString("VersionName", Compile2.Version);
460}
461
Zachary Turneraaad5742016-05-23 23:41:13 +0000462void CVSymbolDumperImpl::visitCompile3Sym(SymbolKind Kind,
463 Compile3Sym &Compile3) {
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000464 DictScope S(W, "CompilerFlags3");
Zachary Turneraaad5742016-05-23 23:41:13 +0000465
466 W.printEnum("Language", Compile3.Header.getLanguage(),
467 makeArrayRef(SourceLanguages));
468 W.printFlags("Flags", Compile3.Header.flags & ~0xff,
469 makeArrayRef(CompileSym3FlagNames));
470 W.printEnum("Machine", unsigned(Compile3.Header.Machine),
471 makeArrayRef(CPUTypeNames));
472 std::string FrontendVersion;
473 {
474 raw_string_ostream Out(FrontendVersion);
475 Out << Compile3.Header.VersionFrontendMajor << '.'
476 << Compile3.Header.VersionFrontendMinor << '.'
477 << Compile3.Header.VersionFrontendBuild << '.'
478 << Compile3.Header.VersionFrontendQFE;
479 }
480 std::string BackendVersion;
481 {
482 raw_string_ostream Out(BackendVersion);
483 Out << Compile3.Header.VersionBackendMajor << '.'
484 << Compile3.Header.VersionBackendMinor << '.'
485 << Compile3.Header.VersionBackendBuild << '.'
486 << Compile3.Header.VersionBackendQFE;
487 }
488 W.printString("FrontendVersion", FrontendVersion);
489 W.printString("BackendVersion", BackendVersion);
490 W.printString("VersionName", Compile3.Version);
491}
492
493void CVSymbolDumperImpl::visitConstantSym(SymbolKind Kind,
494 ConstantSym &Constant) {
495 DictScope S(W, "Constant");
496
497 CVTD.printTypeIndex("Type", Constant.Header.Type);
498 W.printNumber("Value", Constant.Value);
499 W.printString("Name", Constant.Name);
500}
501
502void CVSymbolDumperImpl::visitDataSym(SymbolKind Kind, DataSym &Data) {
503 DictScope S(W, "DataSym");
504
505 StringRef LinkageName;
506 if (ObjDelegate) {
507 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
508 Data.Header.DataOffset, &LinkageName);
509 }
510 CVTD.printTypeIndex("Type", Data.Header.Type);
511 W.printString("DisplayName", Data.Name);
512 if (!LinkageName.empty())
513 W.printString("LinkageName", LinkageName);
514}
515
516void CVSymbolDumperImpl::visitDefRangeFramePointerRelFullScopeSym(
517 SymbolKind Kind,
518 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
519 DictScope S(W, "DefRangeFramePointerRelFullScope");
520 W.printNumber("Offset", DefRangeFramePointerRelFullScope.Header.Offset);
521}
522
523void CVSymbolDumperImpl::visitDefRangeFramePointerRelSym(
524 SymbolKind Kind, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
525 DictScope S(W, "DefRangeFramePointerRel");
526
527 W.printNumber("Offset", DefRangeFramePointerRel.Header.Offset);
528 printLocalVariableAddrRange(DefRangeFramePointerRel.Header.Range,
529 DefRangeFramePointerRel.getRelocationOffset());
530 printLocalVariableAddrGap(DefRangeFramePointerRel.Gaps);
531}
532
533void CVSymbolDumperImpl::visitDefRangeRegisterRelSym(
534 SymbolKind Kind, DefRangeRegisterRelSym &DefRangeRegisterRel) {
535 DictScope S(W, "DefRangeRegisterRel");
536
537 W.printNumber("BaseRegister", DefRangeRegisterRel.Header.BaseRegister);
538 W.printBoolean("HasSpilledUDTMember",
539 DefRangeRegisterRel.hasSpilledUDTMember());
540 W.printNumber("OffsetInParent", DefRangeRegisterRel.offsetInParent());
541 W.printNumber("BasePointerOffset",
542 DefRangeRegisterRel.Header.BasePointerOffset);
543 printLocalVariableAddrRange(DefRangeRegisterRel.Header.Range,
544 DefRangeRegisterRel.getRelocationOffset());
545 printLocalVariableAddrGap(DefRangeRegisterRel.Gaps);
546}
547
548void CVSymbolDumperImpl::visitDefRangeRegisterSym(
549 SymbolKind Kind, DefRangeRegisterSym &DefRangeRegister) {
550 DictScope S(W, "DefRangeRegister");
551
552 W.printNumber("Register", DefRangeRegister.Header.Register);
553 W.printNumber("MayHaveNoName", DefRangeRegister.Header.MayHaveNoName);
554 printLocalVariableAddrRange(DefRangeRegister.Header.Range,
555 DefRangeRegister.getRelocationOffset());
556 printLocalVariableAddrGap(DefRangeRegister.Gaps);
557}
558
559void CVSymbolDumperImpl::visitDefRangeSubfieldRegisterSym(
560 SymbolKind Kind, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
561 DictScope S(W, "DefRangeSubfieldRegister");
562
563 W.printNumber("Register", DefRangeSubfieldRegister.Header.Register);
564 W.printNumber("MayHaveNoName", DefRangeSubfieldRegister.Header.MayHaveNoName);
565 W.printNumber("OffsetInParent",
566 DefRangeSubfieldRegister.Header.OffsetInParent);
567 printLocalVariableAddrRange(DefRangeSubfieldRegister.Header.Range,
568 DefRangeSubfieldRegister.getRelocationOffset());
569 printLocalVariableAddrGap(DefRangeSubfieldRegister.Gaps);
570}
571
572void CVSymbolDumperImpl::visitDefRangeSubfieldSym(
573 SymbolKind Kind, DefRangeSubfieldSym &DefRangeSubfield) {
574 DictScope S(W, "DefRangeSubfield");
575
576 if (ObjDelegate) {
577 StringRef StringTable = ObjDelegate->getStringTable();
578 if (!StringTable.empty()) {
579 W.printString("Program",
580 StringTable.drop_front(DefRangeSubfield.Header.Program)
581 .split('\0')
582 .first);
583 }
584 }
585 W.printNumber("OffsetInParent", DefRangeSubfield.Header.OffsetInParent);
586 printLocalVariableAddrRange(DefRangeSubfield.Header.Range,
587 DefRangeSubfield.getRelocationOffset());
588 printLocalVariableAddrGap(DefRangeSubfield.Gaps);
589}
590
591void CVSymbolDumperImpl::visitDefRangeSym(SymbolKind Kind,
592 DefRangeSym &DefRange) {
593 DictScope S(W, "DefRange");
594
595 if (ObjDelegate) {
596 StringRef StringTable = ObjDelegate->getStringTable();
597 if (!StringTable.empty()) {
598 W.printString(
599 "Program",
600 StringTable.drop_front(DefRange.Header.Program).split('\0').first);
601 }
602 }
603 printLocalVariableAddrRange(DefRange.Header.Range,
604 DefRange.getRelocationOffset());
605 printLocalVariableAddrGap(DefRange.Gaps);
606}
607
608void CVSymbolDumperImpl::visitFrameCookieSym(SymbolKind Kind,
609 FrameCookieSym &FrameCookie) {
610 DictScope S(W, "FrameCookie");
611
612 StringRef LinkageName;
613 if (ObjDelegate) {
614 ObjDelegate->printRelocatedField(
615 "CodeOffset", FrameCookie.getRelocationOffset(),
616 FrameCookie.Header.CodeOffset, &LinkageName);
617 }
618 W.printHex("Register", FrameCookie.Header.Register);
619 W.printEnum("CookieKind", uint16_t(FrameCookie.Header.CookieKind),
620 makeArrayRef(FrameCookieKinds));
621}
622
623void CVSymbolDumperImpl::visitFrameProcSym(SymbolKind Kind,
624 FrameProcSym &FrameProc) {
625 DictScope S(W, "FrameProc");
626
627 W.printHex("TotalFrameBytes", FrameProc.Header.TotalFrameBytes);
628 W.printHex("PaddingFrameBytes", FrameProc.Header.PaddingFrameBytes);
629 W.printHex("OffsetToPadding", FrameProc.Header.OffsetToPadding);
630 W.printHex("BytesOfCalleeSavedRegisters",
631 FrameProc.Header.BytesOfCalleeSavedRegisters);
632 W.printHex("OffsetOfExceptionHandler",
633 FrameProc.Header.OffsetOfExceptionHandler);
634 W.printHex("SectionIdOfExceptionHandler",
635 FrameProc.Header.SectionIdOfExceptionHandler);
636 W.printFlags("Flags", FrameProc.Header.Flags,
637 makeArrayRef(FrameProcSymFlags));
638}
639
640void CVSymbolDumperImpl::visitHeapAllocationSiteSym(
641 SymbolKind Kind, HeapAllocationSiteSym &HeapAllocSite) {
642 DictScope S(W, "HeapAllocationSite");
643
644 StringRef LinkageName;
645 if (ObjDelegate) {
646 ObjDelegate->printRelocatedField(
647 "CodeOffset", HeapAllocSite.getRelocationOffset(),
648 HeapAllocSite.Header.CodeOffset, &LinkageName);
649 }
650 W.printHex("Segment", HeapAllocSite.Header.Segment);
651 W.printHex("CallInstructionSize", HeapAllocSite.Header.CallInstructionSize);
652 CVTD.printTypeIndex("Type", HeapAllocSite.Header.Type);
653 if (!LinkageName.empty())
654 W.printString("LinkageName", LinkageName);
655}
656
657void CVSymbolDumperImpl::visitInlineSiteSym(SymbolKind Kind,
658 InlineSiteSym &InlineSite) {
659 DictScope S(W, "InlineSite");
660
661 W.printHex("PtrParent", InlineSite.Header.PtrParent);
662 W.printHex("PtrEnd", InlineSite.Header.PtrEnd);
663 CVTD.printTypeIndex("Inlinee", InlineSite.Header.Inlinee);
664
665 ListScope BinaryAnnotations(W, "BinaryAnnotations");
666 for (auto &Annotation : InlineSite.annotations()) {
667 switch (Annotation.OpCode) {
668 case BinaryAnnotationsOpCode::Invalid:
669 return parseError();
670 case BinaryAnnotationsOpCode::CodeOffset:
671 case BinaryAnnotationsOpCode::ChangeCodeOffset:
672 case BinaryAnnotationsOpCode::ChangeCodeLength:
673 W.printHex(Annotation.Name, Annotation.U1);
674 break;
675 case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
676 case BinaryAnnotationsOpCode::ChangeLineEndDelta:
677 case BinaryAnnotationsOpCode::ChangeRangeKind:
678 case BinaryAnnotationsOpCode::ChangeColumnStart:
679 case BinaryAnnotationsOpCode::ChangeColumnEnd:
680 W.printNumber(Annotation.Name, Annotation.U1);
681 break;
682 case BinaryAnnotationsOpCode::ChangeLineOffset:
683 case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
684 W.printNumber(Annotation.Name, Annotation.S1);
685 break;
686 case BinaryAnnotationsOpCode::ChangeFile:
687 if (ObjDelegate) {
688 W.printHex("ChangeFile",
689 ObjDelegate->getFileNameForFileOffset(Annotation.U1),
690 Annotation.U1);
691 } else {
692 W.printHex("ChangeFile", Annotation.U1);
693 }
694
695 break;
696 case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
697 W.startLine() << "ChangeCodeOffsetAndLineOffset: {CodeOffset: "
698 << W.hex(Annotation.U1) << ", LineOffset: " << Annotation.S1
699 << "}\n";
700 break;
701 }
702 case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
703 W.startLine() << "ChangeCodeLengthAndCodeOffset: {CodeOffset: "
704 << W.hex(Annotation.U2)
705 << ", Length: " << W.hex(Annotation.U1) << "}\n";
706 break;
707 }
708 }
709 }
710}
711
Zachary Turner4caa1bf2016-05-24 22:58:46 +0000712void CVSymbolDumperImpl::visitRegisterSym(SymbolKind Kind,
713 RegisterSym &Register) {
714 DictScope S(W, "RegisterSym");
715 W.printNumber("Type", Register.Header.Index);
716 W.printEnum("Seg", uint16_t(Register.Header.Register),
717 makeArrayRef(RegisterNames));
718 W.printString("Name", Register.Name);
719}
720
Zachary Turner9e33e6f2016-05-24 18:55:14 +0000721void CVSymbolDumperImpl::visitPublicSym32(SymbolKind Kind,
722 PublicSym32 &Public) {
723 DictScope S(W, "PublicSym");
724 W.printNumber("Type", Public.Header.Index);
725 W.printNumber("Seg", Public.Header.Seg);
726 W.printNumber("Off", Public.Header.Off);
727 W.printString("Name", Public.Name);
728}
729
730void CVSymbolDumperImpl::visitProcRefSym(SymbolKind Kind, ProcRefSym &ProcRef) {
731 DictScope S(W, "ProcRef");
732 W.printNumber("SumName", ProcRef.Header.SumName);
733 W.printNumber("SymOffset", ProcRef.Header.SymOffset);
734 W.printNumber("Mod", ProcRef.Header.Mod);
735 W.printString("Name", ProcRef.Name);
736}
737
Zachary Turneraaad5742016-05-23 23:41:13 +0000738void CVSymbolDumperImpl::visitLabelSym(SymbolKind Kind, LabelSym &Label) {
739 DictScope S(W, "Label");
740
741 StringRef LinkageName;
742 if (ObjDelegate) {
743 ObjDelegate->printRelocatedField("CodeOffset", Label.getRelocationOffset(),
744 Label.Header.CodeOffset, &LinkageName);
745 }
746 W.printHex("Segment", Label.Header.Segment);
747 W.printHex("Flags", Label.Header.Flags);
748 W.printFlags("Flags", Label.Header.Flags, makeArrayRef(ProcSymFlagNames));
749 W.printString("DisplayName", Label.Name);
750 if (!LinkageName.empty())
751 W.printString("LinkageName", LinkageName);
752}
753
754void CVSymbolDumperImpl::visitLocalSym(SymbolKind Kind, LocalSym &Local) {
755 DictScope S(W, "Local");
756
757 CVTD.printTypeIndex("Type", Local.Header.Type);
758 W.printFlags("Flags", uint16_t(Local.Header.Flags), makeArrayRef(LocalFlags));
759 W.printString("VarName", Local.Name);
760}
761
762void CVSymbolDumperImpl::visitObjNameSym(SymbolKind Kind, ObjNameSym &ObjName) {
763 DictScope S(W, "ObjectName");
764
765 W.printHex("Signature", ObjName.Header.Signature);
766 W.printString("ObjectName", ObjName.Name);
767}
768
769void CVSymbolDumperImpl::visitProcSym(SymbolKind Kind, ProcSym &Proc) {
770 DictScope S(W, "ProcStart");
771
772 if (InFunctionScope)
773 return parseError();
774
775 InFunctionScope = true;
776
777 StringRef LinkageName;
778 W.printHex("PtrParent", Proc.Header.PtrParent);
779 W.printHex("PtrEnd", Proc.Header.PtrEnd);
780 W.printHex("PtrNext", Proc.Header.PtrNext);
781 W.printHex("CodeSize", Proc.Header.CodeSize);
782 W.printHex("DbgStart", Proc.Header.DbgStart);
783 W.printHex("DbgEnd", Proc.Header.DbgEnd);
784 CVTD.printTypeIndex("FunctionType", Proc.Header.FunctionType);
785 if (ObjDelegate) {
786 ObjDelegate->printRelocatedField("CodeOffset", Proc.getRelocationOffset(),
787 Proc.Header.CodeOffset, &LinkageName);
788 }
789 W.printHex("Segment", Proc.Header.Segment);
790 W.printFlags("Flags", static_cast<uint8_t>(Proc.Header.Flags),
791 makeArrayRef(ProcSymFlagNames));
792 W.printString("DisplayName", Proc.Name);
793 if (!LinkageName.empty())
794 W.printString("LinkageName", LinkageName);
795}
796
797void CVSymbolDumperImpl::visitScopeEndSym(SymbolKind Kind,
798 ScopeEndSym &ScopeEnd) {
799 if (Kind == SymbolKind::S_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000800 DictScope S(W, "BlockEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000801 else if (Kind == SymbolKind::S_PROC_ID_END)
Zachary Turnercac29ae2016-05-24 17:30:25 +0000802 DictScope S(W, "ProcEnd");
Zachary Turneraaad5742016-05-23 23:41:13 +0000803 else if (Kind == SymbolKind::S_INLINESITE_END)
804 DictScope S(W, "InlineSiteEnd");
805
806 InFunctionScope = false;
807}
808
809void CVSymbolDumperImpl::visitCallerSym(SymbolKind Kind, CallerSym &Caller) {
810 ListScope S(W, Kind == S_CALLEES ? "Callees" : "Callers");
811 for (auto FuncID : Caller.Indices)
812 CVTD.printTypeIndex("FuncID", FuncID);
813}
814
815void CVSymbolDumperImpl::visitRegRelativeSym(SymbolKind Kind,
816 RegRelativeSym &RegRel) {
817 DictScope S(W, "RegRelativeSym");
818
819 W.printHex("Offset", RegRel.Header.Offset);
820 CVTD.printTypeIndex("Type", RegRel.Header.Type);
821 W.printHex("Register", RegRel.Header.Register);
822 W.printString("VarName", RegRel.Name);
823}
824
825void CVSymbolDumperImpl::visitThreadLocalDataSym(SymbolKind Kind,
826 ThreadLocalDataSym &Data) {
827 DictScope S(W, "ThreadLocalDataSym");
828
829 StringRef LinkageName;
830 if (ObjDelegate) {
831 ObjDelegate->printRelocatedField("DataOffset", Data.getRelocationOffset(),
832 Data.Header.DataOffset, &LinkageName);
833 }
834 CVTD.printTypeIndex("Type", Data.Header.Type);
835 W.printString("DisplayName", Data.Name);
836 if (!LinkageName.empty())
837 W.printString("LinkageName", LinkageName);
838}
839
840void CVSymbolDumperImpl::visitUDTSym(SymbolKind Kind, UDTSym &UDT) {
841 DictScope S(W, "UDT");
842 CVTD.printTypeIndex("Type", UDT.Header.Type);
843 W.printString("UDTName", UDT.Name);
844}
845
846void CVSymbolDumperImpl::visitUnknownSymbol(SymbolKind Kind,
847 ArrayRef<uint8_t> Data) {
848 DictScope S(W, "UnknownSym");
Zachary Turner00d847b2016-05-24 17:44:29 +0000849 W.printEnum("Kind", uint16_t(Kind), makeArrayRef(SymbolTypeNames));
850 W.printNumber("Length", uint32_t(Data.size()));
Zachary Turneraaad5742016-05-23 23:41:13 +0000851}
852
853bool CVSymbolDumper::dump(const SymbolIterator::Record &Record) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000854 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turneraaad5742016-05-23 23:41:13 +0000855 Dumper.visitSymbolRecord(Record);
856 return !Dumper.hadError();
857}
858
859bool CVSymbolDumper::dump(ArrayRef<uint8_t> Data) {
Zachary Turner3e78e2d2016-05-24 00:06:04 +0000860 CVSymbolDumperImpl Dumper(CVTD, ObjDelegate.get(), W, PrintRecordBytes);
Zachary Turneraaad5742016-05-23 23:41:13 +0000861 Dumper.visitSymbolStream(Data);
862 return !Dumper.hadError();
863}