LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - SymbolRecord.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 91 158 57.6 %
Date: 2018-10-20 13:21:21 Functions: 4 27 14.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- SymbolRecord.h -------------------------------------------*- C++ -*-===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #ifndef LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
      11             : #define LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H
      12             : 
      13             : #include "llvm/ADT/APSInt.h"
      14             : #include "llvm/ADT/ArrayRef.h"
      15             : #include "llvm/ADT/Optional.h"
      16             : #include "llvm/ADT/StringRef.h"
      17             : #include "llvm/ADT/iterator_range.h"
      18             : #include "llvm/DebugInfo/CodeView/CVRecord.h"
      19             : #include "llvm/DebugInfo/CodeView/CodeView.h"
      20             : #include "llvm/DebugInfo/CodeView/RecordSerialization.h"
      21             : #include "llvm/DebugInfo/CodeView/TypeIndex.h"
      22             : #include "llvm/Support/BinaryStreamArray.h"
      23             : #include "llvm/Support/Endian.h"
      24             : #include <cstdint>
      25             : #include <vector>
      26             : 
      27             : namespace llvm {
      28             : namespace codeview {
      29             : 
      30             : class SymbolRecord {
      31             : protected:
      32        4087 :   explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
      33             : 
      34             : public:
      35           0 :   SymbolRecordKind getKind() const { return Kind; }
      36             : 
      37             :   SymbolRecordKind Kind;
      38             : };
      39             : 
      40             : // S_GPROC32, S_LPROC32, S_GPROC32_ID, S_LPROC32_ID, S_LPROC32_DPC or
      41             : // S_LPROC32_DPC_ID
      42             : class ProcSym : public SymbolRecord {
      43             :   static constexpr uint32_t RelocationOffset = 32;
      44             : 
      45             : public:
      46         998 :   explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
      47             :   ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
      48             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
      49             : 
      50           0 :   uint32_t getRelocationOffset() const {
      51         182 :     return RecordOffset + RelocationOffset;
      52             :   }
      53             : 
      54             :   uint32_t Parent = 0;
      55             :   uint32_t End = 0;
      56             :   uint32_t Next = 0;
      57             :   uint32_t CodeSize = 0;
      58             :   uint32_t DbgStart = 0;
      59             :   uint32_t DbgEnd = 0;
      60             :   TypeIndex FunctionType;
      61             :   uint32_t CodeOffset = 0;
      62             :   uint16_t Segment = 0;
      63             :   ProcSymFlags Flags = ProcSymFlags::None;
      64             :   StringRef Name;
      65             : 
      66             :   uint32_t RecordOffset = 0;
      67             : };
      68             : 
      69             : // S_THUNK32
      70             : class Thunk32Sym : public SymbolRecord {
      71             : public:
      72           4 :   explicit Thunk32Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
      73             :   Thunk32Sym(SymbolRecordKind Kind, uint32_t RecordOffset)
      74             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
      75             : 
      76             :   uint32_t Parent;
      77             :   uint32_t End;
      78             :   uint32_t Next;
      79             :   uint32_t Offset;
      80             :   uint16_t Segment;
      81             :   uint16_t Length;
      82             :   ThunkOrdinal Thunk;
      83             :   StringRef Name;
      84             :   ArrayRef<uint8_t> VariantData;
      85             : 
      86             :   uint32_t RecordOffset;
      87             : };
      88             : 
      89             : // S_TRAMPOLINE
      90             : class TrampolineSym : public SymbolRecord {
      91             : public:
      92           6 :   explicit TrampolineSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
      93             :   TrampolineSym(SymbolRecordKind Kind, uint32_t RecordOffset)
      94             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
      95             : 
      96             :   TrampolineType Type;
      97             :   uint16_t Size;
      98             :   uint32_t ThunkOffset;
      99             :   uint32_t TargetOffset;
     100             :   uint16_t ThunkSection;
     101             :   uint16_t TargetSection;
     102             : 
     103             :   uint32_t RecordOffset;
     104             : };
     105             : 
     106             : // S_SECTION
     107             : class SectionSym : public SymbolRecord {
     108             : public:
     109         291 :   explicit SectionSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     110             :   SectionSym(SymbolRecordKind Kind, uint32_t RecordOffset)
     111             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
     112             : 
     113             :   uint16_t SectionNumber;
     114             :   uint8_t Alignment;
     115             :   uint32_t Rva;
     116             :   uint32_t Length;
     117             :   uint32_t Characteristics;
     118             :   StringRef Name;
     119             : 
     120             :   uint32_t RecordOffset;
     121             : };
     122             : 
     123             : // S_COFFGROUP
     124             : class CoffGroupSym : public SymbolRecord {
     125             : public:
     126          30 :   explicit CoffGroupSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     127             :   CoffGroupSym(SymbolRecordKind Kind, uint32_t RecordOffset)
     128             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
     129             : 
     130             :   uint32_t Size;
     131             :   uint32_t Characteristics;
     132             :   uint32_t Offset;
     133             :   uint16_t Segment;
     134             :   StringRef Name;
     135             : 
     136             :   uint32_t RecordOffset;
     137             : };
     138             : 
     139             : class ScopeEndSym : public SymbolRecord {
     140             : public:
     141         358 :   explicit ScopeEndSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     142             :   ScopeEndSym(SymbolRecordKind Kind, uint32_t RecordOffset)
     143             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
     144             : 
     145             :   uint32_t RecordOffset;
     146             : };
     147             : 
     148           2 : class CallerSym : public SymbolRecord {
     149             : public:
     150          15 :   explicit CallerSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     151             :   CallerSym(SymbolRecordKind Kind, uint32_t RecordOffset)
     152             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
     153             : 
     154             :   std::vector<TypeIndex> Indices;
     155             : 
     156             :   uint32_t RecordOffset;
     157             : };
     158             : 
     159             : struct BinaryAnnotationIterator {
     160             :   struct AnnotationData {
     161             :     BinaryAnnotationsOpCode OpCode;
     162             :     StringRef Name;
     163             :     uint32_t U1;
     164             :     uint32_t U2;
     165             :     int32_t S1;
     166             :   };
     167             : 
     168             :   BinaryAnnotationIterator() = default;
     169             :   BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
     170             :   BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
     171         250 :       : Data(Other.Data) {}
     172             : 
     173         125 :   bool operator==(BinaryAnnotationIterator Other) const {
     174         125 :     return Data == Other.Data;
     175             :   }
     176             : 
     177           0 :   bool operator!=(const BinaryAnnotationIterator &Other) const {
     178         125 :     return !(*this == Other);
     179             :   }
     180             : 
     181           0 :   BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
     182           0 :     Data = Other.Data;
     183           0 :     return *this;
     184             :   }
     185             : 
     186          95 :   BinaryAnnotationIterator &operator++() {
     187          95 :     if (!ParseCurrentAnnotation()) {
     188             :       *this = BinaryAnnotationIterator();
     189           0 :       return *this;
     190             :     }
     191          95 :     Data = Next;
     192          95 :     Next = ArrayRef<uint8_t>();
     193             :     Current.reset();
     194             :     return *this;
     195             :   }
     196             : 
     197             :   BinaryAnnotationIterator operator++(int) {
     198             :     BinaryAnnotationIterator Orig(*this);
     199             :     ++(*this);
     200             :     return Orig;
     201             :   }
     202             : 
     203             :   const AnnotationData &operator*() {
     204          95 :     ParseCurrentAnnotation();
     205             :     return Current.getValue();
     206             :   }
     207             : 
     208             : private:
     209         195 :   static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
     210         195 :     if (Annotations.empty())
     211             :       return -1;
     212             : 
     213         195 :     uint8_t FirstByte = Annotations.front();
     214         195 :     Annotations = Annotations.drop_front();
     215             : 
     216         195 :     if ((FirstByte & 0x80) == 0x00)
     217         195 :       return FirstByte;
     218             : 
     219           0 :     if (Annotations.empty())
     220             :       return -1;
     221             : 
     222           0 :     uint8_t SecondByte = Annotations.front();
     223           0 :     Annotations = Annotations.drop_front();
     224             : 
     225           0 :     if ((FirstByte & 0xC0) == 0x80)
     226           0 :       return ((FirstByte & 0x3F) << 8) | SecondByte;
     227             : 
     228           0 :     if (Annotations.empty())
     229             :       return -1;
     230             : 
     231           0 :     uint8_t ThirdByte = Annotations.front();
     232           0 :     Annotations = Annotations.drop_front();
     233             : 
     234           0 :     if (Annotations.empty())
     235             :       return -1;
     236             : 
     237           0 :     uint8_t FourthByte = Annotations.front();
     238           0 :     Annotations = Annotations.drop_front();
     239             : 
     240           0 :     if ((FirstByte & 0xE0) == 0xC0)
     241           0 :       return ((FirstByte & 0x1F) << 24) | (SecondByte << 16) |
     242           0 :              (ThirdByte << 8) | FourthByte;
     243             : 
     244             :     return -1;
     245             :   };
     246             : 
     247             :   static int32_t DecodeSignedOperand(uint32_t Operand) {
     248          14 :     if (Operand & 1)
     249           2 :       return -(Operand >> 1);
     250          48 :     return Operand >> 1;
     251             :   };
     252             : 
     253             :   static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
     254          14 :     return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
     255             :   };
     256             : 
     257         190 :   bool ParseCurrentAnnotation() {
     258         190 :     if (Current.hasValue())
     259             :       return true;
     260             : 
     261          95 :     Next = Data;
     262          95 :     uint32_t Op = GetCompressedAnnotation(Next);
     263             :     AnnotationData Result;
     264             :     Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
     265          95 :     switch (Result.OpCode) {
     266             :     case BinaryAnnotationsOpCode::Invalid:
     267             :       Result.Name = "Invalid";
     268           0 :       Next = ArrayRef<uint8_t>();
     269           0 :       break;
     270             :     case BinaryAnnotationsOpCode::CodeOffset:
     271             :       Result.Name = "CodeOffset";
     272           0 :       Result.U1 = GetCompressedAnnotation(Next);
     273           0 :       break;
     274             :     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
     275             :       Result.Name = "ChangeCodeOffsetBase";
     276           0 :       Result.U1 = GetCompressedAnnotation(Next);
     277           0 :       break;
     278             :     case BinaryAnnotationsOpCode::ChangeCodeOffset:
     279             :       Result.Name = "ChangeCodeOffset";
     280           9 :       Result.U1 = GetCompressedAnnotation(Next);
     281           9 :       break;
     282             :     case BinaryAnnotationsOpCode::ChangeCodeLength:
     283             :       Result.Name = "ChangeCodeLength";
     284          27 :       Result.U1 = GetCompressedAnnotation(Next);
     285          27 :       break;
     286             :     case BinaryAnnotationsOpCode::ChangeFile:
     287             :       Result.Name = "ChangeFile";
     288           4 :       Result.U1 = GetCompressedAnnotation(Next);
     289           4 :       break;
     290             :     case BinaryAnnotationsOpCode::ChangeLineEndDelta:
     291             :       Result.Name = "ChangeLineEndDelta";
     292           0 :       Result.U1 = GetCompressedAnnotation(Next);
     293           0 :       break;
     294             :     case BinaryAnnotationsOpCode::ChangeRangeKind:
     295             :       Result.Name = "ChangeRangeKind";
     296           0 :       Result.U1 = GetCompressedAnnotation(Next);
     297           0 :       break;
     298             :     case BinaryAnnotationsOpCode::ChangeColumnStart:
     299             :       Result.Name = "ChangeColumnStart";
     300           0 :       Result.U1 = GetCompressedAnnotation(Next);
     301           0 :       break;
     302             :     case BinaryAnnotationsOpCode::ChangeColumnEnd:
     303             :       Result.Name = "ChangeColumnEnd";
     304           0 :       Result.U1 = GetCompressedAnnotation(Next);
     305           0 :       break;
     306             :     case BinaryAnnotationsOpCode::ChangeLineOffset:
     307             :       Result.Name = "ChangeLineOffset";
     308             :       Result.S1 = DecodeSignedOperand(Next);
     309             :       break;
     310             :     case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
     311             :       Result.Name = "ChangeColumnEndDelta";
     312             :       Result.S1 = DecodeSignedOperand(Next);
     313             :       break;
     314             :     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
     315             :       Result.Name = "ChangeCodeOffsetAndLineOffset";
     316          36 :       uint32_t Annotation = GetCompressedAnnotation(Next);
     317          36 :       Result.S1 = DecodeSignedOperand(Annotation >> 4);
     318          36 :       Result.U1 = Annotation & 0xf;
     319          36 :       break;
     320             :     }
     321             :     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
     322             :       Result.Name = "ChangeCodeLengthAndCodeOffset";
     323           5 :       Result.U1 = GetCompressedAnnotation(Next);
     324           5 :       Result.U2 = GetCompressedAnnotation(Next);
     325           5 :       break;
     326             :     }
     327             :     }
     328             :     Current = Result;
     329             :     return true;
     330             :   }
     331             : 
     332             :   Optional<AnnotationData> Current;
     333             :   ArrayRef<uint8_t> Data;
     334             :   ArrayRef<uint8_t> Next;
     335             : };
     336             : 
     337             : // S_INLINESITE
     338             : class InlineSiteSym : public SymbolRecord {
     339             : public:
     340          32 :   explicit InlineSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     341             :   InlineSiteSym(uint32_t RecordOffset)
     342             :       : SymbolRecord(SymbolRecordKind::InlineSiteSym),
     343             :         RecordOffset(RecordOffset) {}
     344             : 
     345             :   iterator_range<BinaryAnnotationIterator> annotations() const {
     346             :     return make_range(BinaryAnnotationIterator(AnnotationData),
     347             :                       BinaryAnnotationIterator());
     348             :   }
     349             : 
     350             :   uint32_t Parent;
     351             :   uint32_t End;
     352             :   TypeIndex Inlinee;
     353             :   std::vector<uint8_t> AnnotationData;
     354             : 
     355             :   uint32_t RecordOffset;
     356             : };
     357             : 
     358             : // S_PUB32
     359             : class PublicSym32 : public SymbolRecord {
     360             : public:
     361             :   PublicSym32() : SymbolRecord(SymbolRecordKind::PublicSym32) {}
     362          18 :   explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     363             :   explicit PublicSym32(uint32_t RecordOffset)
     364         442 :       : SymbolRecord(SymbolRecordKind::PublicSym32),
     365         663 :         RecordOffset(RecordOffset) {}
     366             : 
     367             :   PublicSymFlags Flags = PublicSymFlags::None;
     368             :   uint32_t Offset = 0;
     369             :   uint16_t Segment = 0;
     370             :   StringRef Name;
     371             : 
     372             :   uint32_t RecordOffset = 0;
     373             : };
     374             : 
     375             : // S_REGISTER
     376             : class RegisterSym : public SymbolRecord {
     377             : public:
     378           1 :   explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     379             :   RegisterSym(uint32_t RecordOffset)
     380             :       : SymbolRecord(SymbolRecordKind::RegisterSym),
     381             :         RecordOffset(RecordOffset) {}
     382             : 
     383             :   TypeIndex Index;
     384             :   RegisterId Register;
     385             :   StringRef Name;
     386             : 
     387             :   uint32_t RecordOffset;
     388             : };
     389             : 
     390             : // S_PROCREF, S_LPROCREF
     391             : class ProcRefSym : public SymbolRecord {
     392             : public:
     393          17 :   explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     394             :   explicit ProcRefSym(uint32_t RecordOffset)
     395             :       : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
     396             :   }
     397             : 
     398             :   uint32_t SumName;
     399             :   uint32_t SymOffset;
     400             :   uint16_t Module;
     401             :   StringRef Name;
     402             : 
     403             :   uint32_t RecordOffset;
     404             : };
     405             : 
     406             : // S_LOCAL
     407             : class LocalSym : public SymbolRecord {
     408             : public:
     409         231 :   explicit LocalSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     410             :   explicit LocalSym(uint32_t RecordOffset)
     411             :       : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset) {}
     412             : 
     413             :   TypeIndex Type;
     414             :   LocalSymFlags Flags;
     415             :   StringRef Name;
     416             : 
     417             :   uint32_t RecordOffset;
     418             : };
     419             : 
     420             : struct LocalVariableAddrRange {
     421             :   uint32_t OffsetStart;
     422             :   uint16_t ISectStart;
     423             :   uint16_t Range;
     424             : };
     425             : 
     426             : struct LocalVariableAddrGap {
     427             :   uint16_t GapStartOffset;
     428             :   uint16_t Range;
     429             : };
     430             : 
     431             : enum : uint16_t { MaxDefRange = 0xf000 };
     432             : 
     433             : // S_DEFRANGE
     434             : class DefRangeSym : public SymbolRecord {
     435             :   static constexpr uint32_t RelocationOffset = 8;
     436             : 
     437             : public:
     438           0 :   explicit DefRangeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     439             :   explicit DefRangeSym(uint32_t RecordOffset)
     440             :       : SymbolRecord(SymbolRecordKind::DefRangeSym),
     441             :         RecordOffset(RecordOffset) {}
     442             : 
     443           0 :   uint32_t getRelocationOffset() const {
     444           0 :     return RecordOffset + RelocationOffset;
     445             :   }
     446             : 
     447             :   uint32_t Program;
     448             :   LocalVariableAddrRange Range;
     449             :   std::vector<LocalVariableAddrGap> Gaps;
     450             : 
     451             :   uint32_t RecordOffset;
     452             : };
     453             : 
     454             : // S_DEFRANGE_SUBFIELD
     455             : class DefRangeSubfieldSym : public SymbolRecord {
     456             :   static constexpr uint32_t RelocationOffset = 12;
     457             : 
     458             : public:
     459           0 :   explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     460             :   DefRangeSubfieldSym(uint32_t RecordOffset)
     461             :       : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
     462             :         RecordOffset(RecordOffset) {}
     463             : 
     464           0 :   uint32_t getRelocationOffset() const {
     465           0 :     return RecordOffset + RelocationOffset;
     466             :   }
     467             : 
     468             :   uint32_t Program;
     469             :   uint16_t OffsetInParent;
     470             :   LocalVariableAddrRange Range;
     471             :   std::vector<LocalVariableAddrGap> Gaps;
     472             : 
     473             :   uint32_t RecordOffset;
     474             : };
     475             : 
     476             : // S_DEFRANGE_REGISTER
     477             : class DefRangeRegisterSym : public SymbolRecord {
     478             : public:
     479             :   struct Header {
     480             :     ulittle16_t Register;
     481             :     ulittle16_t MayHaveNoName;
     482             :   };
     483             : 
     484          54 :   explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     485             :   DefRangeRegisterSym(uint32_t RecordOffset)
     486             :       : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
     487             :         RecordOffset(RecordOffset) {}
     488             : 
     489          35 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     490             : 
     491             :   Header Hdr;
     492             :   LocalVariableAddrRange Range;
     493             :   std::vector<LocalVariableAddrGap> Gaps;
     494             : 
     495             :   uint32_t RecordOffset;
     496             : };
     497             : 
     498             : // S_DEFRANGE_SUBFIELD_REGISTER
     499             : class DefRangeSubfieldRegisterSym : public SymbolRecord {
     500             : public:
     501             :   struct Header {
     502             :     ulittle16_t Register;
     503             :     ulittle16_t MayHaveNoName;
     504             :     ulittle32_t OffsetInParent;
     505             :   };
     506             : 
     507             :   explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
     508           7 :       : SymbolRecord(Kind) {}
     509             :   DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
     510             :       : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
     511             :         RecordOffset(RecordOffset) {}
     512             : 
     513           7 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     514             : 
     515             :   Header Hdr;
     516             :   LocalVariableAddrRange Range;
     517             :   std::vector<LocalVariableAddrGap> Gaps;
     518             : 
     519             :   uint32_t RecordOffset;
     520             : };
     521             : 
     522             : // S_DEFRANGE_FRAMEPOINTER_REL
     523             : class DefRangeFramePointerRelSym : public SymbolRecord {
     524             :   static constexpr uint32_t RelocationOffset = 8;
     525             : 
     526             : public:
     527             :   explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
     528         160 :       : SymbolRecord(Kind) {}
     529             :   DefRangeFramePointerRelSym(uint32_t RecordOffset)
     530             :       : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
     531             :         RecordOffset(RecordOffset) {}
     532             : 
     533           0 :   uint32_t getRelocationOffset() const {
     534         148 :     return RecordOffset + RelocationOffset;
     535             :   }
     536             : 
     537             :   int32_t Offset;
     538             :   LocalVariableAddrRange Range;
     539             :   std::vector<LocalVariableAddrGap> Gaps;
     540             : 
     541             :   uint32_t RecordOffset;
     542             : };
     543             : 
     544             : // S_DEFRANGE_REGISTER_REL
     545             : class DefRangeRegisterRelSym : public SymbolRecord {
     546             : public:
     547             :   struct Header {
     548             :     ulittle16_t Register;
     549             :     ulittle16_t Flags;
     550             :     little32_t BasePointerOffset;
     551             :   };
     552             : 
     553          25 :   explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     554             :   explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
     555             :       : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
     556             :         RecordOffset(RecordOffset) {}
     557             : 
     558             :   // The flags implement this notional bitfield:
     559             :   //   uint16_t IsSubfield : 1;
     560             :   //   uint16_t Padding : 3;
     561             :   //   uint16_t OffsetInParent : 12;
     562             :   enum : uint16_t {
     563             :     IsSubfieldFlag = 1,
     564             :     OffsetInParentShift = 4,
     565             :   };
     566             : 
     567          20 :   bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
     568          12 :   uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
     569             : 
     570           4 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     571             : 
     572             :   Header Hdr;
     573             :   LocalVariableAddrRange Range;
     574             :   std::vector<LocalVariableAddrGap> Gaps;
     575             : 
     576             :   uint32_t RecordOffset;
     577             : };
     578             : 
     579             : // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
     580             : class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
     581             : public:
     582             :   explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
     583           8 :       : SymbolRecord(Kind) {}
     584             :   explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
     585             :       : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
     586             :         RecordOffset(RecordOffset) {}
     587             : 
     588             :   int32_t Offset;
     589             : 
     590             :   uint32_t RecordOffset;
     591             : };
     592             : 
     593             : // S_BLOCK32
     594             : class BlockSym : public SymbolRecord {
     595             :   static constexpr uint32_t RelocationOffset = 16;
     596             : 
     597             : public:
     598          18 :   explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     599             :   explicit BlockSym(uint32_t RecordOffset)
     600             :       : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
     601             : 
     602           0 :   uint32_t getRelocationOffset() const {
     603          10 :     return RecordOffset + RelocationOffset;
     604             :   }
     605             : 
     606             :   uint32_t Parent;
     607             :   uint32_t End;
     608             :   uint32_t CodeSize;
     609             :   uint32_t CodeOffset;
     610             :   uint16_t Segment;
     611             :   StringRef Name;
     612             : 
     613             :   uint32_t RecordOffset;
     614             : };
     615             : 
     616             : // S_LABEL32
     617             : class LabelSym : public SymbolRecord {
     618             :   static constexpr uint32_t RelocationOffset = 4;
     619             : 
     620             : public:
     621           1 :   explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     622             :   explicit LabelSym(uint32_t RecordOffset)
     623             :       : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
     624             : 
     625           0 :   uint32_t getRelocationOffset() const {
     626           1 :     return RecordOffset + RelocationOffset;
     627             :   }
     628             : 
     629             :   uint32_t CodeOffset;
     630             :   uint16_t Segment;
     631             :   ProcSymFlags Flags;
     632             :   StringRef Name;
     633             : 
     634             :   uint32_t RecordOffset;
     635             : };
     636             : 
     637             : // S_OBJNAME
     638             : class ObjNameSym : public SymbolRecord {
     639             : public:
     640             :   explicit ObjNameSym() : SymbolRecord(SymbolRecordKind::ObjNameSym) {}
     641         195 :   explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     642             :   ObjNameSym(uint32_t RecordOffset)
     643             :       : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
     644             :   }
     645             : 
     646             :   uint32_t Signature;
     647             :   StringRef Name;
     648             : 
     649             :   uint32_t RecordOffset;
     650             : };
     651             : 
     652             : // S_ENVBLOCK
     653             : class EnvBlockSym : public SymbolRecord {
     654             : public:
     655         111 :   explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     656             :   EnvBlockSym(uint32_t RecordOffset)
     657             :       : SymbolRecord(SymbolRecordKind::EnvBlockSym),
     658             :         RecordOffset(RecordOffset) {}
     659             : 
     660             :   std::vector<StringRef> Fields;
     661             : 
     662             :   uint32_t RecordOffset;
     663             : };
     664             : 
     665             : // S_EXPORT
     666             : class ExportSym : public SymbolRecord {
     667             : public:
     668           0 :   explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     669             :   ExportSym(uint32_t RecordOffset)
     670             :       : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
     671             : 
     672             :   uint16_t Ordinal;
     673             :   ExportFlags Flags;
     674             :   StringRef Name;
     675             : 
     676             :   uint32_t RecordOffset;
     677             : };
     678             : 
     679             : // S_FILESTATIC
     680             : class FileStaticSym : public SymbolRecord {
     681             : public:
     682           6 :   explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     683             :   FileStaticSym(uint32_t RecordOffset)
     684             :       : SymbolRecord(SymbolRecordKind::FileStaticSym),
     685             :         RecordOffset(RecordOffset) {}
     686             : 
     687             :   TypeIndex Index;
     688             :   uint32_t ModFilenameOffset;
     689             :   LocalSymFlags Flags;
     690             :   StringRef Name;
     691             : 
     692             :   uint32_t RecordOffset;
     693             : };
     694             : 
     695             : // S_COMPILE2
     696             : class Compile2Sym : public SymbolRecord {
     697             : public:
     698           0 :   explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     699             :   Compile2Sym(uint32_t RecordOffset)
     700             :       : SymbolRecord(SymbolRecordKind::Compile2Sym),
     701             :         RecordOffset(RecordOffset) {}
     702             : 
     703             :   CompileSym2Flags Flags;
     704             :   CPUType Machine;
     705             :   uint16_t VersionFrontendMajor;
     706             :   uint16_t VersionFrontendMinor;
     707             :   uint16_t VersionFrontendBuild;
     708             :   uint16_t VersionBackendMajor;
     709             :   uint16_t VersionBackendMinor;
     710             :   uint16_t VersionBackendBuild;
     711             :   StringRef Version;
     712             :   std::vector<StringRef> ExtraStrings;
     713             : 
     714           0 :   uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
     715           0 :   uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
     716             : 
     717             :   uint32_t RecordOffset;
     718             : };
     719             : 
     720             : // S_COMPILE3
     721             : class Compile3Sym : public SymbolRecord {
     722             : public:
     723             :   Compile3Sym() : SymbolRecord(SymbolRecordKind::Compile3Sym) {}
     724         284 :   explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     725             :   Compile3Sym(uint32_t RecordOffset)
     726             :       : SymbolRecord(SymbolRecordKind::Compile3Sym),
     727             :         RecordOffset(RecordOffset) {}
     728             : 
     729             :   CompileSym3Flags Flags;
     730             :   CPUType Machine;
     731             :   uint16_t VersionFrontendMajor;
     732             :   uint16_t VersionFrontendMinor;
     733             :   uint16_t VersionFrontendBuild;
     734             :   uint16_t VersionFrontendQFE;
     735             :   uint16_t VersionBackendMajor;
     736             :   uint16_t VersionBackendMinor;
     737             :   uint16_t VersionBackendBuild;
     738             :   uint16_t VersionBackendQFE;
     739             :   StringRef Version;
     740             : 
     741             :   void setLanguage(SourceLanguage Lang) {
     742          88 :     Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
     743             :   }
     744             : 
     745           0 :   SourceLanguage getLanguage() const {
     746           0 :     return static_cast<SourceLanguage>(static_cast<uint32_t>(Flags) & 0xFF);
     747             :   }
     748           0 :   CompileSym3Flags getFlags() const {
     749          99 :     return static_cast<CompileSym3Flags>(static_cast<uint32_t>(Flags) & ~0xFF);
     750             :   }
     751             : 
     752             :   bool hasOptimizations() const {
     753             :     return CompileSym3Flags::None !=
     754             :            (getFlags() & (CompileSym3Flags::PGO | CompileSym3Flags::LTCG));
     755             :   }
     756             : 
     757             :   uint32_t RecordOffset;
     758             : };
     759             : 
     760             : // S_FRAMEPROC
     761             : class FrameProcSym : public SymbolRecord {
     762             : public:
     763         271 :   explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     764             :   explicit FrameProcSym(uint32_t RecordOffset)
     765             :       : SymbolRecord(SymbolRecordKind::FrameProcSym),
     766             :         RecordOffset(RecordOffset) {}
     767             : 
     768             :   uint32_t TotalFrameBytes;
     769             :   uint32_t PaddingFrameBytes;
     770             :   uint32_t OffsetToPadding;
     771             :   uint32_t BytesOfCalleeSavedRegisters;
     772             :   uint32_t OffsetOfExceptionHandler;
     773             :   uint16_t SectionIdOfExceptionHandler;
     774             :   FrameProcedureOptions Flags;
     775             : 
     776             :   /// Extract the register this frame uses to refer to local variables.
     777           0 :   RegisterId getLocalFramePtrReg(CPUType CPU) const {
     778         422 :     return decodeFramePtrReg(
     779         211 :         EncodedFramePtrReg((uint32_t(Flags) >> 14U) & 0x3U), CPU);
     780             :   }
     781             : 
     782             :   /// Extract the register this frame uses to refer to parameters.
     783           0 :   RegisterId getParamFramePtrReg(CPUType CPU) const {
     784         422 :     return decodeFramePtrReg(
     785         211 :         EncodedFramePtrReg((uint32_t(Flags) >> 16U) & 0x3U), CPU);
     786             :   }
     787             : 
     788             :   uint32_t RecordOffset;
     789             : 
     790             : private:
     791             : };
     792             : 
     793             : // S_CALLSITEINFO
     794             : class CallSiteInfoSym : public SymbolRecord {
     795             :   static constexpr uint32_t RelocationOffset = 4;
     796             : 
     797             : public:
     798           0 :   explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     799             :   explicit CallSiteInfoSym(uint32_t RecordOffset)
     800             :       : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
     801             : 
     802           0 :   uint32_t getRelocationOffset() const {
     803           0 :     return RecordOffset + RelocationOffset;
     804             :   }
     805             : 
     806             :   uint32_t CodeOffset;
     807             :   uint16_t Segment;
     808             :   TypeIndex Type;
     809             : 
     810             :   uint32_t RecordOffset;
     811             : };
     812             : 
     813             : // S_HEAPALLOCSITE
     814             : class HeapAllocationSiteSym : public SymbolRecord {
     815             :   static constexpr uint32_t RelocationOffset = 4;
     816             : 
     817             : public:
     818           2 :   explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     819             :   explicit HeapAllocationSiteSym(uint32_t RecordOffset)
     820             :       : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
     821             :         RecordOffset(RecordOffset) {}
     822             : 
     823           0 :   uint32_t getRelocationOffset() const {
     824           0 :     return RecordOffset + RelocationOffset;
     825             :   }
     826             : 
     827             :   uint32_t CodeOffset;
     828             :   uint16_t Segment;
     829             :   uint16_t CallInstructionSize;
     830             :   TypeIndex Type;
     831             : 
     832             :   uint32_t RecordOffset;
     833             : };
     834             : 
     835             : // S_FRAMECOOKIE
     836             : class FrameCookieSym : public SymbolRecord {
     837             :   static constexpr uint32_t RelocationOffset = 4;
     838             : 
     839             : public:
     840           0 :   explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     841             :   explicit FrameCookieSym(uint32_t RecordOffset)
     842             :       : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
     843             : 
     844           0 :   uint32_t getRelocationOffset() const {
     845           0 :     return RecordOffset + RelocationOffset;
     846             :   }
     847             : 
     848             :   uint32_t CodeOffset;
     849             :   uint16_t Register;
     850             :   FrameCookieKind CookieKind;
     851             :   uint8_t Flags;
     852             : 
     853             :   uint32_t RecordOffset;
     854             : };
     855             : 
     856             : // S_UDT, S_COBOLUDT
     857             : class UDTSym : public SymbolRecord {
     858             : public:
     859         765 :   explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     860             :   explicit UDTSym(uint32_t RecordOffset)
     861         120 :       : SymbolRecord(SymbolRecordKind::UDTSym) {}
     862             : 
     863             :   TypeIndex Type;
     864             :   StringRef Name;
     865             : 
     866             :   uint32_t RecordOffset;
     867             : };
     868             : 
     869             : // S_BUILDINFO
     870             : class BuildInfoSym : public SymbolRecord {
     871             : public:
     872         155 :   explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     873             :   BuildInfoSym(uint32_t RecordOffset)
     874             :       : SymbolRecord(SymbolRecordKind::BuildInfoSym),
     875             :         RecordOffset(RecordOffset) {}
     876             : 
     877             :   TypeIndex BuildId;
     878             : 
     879             :   uint32_t RecordOffset;
     880             : };
     881             : 
     882             : // S_BPREL32
     883             : class BPRelativeSym : public SymbolRecord {
     884             : public:
     885           9 :   explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     886             :   explicit BPRelativeSym(uint32_t RecordOffset)
     887             :       : SymbolRecord(SymbolRecordKind::BPRelativeSym),
     888             :         RecordOffset(RecordOffset) {}
     889             : 
     890             :   int32_t Offset;
     891             :   TypeIndex Type;
     892             :   StringRef Name;
     893             : 
     894             :   uint32_t RecordOffset;
     895             : };
     896             : 
     897             : // S_REGREL32
     898             : class RegRelativeSym : public SymbolRecord {
     899             : public:
     900          47 :   explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     901             :   explicit RegRelativeSym(uint32_t RecordOffset)
     902             :       : SymbolRecord(SymbolRecordKind::RegRelativeSym),
     903             :         RecordOffset(RecordOffset) {}
     904             : 
     905             :   uint32_t Offset;
     906             :   TypeIndex Type;
     907             :   RegisterId Register;
     908             :   StringRef Name;
     909             : 
     910             :   uint32_t RecordOffset;
     911             : };
     912             : 
     913             : // S_CONSTANT, S_MANCONSTANT
     914           0 : class ConstantSym : public SymbolRecord {
     915             : public:
     916           0 :   explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     917             :   ConstantSym(uint32_t RecordOffset)
     918           0 :       : SymbolRecord(SymbolRecordKind::ConstantSym),
     919           0 :         RecordOffset(RecordOffset) {}
     920             : 
     921             :   TypeIndex Type;
     922             :   APSInt Value;
     923             :   StringRef Name;
     924             : 
     925             :   uint32_t RecordOffset;
     926             : };
     927             : 
     928             : // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
     929             : class DataSym : public SymbolRecord {
     930             :   static constexpr uint32_t RelocationOffset = 8;
     931             : 
     932             : public:
     933          96 :   explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     934             :   DataSym(uint32_t RecordOffset)
     935             :       : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
     936             : 
     937           0 :   uint32_t getRelocationOffset() const {
     938          57 :     return RecordOffset + RelocationOffset;
     939             :   }
     940             : 
     941             :   TypeIndex Type;
     942             :   uint32_t DataOffset;
     943             :   uint16_t Segment;
     944             :   StringRef Name;
     945             : 
     946             :   uint32_t RecordOffset;
     947             : };
     948             : 
     949             : // S_LTHREAD32, S_GTHREAD32
     950             : class ThreadLocalDataSym : public SymbolRecord {
     951             :   static constexpr uint32_t RelocationOffset = 8;
     952             : 
     953             : public:
     954           2 :   explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     955             :   explicit ThreadLocalDataSym(uint32_t RecordOffset)
     956             :       : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
     957             :         RecordOffset(RecordOffset) {}
     958             : 
     959           0 :   uint32_t getRelocationOffset() const {
     960           1 :     return RecordOffset + RelocationOffset;
     961             :   }
     962             : 
     963             :   TypeIndex Type;
     964             :   uint32_t DataOffset;
     965             :   uint16_t Segment;
     966             :   StringRef Name;
     967             : 
     968             :   uint32_t RecordOffset;
     969             : };
     970             : 
     971             : // S_UNAMESPACE
     972             : class UsingNamespaceSym : public SymbolRecord {
     973             : public:
     974           9 :   explicit UsingNamespaceSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     975             :   explicit UsingNamespaceSym(uint32_t RecordOffset)
     976             :       : SymbolRecord(SymbolRecordKind::RegRelativeSym),
     977             :         RecordOffset(RecordOffset) {}
     978             : 
     979             :   StringRef Name;
     980             : 
     981             :   uint32_t RecordOffset;
     982             : };
     983             : 
     984             : // S_ANNOTATION
     985             : 
     986             : using CVSymbol = CVRecord<SymbolKind>;
     987             : using CVSymbolArray = VarStreamArray<CVSymbol>;
     988             : 
     989             : Expected<CVSymbol> readSymbolFromStream(BinaryStreamRef Stream,
     990             :                                         uint32_t Offset);
     991             : 
     992             : } // end namespace codeview
     993             : } // end namespace llvm
     994             : 
     995             : #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H

Generated by: LCOV version 1.13