1//===- SymbolRecordMapping.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 "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
10
11using namespace llvm;
12using namespace llvm::codeview;
13
14#define error(X) \
15 if (auto EC = X) \
16 return EC;
17
18namespace {
19struct MapGap {
20 Error operator()(CodeViewRecordIO &IO, LocalVariableAddrGap &Gap) const {
21 error(IO.mapInteger(Gap.GapStartOffset));
22 error(IO.mapInteger(Gap.Range));
23 return Error::success();
24 }
25};
26}
27
28static Error mapLocalVariableAddrRange(CodeViewRecordIO &IO,
29 LocalVariableAddrRange &Range) {
30 error(IO.mapInteger(Range.OffsetStart));
31 error(IO.mapInteger(Range.ISectStart));
32 error(IO.mapInteger(Range.Range));
33 return Error::success();
34}
35
36Error SymbolRecordMapping::visitSymbolBegin(CVSymbol &Record) {
37 error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix)));
38 return Error::success();
39}
40
41Error SymbolRecordMapping::visitSymbolEnd(CVSymbol &Record) {
42 error(IO.padToAlignment(alignOf(Container)));
43 error(IO.endRecord());
44 return Error::success();
45}
46
47Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, BlockSym &Block) {
48
49 error(IO.mapInteger(Block.Parent));
50 error(IO.mapInteger(Block.End));
51 error(IO.mapInteger(Block.CodeSize));
52 error(IO.mapInteger(Block.CodeOffset));
53 error(IO.mapInteger(Block.Segment));
54 error(IO.mapStringZ(Block.Name));
55
56 return Error::success();
57}
58
59Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, Thunk32Sym &Thunk) {
60
61 error(IO.mapInteger(Thunk.Parent));
62 error(IO.mapInteger(Thunk.End));
63 error(IO.mapInteger(Thunk.Next));
64 error(IO.mapInteger(Thunk.Offset));
65 error(IO.mapInteger(Thunk.Segment));
66 error(IO.mapInteger(Thunk.Length));
67 error(IO.mapEnum(Thunk.Thunk));
68 error(IO.mapStringZ(Thunk.Name));
69 error(IO.mapByteVectorTail(Thunk.VariantData));
70
71 return Error::success();
72}
73
74Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
75 TrampolineSym &Tramp) {
76
77 error(IO.mapEnum(Tramp.Type));
78 error(IO.mapInteger(Tramp.Size));
79 error(IO.mapInteger(Tramp.ThunkOffset));
80 error(IO.mapInteger(Tramp.TargetOffset));
81 error(IO.mapInteger(Tramp.ThunkSection));
82 error(IO.mapInteger(Tramp.TargetSection));
83
84 return Error::success();
85}
86
87Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
88 SectionSym &Section) {
89 uint8_t Padding = 0;
90
91 error(IO.mapInteger(Section.SectionNumber));
92 error(IO.mapInteger(Section.Alignment));
93 error(IO.mapInteger(Padding));
94 error(IO.mapInteger(Section.Rva));
95 error(IO.mapInteger(Section.Length));
96 error(IO.mapInteger(Section.Characteristics));
97 error(IO.mapStringZ(Section.Name));
98
99 return Error::success();
100}
101
102Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
103 CoffGroupSym &CoffGroup) {
104
105 error(IO.mapInteger(CoffGroup.Size));
106 error(IO.mapInteger(CoffGroup.Characteristics));
107 error(IO.mapInteger(CoffGroup.Offset));
108 error(IO.mapInteger(CoffGroup.Segment));
109 error(IO.mapStringZ(CoffGroup.Name));
110
111 return Error::success();
112}
113
114Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
115 BPRelativeSym &BPRel) {
116
117 error(IO.mapInteger(BPRel.Offset));
118 error(IO.mapInteger(BPRel.Type));
119 error(IO.mapStringZ(BPRel.Name));
120
121 return Error::success();
122}
123
124Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
125 BuildInfoSym &BuildInfo) {
126
127 error(IO.mapInteger(BuildInfo.BuildId));
128
129 return Error::success();
130}
131
132Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
133 CallSiteInfoSym &CallSiteInfo) {
134 uint16_t Padding = 0;
135
136 error(IO.mapInteger(CallSiteInfo.CodeOffset));
137 error(IO.mapInteger(CallSiteInfo.Segment));
138 error(IO.mapInteger(Padding));
139 error(IO.mapInteger(CallSiteInfo.Type));
140
141 return Error::success();
142}
143
144Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
145 EnvBlockSym &EnvBlock) {
146
147 uint8_t Reserved = 0;
148 error(IO.mapInteger(Reserved));
149 error(IO.mapStringZVectorZ(EnvBlock.Fields));
150
151 return Error::success();
152}
153
154Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
155 FileStaticSym &FileStatic) {
156
157 error(IO.mapInteger(FileStatic.Index));
158 error(IO.mapInteger(FileStatic.ModFilenameOffset));
159 error(IO.mapEnum(FileStatic.Flags));
160 error(IO.mapStringZ(FileStatic.Name));
161
162 return Error::success();
163}
164
165Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ExportSym &Export) {
166
167 error(IO.mapInteger(Export.Ordinal));
168 error(IO.mapEnum(Export.Flags));
169 error(IO.mapStringZ(Export.Name));
170
171 return Error::success();
172}
173
174Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
175 Compile2Sym &Compile2) {
176
177 error(IO.mapEnum(Compile2.Flags));
178 error(IO.mapEnum(Compile2.Machine));
179 error(IO.mapInteger(Compile2.VersionFrontendMajor));
180 error(IO.mapInteger(Compile2.VersionFrontendMinor));
181 error(IO.mapInteger(Compile2.VersionFrontendBuild));
182 error(IO.mapInteger(Compile2.VersionBackendMajor));
183 error(IO.mapInteger(Compile2.VersionBackendMinor));
184 error(IO.mapInteger(Compile2.VersionBackendBuild));
185 error(IO.mapStringZ(Compile2.Version));
186 error(IO.mapStringZVectorZ(Compile2.ExtraStrings));
187
188 return Error::success();
189}
190
191Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
192 Compile3Sym &Compile3) {
193
194 error(IO.mapEnum(Compile3.Flags));
195 error(IO.mapEnum(Compile3.Machine));
196 error(IO.mapInteger(Compile3.VersionFrontendMajor));
197 error(IO.mapInteger(Compile3.VersionFrontendMinor));
198 error(IO.mapInteger(Compile3.VersionFrontendBuild));
199 error(IO.mapInteger(Compile3.VersionFrontendQFE));
200 error(IO.mapInteger(Compile3.VersionBackendMajor));
201 error(IO.mapInteger(Compile3.VersionBackendMinor));
202 error(IO.mapInteger(Compile3.VersionBackendBuild));
203 error(IO.mapInteger(Compile3.VersionBackendQFE));
204 error(IO.mapStringZ(Compile3.Version));
205
206 return Error::success();
207}
208
209Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
210 ConstantSym &Constant) {
211
212 error(IO.mapInteger(Constant.Type));
213 error(IO.mapEncodedInteger(Constant.Value));
214 error(IO.mapStringZ(Constant.Name));
215
216 return Error::success();
217}
218
219Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, DataSym &Data) {
220
221 error(IO.mapInteger(Data.Type));
222 error(IO.mapInteger(Data.DataOffset));
223 error(IO.mapInteger(Data.Segment));
224 error(IO.mapStringZ(Data.Name));
225
226 return Error::success();
227}
228
229Error SymbolRecordMapping::visitKnownRecord(
230 CVSymbol &CVR, DefRangeFramePointerRelSym &DefRangeFramePointerRel) {
231
232 error(IO.mapObject(DefRangeFramePointerRel.Hdr.Offset));
233 error(mapLocalVariableAddrRange(IO, DefRangeFramePointerRel.Range));
234 error(IO.mapVectorTail(DefRangeFramePointerRel.Gaps, MapGap()));
235
236 return Error::success();
237}
238
239Error SymbolRecordMapping::visitKnownRecord(
240 CVSymbol &CVR,
241 DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
242
243 error(IO.mapInteger(DefRangeFramePointerRelFullScope.Offset));
244
245 return Error::success();
246}
247
248Error SymbolRecordMapping::visitKnownRecord(
249 CVSymbol &CVR, DefRangeRegisterRelSym &DefRangeRegisterRel) {
250
251 error(IO.mapObject(DefRangeRegisterRel.Hdr.Register));
252 error(IO.mapObject(DefRangeRegisterRel.Hdr.Flags));
253 error(IO.mapObject(DefRangeRegisterRel.Hdr.BasePointerOffset));
254 error(mapLocalVariableAddrRange(IO, DefRangeRegisterRel.Range));
255 error(IO.mapVectorTail(DefRangeRegisterRel.Gaps, MapGap()));
256
257 return Error::success();
258}
259
260Error SymbolRecordMapping::visitKnownRecord(
261 CVSymbol &CVR, DefRangeRegisterSym &DefRangeRegister) {
262
263 error(IO.mapObject(DefRangeRegister.Hdr.Register));
264 error(IO.mapObject(DefRangeRegister.Hdr.MayHaveNoName));
265 error(mapLocalVariableAddrRange(IO, DefRangeRegister.Range));
266 error(IO.mapVectorTail(DefRangeRegister.Gaps, MapGap()));
267
268 return Error::success();
269}
270
271Error SymbolRecordMapping::visitKnownRecord(
272 CVSymbol &CVR, DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) {
273
274 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.Register));
275 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.MayHaveNoName));
276 error(IO.mapObject(DefRangeSubfieldRegister.Hdr.OffsetInParent));
277 error(mapLocalVariableAddrRange(IO, DefRangeSubfieldRegister.Range));
278 error(IO.mapVectorTail(DefRangeSubfieldRegister.Gaps, MapGap()));
279
280 return Error::success();
281}
282
283Error SymbolRecordMapping::visitKnownRecord(
284 CVSymbol &CVR, DefRangeSubfieldSym &DefRangeSubfield) {
285
286 error(IO.mapInteger(DefRangeSubfield.Program));
287 error(IO.mapInteger(DefRangeSubfield.OffsetInParent));
288 error(mapLocalVariableAddrRange(IO, DefRangeSubfield.Range));
289 error(IO.mapVectorTail(DefRangeSubfield.Gaps, MapGap()));
290
291 return Error::success();
292}
293
294Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
295 DefRangeSym &DefRange) {
296
297 error(IO.mapInteger(DefRange.Program));
298 error(mapLocalVariableAddrRange(IO, DefRange.Range));
299 error(IO.mapVectorTail(DefRange.Gaps, MapGap()));
300
301 return Error::success();
302}
303
304Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
305 FrameCookieSym &FrameCookie) {
306
307 error(IO.mapInteger(FrameCookie.CodeOffset));
308 error(IO.mapInteger(FrameCookie.Register));
309 error(IO.mapEnum(FrameCookie.CookieKind));
310 error(IO.mapInteger(FrameCookie.Flags));
311
312 return Error::success();
313}
314
315Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
316 FrameProcSym &FrameProc) {
317 error(IO.mapInteger(FrameProc.TotalFrameBytes));
318 error(IO.mapInteger(FrameProc.PaddingFrameBytes));
319 error(IO.mapInteger(FrameProc.OffsetToPadding));
320 error(IO.mapInteger(FrameProc.BytesOfCalleeSavedRegisters));
321 error(IO.mapInteger(FrameProc.OffsetOfExceptionHandler));
322 error(IO.mapInteger(FrameProc.SectionIdOfExceptionHandler));
323 error(IO.mapEnum(FrameProc.Flags));
324
325 return Error::success();
326}
327
328Error SymbolRecordMapping::visitKnownRecord(
329 CVSymbol &CVR, HeapAllocationSiteSym &HeapAllocSite) {
330
331 error(IO.mapInteger(HeapAllocSite.CodeOffset));
332 error(IO.mapInteger(HeapAllocSite.Segment));
333 error(IO.mapInteger(HeapAllocSite.CallInstructionSize));
334 error(IO.mapInteger(HeapAllocSite.Type));
335
336 return Error::success();
337}
338
339Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
340 InlineSiteSym &InlineSite) {
341
342 error(IO.mapInteger(InlineSite.Parent));
343 error(IO.mapInteger(InlineSite.End));
344 error(IO.mapInteger(InlineSite.Inlinee));
345 error(IO.mapByteVectorTail(InlineSite.AnnotationData));
346
347 return Error::success();
348}
349
350Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
351 RegisterSym &Register) {
352
353 error(IO.mapInteger(Register.Index));
354 error(IO.mapEnum(Register.Register));
355 error(IO.mapStringZ(Register.Name));
356
357 return Error::success();
358}
359
360Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
361 PublicSym32 &Public) {
362
363 error(IO.mapEnum(Public.Flags));
364 error(IO.mapInteger(Public.Offset));
365 error(IO.mapInteger(Public.Segment));
366 error(IO.mapStringZ(Public.Name));
367
368 return Error::success();
369}
370
371Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
372 ProcRefSym &ProcRef) {
373
374 error(IO.mapInteger(ProcRef.SumName));
375 error(IO.mapInteger(ProcRef.SymOffset));
376 error(IO.mapInteger(ProcRef.Module));
377 error(IO.mapStringZ(ProcRef.Name));
378
379 return Error::success();
380}
381
382Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LabelSym &Label) {
383
384 error(IO.mapInteger(Label.CodeOffset));
385 error(IO.mapInteger(Label.Segment));
386 error(IO.mapEnum(Label.Flags));
387 error(IO.mapStringZ(Label.Name));
388
389 return Error::success();
390}
391
392Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, LocalSym &Local) {
393 error(IO.mapInteger(Local.Type));
394 error(IO.mapEnum(Local.Flags));
395 error(IO.mapStringZ(Local.Name));
396
397 return Error::success();
398}
399
400Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
401 ObjNameSym &ObjName) {
402
403 error(IO.mapInteger(ObjName.Signature));
404 error(IO.mapStringZ(ObjName.Name));
405
406 return Error::success();
407}
408
409Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, ProcSym &Proc) {
410 error(IO.mapInteger(Proc.Parent));
411 error(IO.mapInteger(Proc.End));
412 error(IO.mapInteger(Proc.Next));
413 error(IO.mapInteger(Proc.CodeSize));
414 error(IO.mapInteger(Proc.DbgStart));
415 error(IO.mapInteger(Proc.DbgEnd));
416 error(IO.mapInteger(Proc.FunctionType));
417 error(IO.mapInteger(Proc.CodeOffset));
418 error(IO.mapInteger(Proc.Segment));
419 error(IO.mapEnum(Proc.Flags));
420 error(IO.mapStringZ(Proc.Name));
421 return Error::success();
422}
423
424Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
425 ScopeEndSym &ScopeEnd) {
426 return Error::success();
427}
428
429Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, CallerSym &Caller) {
430 error(IO.mapVectorN<uint32_t>(
431 Caller.Indices,
432 [](CodeViewRecordIO &IO, TypeIndex &N) { return IO.mapInteger(N); }));
433 return Error::success();
434}
435
436Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
437 RegRelativeSym &RegRel) {
438
439 error(IO.mapInteger(RegRel.Offset));
440 error(IO.mapInteger(RegRel.Type));
441 error(IO.mapEnum(RegRel.Register));
442 error(IO.mapStringZ(RegRel.Name));
443
444 return Error::success();
445}
446
447Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
448 ThreadLocalDataSym &Data) {
449
450 error(IO.mapInteger(Data.Type));
451 error(IO.mapInteger(Data.DataOffset));
452 error(IO.mapInteger(Data.Segment));
453 error(IO.mapStringZ(Data.Name));
454
455 return Error::success();
456}
457
458Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR, UDTSym &UDT) {
459
460 error(IO.mapInteger(UDT.Type));
461 error(IO.mapStringZ(UDT.Name));
462
463 return Error::success();
464}
465
466Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
467 UsingNamespaceSym &UN) {
468
469 error(IO.mapStringZ(UN.Name));
470
471 return Error::success();
472}
473
474Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
475 AnnotationSym &Annot) {
476
477 error(IO.mapInteger(Annot.CodeOffset));
478 error(IO.mapInteger(Annot.Segment));
479 error(IO.mapVectorN<uint16_t>(
480 Annot.Strings,
481 [](CodeViewRecordIO &IO, StringRef &S) { return IO.mapStringZ(S); }));
482
483 return Error::success();
484}
485
486Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
487 JumpTableSym &JumpTable) {
488 error(IO.mapInteger(JumpTable.BaseOffset));
489 error(IO.mapInteger(JumpTable.BaseSegment));
490 error(IO.mapEnum(JumpTable.SwitchType));
491 error(IO.mapInteger(JumpTable.BranchOffset));
492 error(IO.mapInteger(JumpTable.TableOffset));
493 error(IO.mapInteger(JumpTable.BranchSegment));
494 error(IO.mapInteger(JumpTable.TableSegment));
495 error(IO.mapInteger(JumpTable.EntriesCount));
496 return Error::success();
497}
498
499RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg,
500 CPUType CPU) {
501 assert(unsigned(EncodedReg) < 4);
502 switch (CPU) {
503 // FIXME: Add ARM and AArch64 variants here.
504 default:
505 break;
506 case CPUType::Intel8080:
507 case CPUType::Intel8086:
508 case CPUType::Intel80286:
509 case CPUType::Intel80386:
510 case CPUType::Intel80486:
511 case CPUType::Pentium:
512 case CPUType::PentiumPro:
513 case CPUType::Pentium3:
514 switch (EncodedReg) {
515 case EncodedFramePtrReg::None: return RegisterId::NONE;
516 case EncodedFramePtrReg::StackPtr: return RegisterId::VFRAME;
517 case EncodedFramePtrReg::FramePtr: return RegisterId::EBP;
518 case EncodedFramePtrReg::BasePtr: return RegisterId::EBX;
519 }
520 llvm_unreachable("bad encoding");
521 case CPUType::X64:
522 switch (EncodedReg) {
523 case EncodedFramePtrReg::None: return RegisterId::NONE;
524 case EncodedFramePtrReg::StackPtr: return RegisterId::RSP;
525 case EncodedFramePtrReg::FramePtr: return RegisterId::RBP;
526 case EncodedFramePtrReg::BasePtr: return RegisterId::R13;
527 }
528 llvm_unreachable("bad encoding");
529 }
530 return RegisterId::NONE;
531}
532
533EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) {
534 switch (CPU) {
535 // FIXME: Add ARM and AArch64 variants here.
536 default:
537 break;
538 case CPUType::Intel8080:
539 case CPUType::Intel8086:
540 case CPUType::Intel80286:
541 case CPUType::Intel80386:
542 case CPUType::Intel80486:
543 case CPUType::Pentium:
544 case CPUType::PentiumPro:
545 case CPUType::Pentium3:
546 switch (Reg) {
547 case RegisterId::VFRAME:
548 return EncodedFramePtrReg::StackPtr;
549 case RegisterId::EBP:
550 return EncodedFramePtrReg::FramePtr;
551 case RegisterId::EBX:
552 return EncodedFramePtrReg::BasePtr;
553 default:
554 break;
555 }
556 break;
557 case CPUType::X64:
558 switch (Reg) {
559 case RegisterId::RSP:
560 return EncodedFramePtrReg::StackPtr;
561 case RegisterId::RBP:
562 return EncodedFramePtrReg::FramePtr;
563 case RegisterId::R13:
564 return EncodedFramePtrReg::BasePtr;
565 default:
566 break;
567 }
568 break;
569 }
570 return EncodedFramePtrReg::None;
571}
572