Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/llvm/tools/llvm-pdbutil/MinimalSymbolDumper.cpp
35260 views
1
//===- MinimalSymbolDumper.cpp -------------------------------- *- C++ --*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "MinimalSymbolDumper.h"
10
11
#include "llvm/ADT/StringExtras.h"
12
#include "llvm/DebugInfo/CodeView/CVRecord.h"
13
#include "llvm/DebugInfo/CodeView/CodeView.h"
14
#include "llvm/DebugInfo/CodeView/Formatters.h"
15
#include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
16
#include "llvm/DebugInfo/CodeView/SymbolRecord.h"
17
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
18
#include "llvm/DebugInfo/PDB/Native/FormatUtil.h"
19
#include "llvm/DebugInfo/PDB/Native/InputFile.h"
20
#include "llvm/DebugInfo/PDB/Native/LinePrinter.h"
21
#include "llvm/DebugInfo/PDB/Native/NativeSession.h"
22
#include "llvm/DebugInfo/PDB/Native/PDBFile.h"
23
#include "llvm/DebugInfo/PDB/Native/PDBStringTable.h"
24
#include "llvm/Object/COFF.h"
25
#include "llvm/Support/FormatVariadic.h"
26
27
using namespace llvm;
28
using namespace llvm::codeview;
29
using namespace llvm::pdb;
30
31
static std::string formatLocalSymFlags(uint32_t IndentLevel,
32
LocalSymFlags Flags) {
33
std::vector<std::string> Opts;
34
if (Flags == LocalSymFlags::None)
35
return "none";
36
37
PUSH_FLAG(LocalSymFlags, IsParameter, Flags, "param");
38
PUSH_FLAG(LocalSymFlags, IsAddressTaken, Flags, "address is taken");
39
PUSH_FLAG(LocalSymFlags, IsCompilerGenerated, Flags, "compiler generated");
40
PUSH_FLAG(LocalSymFlags, IsAggregate, Flags, "aggregate");
41
PUSH_FLAG(LocalSymFlags, IsAggregated, Flags, "aggregated");
42
PUSH_FLAG(LocalSymFlags, IsAliased, Flags, "aliased");
43
PUSH_FLAG(LocalSymFlags, IsAlias, Flags, "alias");
44
PUSH_FLAG(LocalSymFlags, IsReturnValue, Flags, "return val");
45
PUSH_FLAG(LocalSymFlags, IsOptimizedOut, Flags, "optimized away");
46
PUSH_FLAG(LocalSymFlags, IsEnregisteredGlobal, Flags, "enreg global");
47
PUSH_FLAG(LocalSymFlags, IsEnregisteredStatic, Flags, "enreg static");
48
return typesetItemList(Opts, 4, IndentLevel, " | ");
49
}
50
51
static std::string formatExportFlags(uint32_t IndentLevel, ExportFlags Flags) {
52
std::vector<std::string> Opts;
53
if (Flags == ExportFlags::None)
54
return "none";
55
56
PUSH_FLAG(ExportFlags, IsConstant, Flags, "constant");
57
PUSH_FLAG(ExportFlags, IsData, Flags, "data");
58
PUSH_FLAG(ExportFlags, IsPrivate, Flags, "private");
59
PUSH_FLAG(ExportFlags, HasNoName, Flags, "no name");
60
PUSH_FLAG(ExportFlags, HasExplicitOrdinal, Flags, "explicit ord");
61
PUSH_FLAG(ExportFlags, IsForwarder, Flags, "forwarder");
62
63
return typesetItemList(Opts, 4, IndentLevel, " | ");
64
}
65
66
static std::string formatCompileSym2Flags(uint32_t IndentLevel,
67
CompileSym2Flags Flags) {
68
std::vector<std::string> Opts;
69
Flags &= ~CompileSym2Flags::SourceLanguageMask;
70
if (Flags == CompileSym2Flags::None)
71
return "none";
72
73
PUSH_FLAG(CompileSym2Flags, EC, Flags, "edit and continue");
74
PUSH_FLAG(CompileSym2Flags, NoDbgInfo, Flags, "no dbg info");
75
PUSH_FLAG(CompileSym2Flags, LTCG, Flags, "ltcg");
76
PUSH_FLAG(CompileSym2Flags, NoDataAlign, Flags, "no data align");
77
PUSH_FLAG(CompileSym2Flags, ManagedPresent, Flags, "has managed code");
78
PUSH_FLAG(CompileSym2Flags, SecurityChecks, Flags, "security checks");
79
PUSH_FLAG(CompileSym2Flags, HotPatch, Flags, "hot patchable");
80
PUSH_FLAG(CompileSym2Flags, CVTCIL, Flags, "cvtcil");
81
PUSH_FLAG(CompileSym2Flags, MSILModule, Flags, "msil module");
82
return typesetItemList(Opts, 4, IndentLevel, " | ");
83
}
84
85
static std::string formatCompileSym3Flags(uint32_t IndentLevel,
86
CompileSym3Flags Flags) {
87
std::vector<std::string> Opts;
88
Flags &= ~CompileSym3Flags::SourceLanguageMask;
89
90
if (Flags == CompileSym3Flags::None)
91
return "none";
92
93
PUSH_FLAG(CompileSym3Flags, EC, Flags, "edit and continue");
94
PUSH_FLAG(CompileSym3Flags, NoDbgInfo, Flags, "no dbg info");
95
PUSH_FLAG(CompileSym3Flags, LTCG, Flags, "ltcg");
96
PUSH_FLAG(CompileSym3Flags, NoDataAlign, Flags, "no data align");
97
PUSH_FLAG(CompileSym3Flags, ManagedPresent, Flags, "has managed code");
98
PUSH_FLAG(CompileSym3Flags, SecurityChecks, Flags, "security checks");
99
PUSH_FLAG(CompileSym3Flags, HotPatch, Flags, "hot patchable");
100
PUSH_FLAG(CompileSym3Flags, CVTCIL, Flags, "cvtcil");
101
PUSH_FLAG(CompileSym3Flags, MSILModule, Flags, "msil module");
102
PUSH_FLAG(CompileSym3Flags, Sdl, Flags, "sdl");
103
PUSH_FLAG(CompileSym3Flags, PGO, Flags, "pgo");
104
PUSH_FLAG(CompileSym3Flags, Exp, Flags, "exp");
105
return typesetItemList(Opts, 4, IndentLevel, " | ");
106
}
107
108
static std::string formatFrameProcedureOptions(uint32_t IndentLevel,
109
FrameProcedureOptions FPO) {
110
std::vector<std::string> Opts;
111
if (FPO == FrameProcedureOptions::None)
112
return "none";
113
114
PUSH_FLAG(FrameProcedureOptions, HasAlloca, FPO, "has alloca");
115
PUSH_FLAG(FrameProcedureOptions, HasSetJmp, FPO, "has setjmp");
116
PUSH_FLAG(FrameProcedureOptions, HasLongJmp, FPO, "has longjmp");
117
PUSH_FLAG(FrameProcedureOptions, HasInlineAssembly, FPO, "has inline asm");
118
PUSH_FLAG(FrameProcedureOptions, HasExceptionHandling, FPO, "has eh");
119
PUSH_FLAG(FrameProcedureOptions, MarkedInline, FPO, "marked inline");
120
PUSH_FLAG(FrameProcedureOptions, HasStructuredExceptionHandling, FPO,
121
"has seh");
122
PUSH_FLAG(FrameProcedureOptions, Naked, FPO, "naked");
123
PUSH_FLAG(FrameProcedureOptions, SecurityChecks, FPO, "secure checks");
124
PUSH_FLAG(FrameProcedureOptions, AsynchronousExceptionHandling, FPO,
125
"has async eh");
126
PUSH_FLAG(FrameProcedureOptions, NoStackOrderingForSecurityChecks, FPO,
127
"no stack order");
128
PUSH_FLAG(FrameProcedureOptions, Inlined, FPO, "inlined");
129
PUSH_FLAG(FrameProcedureOptions, StrictSecurityChecks, FPO,
130
"strict secure checks");
131
PUSH_FLAG(FrameProcedureOptions, SafeBuffers, FPO, "safe buffers");
132
PUSH_FLAG(FrameProcedureOptions, ProfileGuidedOptimization, FPO, "pgo");
133
PUSH_FLAG(FrameProcedureOptions, ValidProfileCounts, FPO,
134
"has profile counts");
135
PUSH_FLAG(FrameProcedureOptions, OptimizedForSpeed, FPO, "opt speed");
136
PUSH_FLAG(FrameProcedureOptions, GuardCfg, FPO, "guard cfg");
137
PUSH_FLAG(FrameProcedureOptions, GuardCfw, FPO, "guard cfw");
138
return typesetItemList(Opts, 4, IndentLevel, " | ");
139
}
140
141
static std::string formatPublicSymFlags(uint32_t IndentLevel,
142
PublicSymFlags Flags) {
143
std::vector<std::string> Opts;
144
if (Flags == PublicSymFlags::None)
145
return "none";
146
147
PUSH_FLAG(PublicSymFlags, Code, Flags, "code");
148
PUSH_FLAG(PublicSymFlags, Function, Flags, "function");
149
PUSH_FLAG(PublicSymFlags, Managed, Flags, "managed");
150
PUSH_FLAG(PublicSymFlags, MSIL, Flags, "msil");
151
return typesetItemList(Opts, 4, IndentLevel, " | ");
152
}
153
154
static std::string formatProcSymFlags(uint32_t IndentLevel,
155
ProcSymFlags Flags) {
156
std::vector<std::string> Opts;
157
if (Flags == ProcSymFlags::None)
158
return "none";
159
160
PUSH_FLAG(ProcSymFlags, HasFP, Flags, "has fp");
161
PUSH_FLAG(ProcSymFlags, HasIRET, Flags, "has iret");
162
PUSH_FLAG(ProcSymFlags, HasFRET, Flags, "has fret");
163
PUSH_FLAG(ProcSymFlags, IsNoReturn, Flags, "noreturn");
164
PUSH_FLAG(ProcSymFlags, IsUnreachable, Flags, "unreachable");
165
PUSH_FLAG(ProcSymFlags, HasCustomCallingConv, Flags, "custom calling conv");
166
PUSH_FLAG(ProcSymFlags, IsNoInline, Flags, "noinline");
167
PUSH_FLAG(ProcSymFlags, HasOptimizedDebugInfo, Flags, "opt debuginfo");
168
return typesetItemList(Opts, 4, IndentLevel, " | ");
169
}
170
171
static std::string formatThunkOrdinal(ThunkOrdinal Ordinal) {
172
switch (Ordinal) {
173
RETURN_CASE(ThunkOrdinal, Standard, "thunk");
174
RETURN_CASE(ThunkOrdinal, ThisAdjustor, "this adjustor");
175
RETURN_CASE(ThunkOrdinal, Vcall, "vcall");
176
RETURN_CASE(ThunkOrdinal, Pcode, "pcode");
177
RETURN_CASE(ThunkOrdinal, UnknownLoad, "unknown load");
178
RETURN_CASE(ThunkOrdinal, TrampIncremental, "tramp incremental");
179
RETURN_CASE(ThunkOrdinal, BranchIsland, "branch island");
180
}
181
return formatUnknownEnum(Ordinal);
182
}
183
184
static std::string formatTrampolineType(TrampolineType Tramp) {
185
switch (Tramp) {
186
RETURN_CASE(TrampolineType, TrampIncremental, "tramp incremental");
187
RETURN_CASE(TrampolineType, BranchIsland, "branch island");
188
}
189
return formatUnknownEnum(Tramp);
190
}
191
192
static std::string formatSourceLanguage(SourceLanguage Lang) {
193
switch (Lang) {
194
RETURN_CASE(SourceLanguage, C, "c");
195
RETURN_CASE(SourceLanguage, Cpp, "c++");
196
RETURN_CASE(SourceLanguage, Fortran, "fortran");
197
RETURN_CASE(SourceLanguage, Masm, "masm");
198
RETURN_CASE(SourceLanguage, Pascal, "pascal");
199
RETURN_CASE(SourceLanguage, Basic, "basic");
200
RETURN_CASE(SourceLanguage, Cobol, "cobol");
201
RETURN_CASE(SourceLanguage, Link, "link");
202
RETURN_CASE(SourceLanguage, VB, "vb");
203
RETURN_CASE(SourceLanguage, Cvtres, "cvtres");
204
RETURN_CASE(SourceLanguage, Cvtpgd, "cvtpgd");
205
RETURN_CASE(SourceLanguage, CSharp, "c#");
206
RETURN_CASE(SourceLanguage, ILAsm, "il asm");
207
RETURN_CASE(SourceLanguage, Java, "java");
208
RETURN_CASE(SourceLanguage, JScript, "javascript");
209
RETURN_CASE(SourceLanguage, MSIL, "msil");
210
RETURN_CASE(SourceLanguage, HLSL, "hlsl");
211
RETURN_CASE(SourceLanguage, D, "d");
212
RETURN_CASE(SourceLanguage, Swift, "swift");
213
RETURN_CASE(SourceLanguage, Rust, "rust");
214
RETURN_CASE(SourceLanguage, ObjC, "objc");
215
RETURN_CASE(SourceLanguage, ObjCpp, "objc++");
216
RETURN_CASE(SourceLanguage, AliasObj, "aliasobj");
217
RETURN_CASE(SourceLanguage, Go, "go");
218
RETURN_CASE(SourceLanguage, OldSwift, "swift");
219
}
220
return formatUnknownEnum(Lang);
221
}
222
223
static std::string formatMachineType(CPUType Cpu) {
224
switch (Cpu) {
225
RETURN_CASE(CPUType, Intel8080, "intel 8080");
226
RETURN_CASE(CPUType, Intel8086, "intel 8086");
227
RETURN_CASE(CPUType, Intel80286, "intel 80286");
228
RETURN_CASE(CPUType, Intel80386, "intel 80386");
229
RETURN_CASE(CPUType, Intel80486, "intel 80486");
230
RETURN_CASE(CPUType, Pentium, "intel pentium");
231
RETURN_CASE(CPUType, PentiumPro, "intel pentium pro");
232
RETURN_CASE(CPUType, Pentium3, "intel pentium 3");
233
RETURN_CASE(CPUType, MIPS, "mips");
234
RETURN_CASE(CPUType, MIPS16, "mips-16");
235
RETURN_CASE(CPUType, MIPS32, "mips-32");
236
RETURN_CASE(CPUType, MIPS64, "mips-64");
237
RETURN_CASE(CPUType, MIPSI, "mips i");
238
RETURN_CASE(CPUType, MIPSII, "mips ii");
239
RETURN_CASE(CPUType, MIPSIII, "mips iii");
240
RETURN_CASE(CPUType, MIPSIV, "mips iv");
241
RETURN_CASE(CPUType, MIPSV, "mips v");
242
RETURN_CASE(CPUType, M68000, "motorola 68000");
243
RETURN_CASE(CPUType, M68010, "motorola 68010");
244
RETURN_CASE(CPUType, M68020, "motorola 68020");
245
RETURN_CASE(CPUType, M68030, "motorola 68030");
246
RETURN_CASE(CPUType, M68040, "motorola 68040");
247
RETURN_CASE(CPUType, Alpha, "alpha");
248
RETURN_CASE(CPUType, Alpha21164, "alpha 21164");
249
RETURN_CASE(CPUType, Alpha21164A, "alpha 21164a");
250
RETURN_CASE(CPUType, Alpha21264, "alpha 21264");
251
RETURN_CASE(CPUType, Alpha21364, "alpha 21364");
252
RETURN_CASE(CPUType, PPC601, "powerpc 601");
253
RETURN_CASE(CPUType, PPC603, "powerpc 603");
254
RETURN_CASE(CPUType, PPC604, "powerpc 604");
255
RETURN_CASE(CPUType, PPC620, "powerpc 620");
256
RETURN_CASE(CPUType, PPCFP, "powerpc fp");
257
RETURN_CASE(CPUType, PPCBE, "powerpc be");
258
RETURN_CASE(CPUType, SH3, "sh3");
259
RETURN_CASE(CPUType, SH3E, "sh3e");
260
RETURN_CASE(CPUType, SH3DSP, "sh3 dsp");
261
RETURN_CASE(CPUType, SH4, "sh4");
262
RETURN_CASE(CPUType, SHMedia, "shmedia");
263
RETURN_CASE(CPUType, ARM3, "arm 3");
264
RETURN_CASE(CPUType, ARM4, "arm 4");
265
RETURN_CASE(CPUType, ARM4T, "arm 4t");
266
RETURN_CASE(CPUType, ARM5, "arm 5");
267
RETURN_CASE(CPUType, ARM5T, "arm 5t");
268
RETURN_CASE(CPUType, ARM6, "arm 6");
269
RETURN_CASE(CPUType, ARM_XMAC, "arm xmac");
270
RETURN_CASE(CPUType, ARM_WMMX, "arm wmmx");
271
RETURN_CASE(CPUType, ARM7, "arm 7");
272
RETURN_CASE(CPUType, ARM64, "arm64");
273
RETURN_CASE(CPUType, ARM64EC, "arm64ec");
274
RETURN_CASE(CPUType, ARM64X, "arm64x");
275
RETURN_CASE(CPUType, HybridX86ARM64, "hybrid x86 arm64");
276
RETURN_CASE(CPUType, Omni, "omni");
277
RETURN_CASE(CPUType, Ia64, "intel itanium ia64");
278
RETURN_CASE(CPUType, Ia64_2, "intel itanium ia64 2");
279
RETURN_CASE(CPUType, CEE, "cee");
280
RETURN_CASE(CPUType, AM33, "am33");
281
RETURN_CASE(CPUType, M32R, "m32r");
282
RETURN_CASE(CPUType, TriCore, "tri-core");
283
RETURN_CASE(CPUType, X64, "intel x86-x64");
284
RETURN_CASE(CPUType, EBC, "ebc");
285
RETURN_CASE(CPUType, Thumb, "thumb");
286
RETURN_CASE(CPUType, ARMNT, "arm nt");
287
RETURN_CASE(CPUType, D3D11_Shader, "d3d11 shader");
288
RETURN_CASE(CPUType, Unknown, "unknown");
289
}
290
return formatUnknownEnum(Cpu);
291
}
292
293
static std::string formatCookieKind(FrameCookieKind Kind) {
294
switch (Kind) {
295
RETURN_CASE(FrameCookieKind, Copy, "copy");
296
RETURN_CASE(FrameCookieKind, XorStackPointer, "xor stack ptr");
297
RETURN_CASE(FrameCookieKind, XorFramePointer, "xor frame ptr");
298
RETURN_CASE(FrameCookieKind, XorR13, "xor rot13");
299
}
300
return formatUnknownEnum(Kind);
301
}
302
303
static std::string formatRegisterId(RegisterId Id, CPUType Cpu) {
304
if (Cpu == CPUType::ARMNT) {
305
switch (Id) {
306
#define CV_REGISTERS_ARM
307
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
308
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
309
#undef CV_REGISTER
310
#undef CV_REGISTERS_ARM
311
312
default:
313
break;
314
}
315
} else if (Cpu == CPUType::ARM64) {
316
switch (Id) {
317
#define CV_REGISTERS_ARM64
318
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
319
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
320
#undef CV_REGISTER
321
#undef CV_REGISTERS_ARM64
322
323
default:
324
break;
325
}
326
} else {
327
switch (Id) {
328
#define CV_REGISTERS_X86
329
#define CV_REGISTER(name, val) RETURN_CASE(RegisterId, name, #name)
330
#include "llvm/DebugInfo/CodeView/CodeViewRegisters.def"
331
#undef CV_REGISTER
332
#undef CV_REGISTERS_X86
333
334
default:
335
break;
336
}
337
}
338
return formatUnknownEnum(Id);
339
}
340
341
static std::string formatRegisterId(uint16_t Reg16, CPUType Cpu) {
342
return formatRegisterId(RegisterId(Reg16), Cpu);
343
}
344
345
static std::string formatRegisterId(ulittle16_t &Reg16, CPUType Cpu) {
346
return formatRegisterId(uint16_t(Reg16), Cpu);
347
}
348
349
static std::string formatRange(LocalVariableAddrRange Range) {
350
return formatv("[{0},+{1})",
351
formatSegmentOffset(Range.ISectStart, Range.OffsetStart),
352
Range.Range)
353
.str();
354
}
355
356
static std::string formatGaps(uint32_t IndentLevel,
357
ArrayRef<LocalVariableAddrGap> Gaps) {
358
std::vector<std::string> GapStrs;
359
for (const auto &G : Gaps) {
360
GapStrs.push_back(formatv("({0},{1})", G.GapStartOffset, G.Range).str());
361
}
362
return typesetItemList(GapStrs, 7, IndentLevel, ", ");
363
}
364
365
static std::string formatJumpTableEntrySize(JumpTableEntrySize EntrySize) {
366
switch (EntrySize) {
367
RETURN_CASE(JumpTableEntrySize, Int8, "int8");
368
RETURN_CASE(JumpTableEntrySize, UInt8, "uin8");
369
RETURN_CASE(JumpTableEntrySize, Int16, "int16");
370
RETURN_CASE(JumpTableEntrySize, UInt16, "uint16");
371
RETURN_CASE(JumpTableEntrySize, Int32, "int32");
372
RETURN_CASE(JumpTableEntrySize, UInt32, "uint32");
373
RETURN_CASE(JumpTableEntrySize, Pointer, "pointer");
374
RETURN_CASE(JumpTableEntrySize, UInt8ShiftLeft, "uint8shl");
375
RETURN_CASE(JumpTableEntrySize, UInt16ShiftLeft, "uint16shl");
376
RETURN_CASE(JumpTableEntrySize, Int8ShiftLeft, "int8shl");
377
RETURN_CASE(JumpTableEntrySize, Int16ShiftLeft, "int16shl");
378
}
379
return formatUnknownEnum(EntrySize);
380
}
381
382
Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record) {
383
return visitSymbolBegin(Record, 0);
384
}
385
386
Error MinimalSymbolDumper::visitSymbolBegin(codeview::CVSymbol &Record,
387
uint32_t Offset) {
388
// formatLine puts the newline at the beginning, so we use formatLine here
389
// to start a new line, and then individual visit methods use format to
390
// append to the existing line.
391
P.formatLine("{0} | {1} [size = {2}]",
392
fmt_align(Offset, AlignStyle::Right, 6),
393
formatSymbolKind(Record.kind()), Record.length());
394
P.Indent();
395
return Error::success();
396
}
397
398
Error MinimalSymbolDumper::visitSymbolEnd(CVSymbol &Record) {
399
if (RecordBytes) {
400
AutoIndent Indent(P, 7);
401
P.formatBinary("bytes", Record.content(), 0);
402
}
403
P.Unindent();
404
return Error::success();
405
}
406
407
std::string MinimalSymbolDumper::typeOrIdIndex(codeview::TypeIndex TI,
408
bool IsType) const {
409
if (TI.isSimple() || TI.isDecoratedItemId())
410
return formatv("{0}", TI).str();
411
auto &Container = IsType ? Types : Ids;
412
StringRef Name = Container.getTypeName(TI);
413
if (Name.size() > 32) {
414
Name = Name.take_front(32);
415
return std::string(formatv("{0} ({1}...)", TI, Name));
416
} else
417
return std::string(formatv("{0} ({1})", TI, Name));
418
}
419
420
std::string MinimalSymbolDumper::idIndex(codeview::TypeIndex TI) const {
421
return typeOrIdIndex(TI, false);
422
}
423
424
std::string MinimalSymbolDumper::typeIndex(TypeIndex TI) const {
425
return typeOrIdIndex(TI, true);
426
}
427
428
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
429
P.format(" `{0}`", Block.Name);
430
AutoIndent Indent(P, 7);
431
P.formatLine("parent = {0}, end = {1}", Block.Parent, Block.End);
432
P.formatLine("code size = {0}, addr = {1}", Block.CodeSize,
433
formatSegmentOffset(Block.Segment, Block.CodeOffset));
434
return Error::success();
435
}
436
437
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
438
P.format(" `{0}`", Thunk.Name);
439
AutoIndent Indent(P, 7);
440
P.formatLine("parent = {0}, end = {1}, next = {2}", Thunk.Parent, Thunk.End,
441
Thunk.Next);
442
P.formatLine("kind = {0}, size = {1}, addr = {2}",
443
formatThunkOrdinal(Thunk.Thunk), Thunk.Length,
444
formatSegmentOffset(Thunk.Segment, Thunk.Offset));
445
446
return Error::success();
447
}
448
449
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
450
TrampolineSym &Tramp) {
451
AutoIndent Indent(P, 7);
452
P.formatLine("type = {0}, size = {1}, source = {2}, target = {3}",
453
formatTrampolineType(Tramp.Type), Tramp.Size,
454
formatSegmentOffset(Tramp.ThunkSection, Tramp.ThunkOffset),
455
formatSegmentOffset(Tramp.TargetSection, Tramp.ThunkOffset));
456
457
return Error::success();
458
}
459
460
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
461
SectionSym &Section) {
462
P.format(" `{0}`", Section.Name);
463
AutoIndent Indent(P, 7);
464
P.formatLine("length = {0}, alignment = {1}, rva = {2}, section # = {3}",
465
Section.Length, Section.Alignment, Section.Rva,
466
Section.SectionNumber);
467
P.printLine("characteristics =");
468
AutoIndent Indent2(P, 2);
469
P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
470
Section.Characteristics, 1, "",
471
CharacteristicStyle::Descriptive));
472
return Error::success();
473
}
474
475
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CoffGroupSym &CG) {
476
P.format(" `{0}`", CG.Name);
477
AutoIndent Indent(P, 7);
478
P.formatLine("length = {0}, addr = {1}", CG.Size,
479
formatSegmentOffset(CG.Segment, CG.Offset));
480
P.printLine("characteristics =");
481
AutoIndent Indent2(P, 2);
482
P.printLine(formatSectionCharacteristics(P.getIndentLevel(),
483
CG.Characteristics, 1, "",
484
CharacteristicStyle::Descriptive));
485
return Error::success();
486
}
487
488
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
489
BPRelativeSym &BPRel) {
490
P.format(" `{0}`", BPRel.Name);
491
AutoIndent Indent(P, 7);
492
P.formatLine("type = {0}, offset = {1}", typeIndex(BPRel.Type), BPRel.Offset);
493
return Error::success();
494
}
495
496
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
497
BuildInfoSym &BuildInfo) {
498
P.format(" BuildId = `{0}`", BuildInfo.BuildId);
499
return Error::success();
500
}
501
502
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
503
CallSiteInfoSym &CSI) {
504
AutoIndent Indent(P, 7);
505
P.formatLine("type = {0}, addr = {1}", typeIndex(CSI.Type),
506
formatSegmentOffset(CSI.Segment, CSI.CodeOffset));
507
return Error::success();
508
}
509
510
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
511
EnvBlockSym &EnvBlock) {
512
AutoIndent Indent(P, 7);
513
for (const auto &Entry : EnvBlock.Fields) {
514
P.formatLine("- {0}", Entry);
515
}
516
return Error::success();
517
}
518
519
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FileStaticSym &FS) {
520
P.format(" `{0}`", FS.Name);
521
AutoIndent Indent(P, 7);
522
if (SymGroup) {
523
Expected<StringRef> FileName =
524
SymGroup->getNameFromStringTable(FS.ModFilenameOffset);
525
if (FileName) {
526
P.formatLine("type = {0}, file name = {1} ({2}), flags = {3}",
527
typeIndex(FS.Index), FS.ModFilenameOffset, *FileName,
528
formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags));
529
}
530
return Error::success();
531
}
532
533
P.formatLine("type = {0}, file name offset = {1}, flags = {2}",
534
typeIndex(FS.Index), FS.ModFilenameOffset,
535
formatLocalSymFlags(P.getIndentLevel() + 9, FS.Flags));
536
return Error::success();
537
}
538
539
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
540
P.format(" `{0}`", Export.Name);
541
AutoIndent Indent(P, 7);
542
P.formatLine("ordinal = {0}, flags = {1}", Export.Ordinal,
543
formatExportFlags(P.getIndentLevel() + 9, Export.Flags));
544
return Error::success();
545
}
546
547
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
548
Compile2Sym &Compile2) {
549
AutoIndent Indent(P, 7);
550
SourceLanguage Lang = static_cast<SourceLanguage>(
551
Compile2.Flags & CompileSym2Flags::SourceLanguageMask);
552
CompilationCPU = Compile2.Machine;
553
P.formatLine("machine = {0}, ver = {1}, language = {2}",
554
formatMachineType(Compile2.Machine), Compile2.Version,
555
formatSourceLanguage(Lang));
556
P.formatLine("frontend = {0}.{1}.{2}, backend = {3}.{4}.{5}",
557
Compile2.VersionFrontendMajor, Compile2.VersionFrontendMinor,
558
Compile2.VersionFrontendBuild, Compile2.VersionBackendMajor,
559
Compile2.VersionBackendMinor, Compile2.VersionBackendBuild);
560
P.formatLine("flags = {0}",
561
formatCompileSym2Flags(P.getIndentLevel() + 9, Compile2.Flags));
562
P.formatLine(
563
"extra strings = {0}",
564
typesetStringList(P.getIndentLevel() + 9 + 2, Compile2.ExtraStrings));
565
return Error::success();
566
}
567
568
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
569
Compile3Sym &Compile3) {
570
AutoIndent Indent(P, 7);
571
SourceLanguage Lang = static_cast<SourceLanguage>(
572
Compile3.Flags & CompileSym3Flags::SourceLanguageMask);
573
CompilationCPU = Compile3.Machine;
574
P.formatLine("machine = {0}, Ver = {1}, language = {2}",
575
formatMachineType(Compile3.Machine), Compile3.Version,
576
formatSourceLanguage(Lang));
577
P.formatLine("frontend = {0}.{1}.{2}.{3}, backend = {4}.{5}.{6}.{7}",
578
Compile3.VersionFrontendMajor, Compile3.VersionFrontendMinor,
579
Compile3.VersionFrontendBuild, Compile3.VersionFrontendQFE,
580
Compile3.VersionBackendMajor, Compile3.VersionBackendMinor,
581
Compile3.VersionBackendBuild, Compile3.VersionBackendQFE);
582
P.formatLine("flags = {0}",
583
formatCompileSym3Flags(P.getIndentLevel() + 9, Compile3.Flags));
584
return Error::success();
585
}
586
587
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
588
ConstantSym &Constant) {
589
P.format(" `{0}`", Constant.Name);
590
AutoIndent Indent(P, 7);
591
P.formatLine("type = {0}, value = {1}", typeIndex(Constant.Type),
592
toString(Constant.Value, 10));
593
return Error::success();
594
}
595
596
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
597
P.format(" `{0}`", Data.Name);
598
AutoIndent Indent(P, 7);
599
P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
600
formatSegmentOffset(Data.Segment, Data.DataOffset));
601
return Error::success();
602
}
603
604
Error MinimalSymbolDumper::visitKnownRecord(
605
CVSymbol &CVR, DefRangeFramePointerRelFullScopeSym &Def) {
606
P.format(" offset = {0}", Def.Offset);
607
return Error::success();
608
}
609
610
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
611
DefRangeFramePointerRelSym &Def) {
612
AutoIndent Indent(P, 7);
613
P.formatLine("offset = {0}, range = {1}", Def.Hdr.Offset,
614
formatRange(Def.Range));
615
P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
616
return Error::success();
617
}
618
619
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
620
DefRangeRegisterRelSym &Def) {
621
AutoIndent Indent(P, 7);
622
P.formatLine("register = {0}, offset = {1}, offset in parent = {2}, has "
623
"spilled udt = {3}",
624
formatRegisterId(Def.Hdr.Register, CompilationCPU),
625
int32_t(Def.Hdr.BasePointerOffset), Def.offsetInParent(),
626
Def.hasSpilledUDTMember());
627
P.formatLine("range = {0}, gaps = [{1}]", formatRange(Def.Range),
628
formatGaps(P.getIndentLevel() + 9, Def.Gaps));
629
return Error::success();
630
}
631
632
Error MinimalSymbolDumper::visitKnownRecord(
633
CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
634
AutoIndent Indent(P, 7);
635
P.formatLine("register = {0}, may have no name = {1}, range start = "
636
"{2}, length = {3}",
637
formatRegisterId(DefRangeRegister.Hdr.Register, CompilationCPU),
638
bool(DefRangeRegister.Hdr.MayHaveNoName),
639
formatSegmentOffset(DefRangeRegister.Range.ISectStart,
640
DefRangeRegister.Range.OffsetStart),
641
DefRangeRegister.Range.Range);
642
P.formatLine("gaps = [{0}]",
643
formatGaps(P.getIndentLevel() + 9, DefRangeRegister.Gaps));
644
return Error::success();
645
}
646
647
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
648
DefRangeSubfieldRegisterSym &Def) {
649
AutoIndent Indent(P, 7);
650
bool NoName = !!(Def.Hdr.MayHaveNoName == 0);
651
P.formatLine("register = {0}, may have no name = {1}, offset in parent = {2}",
652
formatRegisterId(Def.Hdr.Register, CompilationCPU), NoName,
653
uint32_t(Def.Hdr.OffsetInParent));
654
P.formatLine("range = {0}, gaps = [{1}]", formatRange(Def.Range),
655
formatGaps(P.getIndentLevel() + 9, Def.Gaps));
656
return Error::success();
657
}
658
659
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
660
DefRangeSubfieldSym &Def) {
661
AutoIndent Indent(P, 7);
662
P.formatLine("program = {0}, offset in parent = {1}, range = {2}",
663
Def.Program, Def.OffsetInParent, formatRange(Def.Range));
664
P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
665
return Error::success();
666
}
667
668
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, DefRangeSym &Def) {
669
AutoIndent Indent(P, 7);
670
P.formatLine("program = {0}, range = {1}", Def.Program,
671
formatRange(Def.Range));
672
P.formatLine("gaps = [{0}]", formatGaps(P.getIndentLevel() + 9, Def.Gaps));
673
return Error::success();
674
}
675
676
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameCookieSym &FC) {
677
AutoIndent Indent(P, 7);
678
P.formatLine("code offset = {0}, Register = {1}, kind = {2}, flags = {3}",
679
FC.CodeOffset, formatRegisterId(FC.Register, CompilationCPU),
680
formatCookieKind(FC.CookieKind), FC.Flags);
681
return Error::success();
682
}
683
684
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, FrameProcSym &FP) {
685
AutoIndent Indent(P, 7);
686
P.formatLine("size = {0}, padding size = {1}, offset to padding = {2}",
687
FP.TotalFrameBytes, FP.PaddingFrameBytes, FP.OffsetToPadding);
688
P.formatLine("bytes of callee saved registers = {0}, exception handler addr "
689
"= {1}",
690
FP.BytesOfCalleeSavedRegisters,
691
formatSegmentOffset(FP.SectionIdOfExceptionHandler,
692
FP.OffsetOfExceptionHandler));
693
P.formatLine(
694
"local fp reg = {0}, param fp reg = {1}",
695
formatRegisterId(FP.getLocalFramePtrReg(CompilationCPU), CompilationCPU),
696
formatRegisterId(FP.getParamFramePtrReg(CompilationCPU), CompilationCPU));
697
P.formatLine("flags = {0}",
698
formatFrameProcedureOptions(P.getIndentLevel() + 9, FP.Flags));
699
return Error::success();
700
}
701
702
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
703
HeapAllocationSiteSym &HAS) {
704
AutoIndent Indent(P, 7);
705
P.formatLine("type = {0}, addr = {1} call size = {2}", typeIndex(HAS.Type),
706
formatSegmentOffset(HAS.Segment, HAS.CodeOffset),
707
HAS.CallInstructionSize);
708
return Error::success();
709
}
710
711
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, InlineSiteSym &IS) {
712
AutoIndent Indent(P, 7);
713
P.formatLine("inlinee = {0}, parent = {1}, end = {2}", idIndex(IS.Inlinee),
714
IS.Parent, IS.End);
715
716
// Break down the annotation byte code and calculate code and line offsets.
717
// FIXME: It would be helpful if we could look up the initial file and inlinee
718
// lines offset using the inlinee index above.
719
uint32_t CodeOffset = 0;
720
int32_t LineOffset = 0;
721
for (auto &Annot : IS.annotations()) {
722
P.formatLine(" {0}", fmt_align(toHex(Annot.Bytes), AlignStyle::Left, 9));
723
724
auto formatCodeOffset = [&](uint32_t Delta) {
725
CodeOffset += Delta;
726
P.format(" code 0x{0} (+0x{1})", utohexstr(CodeOffset), utohexstr(Delta));
727
};
728
auto formatCodeLength = [&](uint32_t Length) {
729
// Notably, changing the code length does not affect the code offset.
730
P.format(" code end 0x{0} (+0x{1})", utohexstr(CodeOffset + Length),
731
utohexstr(Length));
732
};
733
auto formatLineOffset = [&](int32_t Delta) {
734
LineOffset += Delta;
735
char Sign = Delta > 0 ? '+' : '-';
736
P.format(" line {0} ({1}{2})", LineOffset, Sign, std::abs(Delta));
737
};
738
739
// Use the opcode to interpret the integer values.
740
switch (Annot.OpCode) {
741
case BinaryAnnotationsOpCode::Invalid:
742
break;
743
case BinaryAnnotationsOpCode::CodeOffset:
744
case BinaryAnnotationsOpCode::ChangeCodeOffset:
745
formatCodeOffset(Annot.U1);
746
break;
747
case BinaryAnnotationsOpCode::ChangeLineOffset:
748
formatLineOffset(Annot.S1);
749
break;
750
case BinaryAnnotationsOpCode::ChangeCodeLength:
751
formatCodeLength(Annot.U1);
752
// Apparently this annotation updates the code offset. It's hard to make
753
// MSVC produce this opcode, but clang uses it, and debuggers seem to use
754
// this interpretation.
755
CodeOffset += Annot.U1;
756
break;
757
case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset:
758
formatCodeOffset(Annot.U1);
759
formatLineOffset(Annot.S1);
760
break;
761
case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset:
762
formatCodeOffset(Annot.U2);
763
formatCodeLength(Annot.U1);
764
break;
765
766
case BinaryAnnotationsOpCode::ChangeFile: {
767
uint32_t FileOffset = Annot.U1;
768
StringRef Filename = "<unknown>";
769
if (SymGroup) {
770
if (Expected<StringRef> MaybeFile =
771
SymGroup->getNameFromStringTable(FileOffset))
772
Filename = *MaybeFile;
773
else
774
return MaybeFile.takeError();
775
}
776
P.format(" setfile {0} 0x{1}", utohexstr(FileOffset));
777
break;
778
}
779
780
// The rest of these are hard to convince MSVC to emit, so they are not as
781
// well understood.
782
case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
783
formatCodeOffset(Annot.U1);
784
break;
785
case BinaryAnnotationsOpCode::ChangeLineEndDelta:
786
case BinaryAnnotationsOpCode::ChangeRangeKind:
787
case BinaryAnnotationsOpCode::ChangeColumnStart:
788
case BinaryAnnotationsOpCode::ChangeColumnEnd:
789
P.format(" {0} {1}", Annot.Name, Annot.U1);
790
break;
791
case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
792
P.format(" {0} {1}", Annot.Name, Annot.S1);
793
break;
794
}
795
}
796
return Error::success();
797
}
798
799
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
800
RegisterSym &Register) {
801
P.format(" `{0}`", Register.Name);
802
AutoIndent Indent(P, 7);
803
P.formatLine("register = {0}, type = {1}",
804
formatRegisterId(Register.Register, CompilationCPU),
805
typeIndex(Register.Index));
806
return Error::success();
807
}
808
809
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
810
PublicSym32 &Public) {
811
P.format(" `{0}`", Public.Name);
812
AutoIndent Indent(P, 7);
813
P.formatLine("flags = {0}, addr = {1}",
814
formatPublicSymFlags(P.getIndentLevel() + 9, Public.Flags),
815
formatSegmentOffset(Public.Segment, Public.Offset));
816
return Error::success();
817
}
818
819
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcRefSym &PR) {
820
P.format(" `{0}`", PR.Name);
821
AutoIndent Indent(P, 7);
822
P.formatLine("module = {0}, sum name = {1}, offset = {2}", PR.Module,
823
PR.SumName, PR.SymOffset);
824
return Error::success();
825
}
826
827
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
828
P.format(" `{0}` (addr = {1})", Label.Name,
829
formatSegmentOffset(Label.Segment, Label.CodeOffset));
830
AutoIndent Indent(P, 7);
831
P.formatLine("flags = {0}",
832
formatProcSymFlags(P.getIndentLevel() + 9, Label.Flags));
833
return Error::success();
834
}
835
836
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
837
P.format(" `{0}`", Local.Name);
838
AutoIndent Indent(P, 7);
839
840
std::string FlagStr =
841
formatLocalSymFlags(P.getIndentLevel() + 9, Local.Flags);
842
P.formatLine("type={0}, flags = {1}", typeIndex(Local.Type), FlagStr);
843
return Error::success();
844
}
845
846
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
847
ObjNameSym &ObjName) {
848
P.format(" sig={0}, `{1}`", ObjName.Signature, ObjName.Name);
849
return Error::success();
850
}
851
852
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
853
P.format(" `{0}`", Proc.Name);
854
AutoIndent Indent(P, 7);
855
P.formatLine("parent = {0}, end = {1}, addr = {2}, code size = {3}",
856
Proc.Parent, Proc.End,
857
formatSegmentOffset(Proc.Segment, Proc.CodeOffset),
858
Proc.CodeSize);
859
bool IsType = true;
860
switch (Proc.getKind()) {
861
case SymbolRecordKind::GlobalProcIdSym:
862
case SymbolRecordKind::ProcIdSym:
863
case SymbolRecordKind::DPCProcIdSym:
864
IsType = false;
865
break;
866
default:
867
break;
868
}
869
P.formatLine("type = `{0}`, debug start = {1}, debug end = {2}, flags = {3}",
870
typeOrIdIndex(Proc.FunctionType, IsType), Proc.DbgStart,
871
Proc.DbgEnd,
872
formatProcSymFlags(P.getIndentLevel() + 9, Proc.Flags));
873
return Error::success();
874
}
875
876
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
877
ScopeEndSym &ScopeEnd) {
878
return Error::success();
879
}
880
881
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
882
const char *Format;
883
switch (CVR.kind()) {
884
case S_CALLEES:
885
Format = "callee: {0}";
886
break;
887
case S_CALLERS:
888
Format = "caller: {0}";
889
break;
890
case S_INLINEES:
891
Format = "inlinee: {0}";
892
break;
893
default:
894
return llvm::make_error<CodeViewError>(
895
"Unknown CV Record type for a CallerSym object!");
896
}
897
AutoIndent Indent(P, 7);
898
for (const auto &I : Caller.Indices) {
899
P.formatLine(Format, idIndex(I));
900
}
901
return Error::success();
902
}
903
904
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
905
RegRelativeSym &RegRel) {
906
P.format(" `{0}`", RegRel.Name);
907
AutoIndent Indent(P, 7);
908
P.formatLine(
909
"type = {0}, register = {1}, offset = {2}", typeIndex(RegRel.Type),
910
formatRegisterId(RegRel.Register, CompilationCPU), RegRel.Offset);
911
return Error::success();
912
}
913
914
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
915
ThreadLocalDataSym &Data) {
916
P.format(" `{0}`", Data.Name);
917
AutoIndent Indent(P, 7);
918
P.formatLine("type = {0}, addr = {1}", typeIndex(Data.Type),
919
formatSegmentOffset(Data.Segment, Data.DataOffset));
920
return Error::success();
921
}
922
923
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
924
P.format(" `{0}`", UDT.Name);
925
AutoIndent Indent(P, 7);
926
P.formatLine("original type = {0}", UDT.Type);
927
return Error::success();
928
}
929
930
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
931
UsingNamespaceSym &UN) {
932
P.format(" `{0}`", UN.Name);
933
return Error::success();
934
}
935
936
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
937
AnnotationSym &Annot) {
938
AutoIndent Indent(P, 7);
939
P.formatLine("addr = {0}", formatSegmentOffset(Annot.Segment, Annot.CodeOffset));
940
P.formatLine("strings = {0}", typesetStringList(P.getIndentLevel() + 9 + 2,
941
Annot.Strings));
942
return Error::success();
943
}
944
945
Error MinimalSymbolDumper::visitKnownRecord(CVSymbol &CVR,
946
JumpTableSym &JumpTable) {
947
AutoIndent Indent(P, 7);
948
P.formatLine(
949
"base = {0}, switchtype = {1}, branch = {2}, table = {3}, entriescount = "
950
"{4}",
951
formatSegmentOffset(JumpTable.BaseSegment, JumpTable.BaseOffset),
952
formatJumpTableEntrySize(JumpTable.SwitchType),
953
formatSegmentOffset(JumpTable.BranchSegment, JumpTable.BranchOffset),
954
formatSegmentOffset(JumpTable.TableSegment, JumpTable.TableOffset),
955
JumpTable.EntriesCount);
956
return Error::success();
957
}
958
959