Home | History | Annotate | Line # | Download | only in CodeView
      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 
     11 using namespace llvm;
     12 using namespace llvm::codeview;
     13 
     14 #define error(X)                                                               \
     15   if (auto EC = X)                                                             \
     16     return EC;
     17 
     18 namespace {
     19 struct 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 
     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();
     34 }
     35 
     36 Error SymbolRecordMapping::visitSymbolBegin(CVSymbol &Record) {
     37   error(IO.beginRecord(MaxRecordLength - sizeof(RecordPrefix)));
     38   return Error::success();
     39 }
     40 
     41 Error SymbolRecordMapping::visitSymbolEnd(CVSymbol &Record) {
     42   error(IO.padToAlignment(alignOf(Container)));
     43   error(IO.endRecord());
     44   return Error::success();
     45 }
     46 
     47 Error 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 
     59 Error 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 
     74 Error 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 
     87 Error 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 
    102 Error 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 
    114 Error 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 
    124 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
    125                                             BuildInfoSym &BuildInfo) {
    126 
    127   error(IO.mapInteger(BuildInfo.BuildId));
    128 
    129   return Error::success();
    130 }
    131 
    132 Error 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 
    144 Error 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 
    154 Error 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 
    165 Error 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 
    174 Error 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 
    191 Error 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 
    209 Error 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 
    219 Error 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 
    229 Error 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 
    239 Error SymbolRecordMapping::visitKnownRecord(
    240     CVSymbol &CVR,
    241     DefRangeFramePointerRelFullScopeSym &DefRangeFramePointerRelFullScope) {
    242 
    243   error(IO.mapInteger(DefRangeFramePointerRelFullScope.Offset));
    244 
    245   return Error::success();
    246 }
    247 
    248 Error 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 
    260 Error 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 
    271 Error 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 
    283 Error 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 
    294 Error 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 
    304 Error 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 
    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));
    324 
    325   return Error::success();
    326 }
    327 
    328 Error 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 
    339 Error 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 
    350 Error 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 
    360 Error 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 
    371 Error 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 
    382 Error 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 
    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));
    396 
    397   return Error::success();
    398 }
    399 
    400 Error 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 
    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();
    422 }
    423 
    424 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
    425                                             ScopeEndSym &ScopeEnd) {
    426   return Error::success();
    427 }
    428 
    429 Error 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 
    436 Error 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 
    447 Error 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 
    458 Error 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 
    466 Error SymbolRecordMapping::visitKnownRecord(CVSymbol &CVR,
    467                                             UsingNamespaceSym &UN) {
    468 
    469   error(IO.mapStringZ(UN.Name));
    470 
    471   return Error::success();
    472 }
    473 
    474 Error 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 
    486 RegisterId codeview::decodeFramePtrReg(EncodedFramePtrReg EncodedReg,
    487                                        CPUType CPU) {
    488   assert(unsigned(EncodedReg) < 4);
    489   switch (CPU) {
    490   // FIXME: Add ARM and AArch64 variants here.
    491   default:
    492     break;
    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;
    506     }
    507     llvm_unreachable("bad encoding");
    508   case CPUType::X64:
    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;
    514     }
    515     llvm_unreachable("bad encoding");
    516   }
    517   return RegisterId::NONE;
    518 }
    519 
    520 EncodedFramePtrReg codeview::encodeFramePtrReg(RegisterId Reg, CPUType CPU) {
    521   switch (CPU) {
    522   // FIXME: Add ARM and AArch64 variants here.
    523   default:
    524     break;
    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:
    533     switch (Reg) {
    534     case RegisterId::VFRAME:
    535       return EncodedFramePtrReg::StackPtr;
    536     case RegisterId::EBP:
    537       return EncodedFramePtrReg::FramePtr;
    538     case RegisterId::EBX:
    539       return EncodedFramePtrReg::BasePtr;
    540     default:
    541       break;
    542     }
    543     break;
    544   case CPUType::X64:
    545     switch (Reg) {
    546     case RegisterId::RSP:
    547       return EncodedFramePtrReg::StackPtr;
    548     case RegisterId::RBP:
    549       return EncodedFramePtrReg::FramePtr;
    550     case RegisterId::R13:
    551       return EncodedFramePtrReg::BasePtr;
    552     default:
    553       break;
    554     }
    555     break;
    556   }
    557   return EncodedFramePtrReg::None;
    558 }
    559