1 //===- SymbolRecordMapping.cpp -----------------------------------*- C++-*-===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/CodeView/SymbolRecordMapping.h"
12 using namespace llvm::codeview
;
20 Error
operator()(CodeViewRecordIO
&IO
, LocalVariableAddrGap
&Gap
) const {
21 error(IO
.mapInteger(Gap
.GapStartOffset
));
22 error(IO
.mapInteger(Gap
.Range
));
23 return Error::success();
28 static 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();
36 Error
SymbolRecordMapping::visitSymbolBegin(CVSymbol
&Record
) {
37 error(IO
.beginRecord(MaxRecordLength
- sizeof(RecordPrefix
)));
38 return Error::success();
41 Error
SymbolRecordMapping::visitSymbolEnd(CVSymbol
&Record
) {
42 error(IO
.padToAlignment(alignOf(Container
)));
43 error(IO
.endRecord());
44 return Error::success();
47 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, BlockSym
&Block
) {
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
));
56 return Error::success();
59 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, Thunk32Sym
&Thunk
) {
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
));
71 return Error::success();
74 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
75 TrampolineSym
&Tramp
) {
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
));
84 return Error::success();
87 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
88 SectionSym
&Section
) {
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
));
99 return Error::success();
102 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
103 CoffGroupSym
&CoffGroup
) {
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
));
111 return Error::success();
114 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
115 BPRelativeSym
&BPRel
) {
117 error(IO
.mapInteger(BPRel
.Offset
));
118 error(IO
.mapInteger(BPRel
.Type
));
119 error(IO
.mapStringZ(BPRel
.Name
));
121 return Error::success();
124 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
125 BuildInfoSym
&BuildInfo
) {
127 error(IO
.mapInteger(BuildInfo
.BuildId
));
129 return Error::success();
132 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
133 CallSiteInfoSym
&CallSiteInfo
) {
134 uint16_t Padding
= 0;
136 error(IO
.mapInteger(CallSiteInfo
.CodeOffset
));
137 error(IO
.mapInteger(CallSiteInfo
.Segment
));
138 error(IO
.mapInteger(Padding
));
139 error(IO
.mapInteger(CallSiteInfo
.Type
));
141 return Error::success();
144 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
145 EnvBlockSym
&EnvBlock
) {
147 uint8_t Reserved
= 0;
148 error(IO
.mapInteger(Reserved
));
149 error(IO
.mapStringZVectorZ(EnvBlock
.Fields
));
151 return Error::success();
154 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
155 FileStaticSym
&FileStatic
) {
157 error(IO
.mapInteger(FileStatic
.Index
));
158 error(IO
.mapInteger(FileStatic
.ModFilenameOffset
));
159 error(IO
.mapEnum(FileStatic
.Flags
));
160 error(IO
.mapStringZ(FileStatic
.Name
));
162 return Error::success();
165 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, ExportSym
&Export
) {
167 error(IO
.mapInteger(Export
.Ordinal
));
168 error(IO
.mapEnum(Export
.Flags
));
169 error(IO
.mapStringZ(Export
.Name
));
171 return Error::success();
174 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
175 Compile2Sym
&Compile2
) {
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
));
188 return Error::success();
191 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
192 Compile3Sym
&Compile3
) {
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
));
206 return Error::success();
209 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
210 ConstantSym
&Constant
) {
212 error(IO
.mapInteger(Constant
.Type
));
213 error(IO
.mapEncodedInteger(Constant
.Value
));
214 error(IO
.mapStringZ(Constant
.Name
));
216 return Error::success();
219 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, DataSym
&Data
) {
221 error(IO
.mapInteger(Data
.Type
));
222 error(IO
.mapInteger(Data
.DataOffset
));
223 error(IO
.mapInteger(Data
.Segment
));
224 error(IO
.mapStringZ(Data
.Name
));
226 return Error::success();
229 Error
SymbolRecordMapping::visitKnownRecord(
230 CVSymbol
&CVR
, DefRangeFramePointerRelSym
&DefRangeFramePointerRel
) {
232 error(IO
.mapObject(DefRangeFramePointerRel
.Hdr
.Offset
));
233 error(mapLocalVariableAddrRange(IO
, DefRangeFramePointerRel
.Range
));
234 error(IO
.mapVectorTail(DefRangeFramePointerRel
.Gaps
, MapGap()));
236 return Error::success();
239 Error
SymbolRecordMapping::visitKnownRecord(
241 DefRangeFramePointerRelFullScopeSym
&DefRangeFramePointerRelFullScope
) {
243 error(IO
.mapInteger(DefRangeFramePointerRelFullScope
.Offset
));
245 return Error::success();
248 Error
SymbolRecordMapping::visitKnownRecord(
249 CVSymbol
&CVR
, DefRangeRegisterRelSym
&DefRangeRegisterRel
) {
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()));
257 return Error::success();
260 Error
SymbolRecordMapping::visitKnownRecord(
261 CVSymbol
&CVR
, DefRangeRegisterSym
&DefRangeRegister
) {
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()));
268 return Error::success();
271 Error
SymbolRecordMapping::visitKnownRecord(
272 CVSymbol
&CVR
, DefRangeSubfieldRegisterSym
&DefRangeSubfieldRegister
) {
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()));
280 return Error::success();
283 Error
SymbolRecordMapping::visitKnownRecord(
284 CVSymbol
&CVR
, DefRangeSubfieldSym
&DefRangeSubfield
) {
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()));
291 return Error::success();
294 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
295 DefRangeSym
&DefRange
) {
297 error(IO
.mapInteger(DefRange
.Program
));
298 error(mapLocalVariableAddrRange(IO
, DefRange
.Range
));
299 error(IO
.mapVectorTail(DefRange
.Gaps
, MapGap()));
301 return Error::success();
304 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
305 FrameCookieSym
&FrameCookie
) {
307 error(IO
.mapInteger(FrameCookie
.CodeOffset
));
308 error(IO
.mapInteger(FrameCookie
.Register
));
309 error(IO
.mapEnum(FrameCookie
.CookieKind
));
310 error(IO
.mapInteger(FrameCookie
.Flags
));
312 return Error::success();
315 Error
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
));
325 return Error::success();
328 Error
SymbolRecordMapping::visitKnownRecord(
329 CVSymbol
&CVR
, HeapAllocationSiteSym
&HeapAllocSite
) {
331 error(IO
.mapInteger(HeapAllocSite
.CodeOffset
));
332 error(IO
.mapInteger(HeapAllocSite
.Segment
));
333 error(IO
.mapInteger(HeapAllocSite
.CallInstructionSize
));
334 error(IO
.mapInteger(HeapAllocSite
.Type
));
336 return Error::success();
339 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
340 InlineSiteSym
&InlineSite
) {
342 error(IO
.mapInteger(InlineSite
.Parent
));
343 error(IO
.mapInteger(InlineSite
.End
));
344 error(IO
.mapInteger(InlineSite
.Inlinee
));
345 error(IO
.mapByteVectorTail(InlineSite
.AnnotationData
));
347 return Error::success();
350 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
351 RegisterSym
&Register
) {
353 error(IO
.mapInteger(Register
.Index
));
354 error(IO
.mapEnum(Register
.Register
));
355 error(IO
.mapStringZ(Register
.Name
));
357 return Error::success();
360 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
361 PublicSym32
&Public
) {
363 error(IO
.mapEnum(Public
.Flags
));
364 error(IO
.mapInteger(Public
.Offset
));
365 error(IO
.mapInteger(Public
.Segment
));
366 error(IO
.mapStringZ(Public
.Name
));
368 return Error::success();
371 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
372 ProcRefSym
&ProcRef
) {
374 error(IO
.mapInteger(ProcRef
.SumName
));
375 error(IO
.mapInteger(ProcRef
.SymOffset
));
376 error(IO
.mapInteger(ProcRef
.Module
));
377 error(IO
.mapStringZ(ProcRef
.Name
));
379 return Error::success();
382 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, LabelSym
&Label
) {
384 error(IO
.mapInteger(Label
.CodeOffset
));
385 error(IO
.mapInteger(Label
.Segment
));
386 error(IO
.mapEnum(Label
.Flags
));
387 error(IO
.mapStringZ(Label
.Name
));
389 return Error::success();
392 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, LocalSym
&Local
) {
393 error(IO
.mapInteger(Local
.Type
));
394 error(IO
.mapEnum(Local
.Flags
));
395 error(IO
.mapStringZ(Local
.Name
));
397 return Error::success();
400 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
401 ObjNameSym
&ObjName
) {
403 error(IO
.mapInteger(ObjName
.Signature
));
404 error(IO
.mapStringZ(ObjName
.Name
));
406 return Error::success();
409 Error
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();
424 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
425 ScopeEndSym
&ScopeEnd
) {
426 return Error::success();
429 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, CallerSym
&Caller
) {
430 error(IO
.mapVectorN
<uint32_t>(
432 [](CodeViewRecordIO
&IO
, TypeIndex
&N
) { return IO
.mapInteger(N
); }));
433 return Error::success();
436 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
437 RegRelativeSym
&RegRel
) {
439 error(IO
.mapInteger(RegRel
.Offset
));
440 error(IO
.mapInteger(RegRel
.Type
));
441 error(IO
.mapEnum(RegRel
.Register
));
442 error(IO
.mapStringZ(RegRel
.Name
));
444 return Error::success();
447 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
448 ThreadLocalDataSym
&Data
) {
450 error(IO
.mapInteger(Data
.Type
));
451 error(IO
.mapInteger(Data
.DataOffset
));
452 error(IO
.mapInteger(Data
.Segment
));
453 error(IO
.mapStringZ(Data
.Name
));
455 return Error::success();
458 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
, UDTSym
&UDT
) {
460 error(IO
.mapInteger(UDT
.Type
));
461 error(IO
.mapStringZ(UDT
.Name
));
463 return Error::success();
466 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
467 UsingNamespaceSym
&UN
) {
469 error(IO
.mapStringZ(UN
.Name
));
471 return Error::success();
474 Error
SymbolRecordMapping::visitKnownRecord(CVSymbol
&CVR
,
475 AnnotationSym
&Annot
) {
477 error(IO
.mapInteger(Annot
.CodeOffset
));
478 error(IO
.mapInteger(Annot
.Segment
));
479 error(IO
.mapVectorN
<uint16_t>(
481 [](CodeViewRecordIO
&IO
, StringRef
&S
) { return IO
.mapStringZ(S
); }));
483 return Error::success();
486 RegisterId
codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg
,
488 assert(unsigned(EncodedReg
) < 4);
490 // FIXME: Add ARM and AArch64 variants here.
493 case CPUType::Intel8080
:
494 case CPUType::Intel8086
:
495 case CPUType::Intel80286
:
496 case CPUType::Intel80386
:
497 case CPUType::Intel80486
:
498 case CPUType::Pentium
:
499 case CPUType::PentiumPro
:
500 case CPUType::Pentium3
:
501 switch (EncodedReg
) {
502 case EncodedFramePtrReg::None
: return RegisterId::NONE
;
503 case EncodedFramePtrReg::StackPtr
: return RegisterId::VFRAME
;
504 case EncodedFramePtrReg::FramePtr
: return RegisterId::EBP
;
505 case EncodedFramePtrReg::BasePtr
: return RegisterId::EBX
;
507 llvm_unreachable("bad encoding");
509 switch (EncodedReg
) {
510 case EncodedFramePtrReg::None
: return RegisterId::NONE
;
511 case EncodedFramePtrReg::StackPtr
: return RegisterId::RSP
;
512 case EncodedFramePtrReg::FramePtr
: return RegisterId::RBP
;
513 case EncodedFramePtrReg::BasePtr
: return RegisterId::R13
;
515 llvm_unreachable("bad encoding");
517 return RegisterId::NONE
;
520 EncodedFramePtrReg
codeview::encodeFramePtrReg(RegisterId Reg
, CPUType CPU
) {
522 // FIXME: Add ARM and AArch64 variants here.
525 case CPUType::Intel8080
:
526 case CPUType::Intel8086
:
527 case CPUType::Intel80286
:
528 case CPUType::Intel80386
:
529 case CPUType::Intel80486
:
530 case CPUType::Pentium
:
531 case CPUType::PentiumPro
:
532 case CPUType::Pentium3
:
534 case RegisterId::VFRAME
:
535 return EncodedFramePtrReg::StackPtr
;
536 case RegisterId::EBP
:
537 return EncodedFramePtrReg::FramePtr
;
538 case RegisterId::EBX
:
539 return EncodedFramePtrReg::BasePtr
;
546 case RegisterId::RSP
:
547 return EncodedFramePtrReg::StackPtr
;
548 case RegisterId::RBP
:
549 return EncodedFramePtrReg::FramePtr
;
550 case RegisterId::R13
:
551 return EncodedFramePtrReg::BasePtr
;
557 return EncodedFramePtrReg::None
;