LCOV - code coverage report
Current view: top level - include/llvm/DebugInfo/CodeView - SymbolRecord.h (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 116 189 61.4 %
Date: 2017-09-14 15:23:50 Functions: 4 5 80.0 %
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        2159 :   explicit SymbolRecord(SymbolRecordKind Kind) : Kind(Kind) {}
      33             : 
      34             : public:
      35          20 :   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         748 :   explicit ProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
      47             :   ProcSym(SymbolRecordKind Kind, uint32_t RecordOffset)
      48             :       : SymbolRecord(Kind), RecordOffset(RecordOffset) {}
      49             : 
      50             :   uint32_t getRelocationOffset() const {
      51         128 :     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           0 :   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          12 :   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         444 :   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          90 :   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         438 :   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           4 : class CallerSym : public SymbolRecord {
     149             : public:
     150           6 :   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         634 : struct BinaryAnnotationIterator {
     160         166 :   struct AnnotationData {
     161             :     BinaryAnnotationsOpCode OpCode;
     162             :     StringRef Name;
     163             :     uint32_t U1;
     164             :     uint32_t U2;
     165             :     int32_t S1;
     166             :   };
     167             : 
     168          78 :   BinaryAnnotationIterator() = default;
     169          78 :   BinaryAnnotationIterator(ArrayRef<uint8_t> Annotations) : Data(Annotations) {}
     170             :   BinaryAnnotationIterator(const BinaryAnnotationIterator &Other)
     171         743 :       : Data(Other.Data) {}
     172             : 
     173             :   bool operator==(BinaryAnnotationIterator Other) const {
     174             :     return Data == Other.Data;
     175             :   }
     176             : 
     177         109 :   bool operator!=(const BinaryAnnotationIterator &Other) const {
     178         327 :     return !(*this == Other);
     179             :   }
     180             : 
     181             :   BinaryAnnotationIterator &operator=(const BinaryAnnotationIterator Other) {
     182           0 :     Data = Other.Data;
     183             :     return *this;
     184             :   }
     185             : 
     186          83 :   BinaryAnnotationIterator &operator++() {
     187          83 :     if (!ParseCurrentAnnotation()) {
     188           0 :       *this = BinaryAnnotationIterator();
     189           0 :       return *this;
     190             :     }
     191          83 :     Data = Next;
     192          83 :     Next = ArrayRef<uint8_t>();
     193          83 :     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          83 :     ParseCurrentAnnotation();
     205         166 :     return Current.getValue();
     206             :   }
     207             : 
     208             : private:
     209         169 :   static uint32_t GetCompressedAnnotation(ArrayRef<uint8_t> &Annotations) {
     210         169 :     if (Annotations.empty())
     211             :       return -1;
     212             : 
     213         169 :     uint8_t FirstByte = Annotations.front();
     214         169 :     Annotations = Annotations.drop_front();
     215             : 
     216         169 :     if ((FirstByte & 0x80) == 0x00)
     217         169 :       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          44 :     if (Operand & 1)
     249           2 :       return -(Operand >> 1);
     250          42 :     return Operand >> 1;
     251             :   };
     252             : 
     253             :   static int32_t DecodeSignedOperand(ArrayRef<uint8_t> &Annotations) {
     254          12 :     return DecodeSignedOperand(GetCompressedAnnotation(Annotations));
     255             :   };
     256             : 
     257         166 :   bool ParseCurrentAnnotation() {
     258         166 :     if (Current.hasValue())
     259             :       return true;
     260             : 
     261          83 :     Next = Data;
     262          83 :     uint32_t Op = GetCompressedAnnotation(Next);
     263          83 :     AnnotationData Result;
     264          83 :     Result.OpCode = static_cast<BinaryAnnotationsOpCode>(Op);
     265          83 :     switch (Result.OpCode) {
     266           0 :     case BinaryAnnotationsOpCode::Invalid:
     267           0 :       Result.Name = "Invalid";
     268           0 :       Next = ArrayRef<uint8_t>();
     269           0 :       break;
     270           0 :     case BinaryAnnotationsOpCode::CodeOffset:
     271           0 :       Result.Name = "CodeOffset";
     272           0 :       Result.U1 = GetCompressedAnnotation(Next);
     273           0 :       break;
     274           0 :     case BinaryAnnotationsOpCode::ChangeCodeOffsetBase:
     275           0 :       Result.Name = "ChangeCodeOffsetBase";
     276           0 :       Result.U1 = GetCompressedAnnotation(Next);
     277           0 :       break;
     278           9 :     case BinaryAnnotationsOpCode::ChangeCodeOffset:
     279           9 :       Result.Name = "ChangeCodeOffset";
     280           9 :       Result.U1 = GetCompressedAnnotation(Next);
     281           9 :       break;
     282          23 :     case BinaryAnnotationsOpCode::ChangeCodeLength:
     283          23 :       Result.Name = "ChangeCodeLength";
     284          23 :       Result.U1 = GetCompressedAnnotation(Next);
     285          23 :       break;
     286           4 :     case BinaryAnnotationsOpCode::ChangeFile:
     287           4 :       Result.Name = "ChangeFile";
     288           4 :       Result.U1 = GetCompressedAnnotation(Next);
     289           4 :       break;
     290           0 :     case BinaryAnnotationsOpCode::ChangeLineEndDelta:
     291           0 :       Result.Name = "ChangeLineEndDelta";
     292           0 :       Result.U1 = GetCompressedAnnotation(Next);
     293           0 :       break;
     294           0 :     case BinaryAnnotationsOpCode::ChangeRangeKind:
     295           0 :       Result.Name = "ChangeRangeKind";
     296           0 :       Result.U1 = GetCompressedAnnotation(Next);
     297           0 :       break;
     298           0 :     case BinaryAnnotationsOpCode::ChangeColumnStart:
     299           0 :       Result.Name = "ChangeColumnStart";
     300           0 :       Result.U1 = GetCompressedAnnotation(Next);
     301           0 :       break;
     302           0 :     case BinaryAnnotationsOpCode::ChangeColumnEnd:
     303           0 :       Result.Name = "ChangeColumnEnd";
     304           0 :       Result.U1 = GetCompressedAnnotation(Next);
     305           0 :       break;
     306          12 :     case BinaryAnnotationsOpCode::ChangeLineOffset:
     307          12 :       Result.Name = "ChangeLineOffset";
     308          12 :       Result.S1 = DecodeSignedOperand(Next);
     309             :       break;
     310           0 :     case BinaryAnnotationsOpCode::ChangeColumnEndDelta:
     311           0 :       Result.Name = "ChangeColumnEndDelta";
     312           0 :       Result.S1 = DecodeSignedOperand(Next);
     313             :       break;
     314          32 :     case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: {
     315          32 :       Result.Name = "ChangeCodeOffsetAndLineOffset";
     316          32 :       uint32_t Annotation = GetCompressedAnnotation(Next);
     317          64 :       Result.S1 = DecodeSignedOperand(Annotation >> 4);
     318          32 :       Result.U1 = Annotation & 0xf;
     319          32 :       break;
     320             :     }
     321           3 :     case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: {
     322           3 :       Result.Name = "ChangeCodeLengthAndCodeOffset";
     323           3 :       Result.U1 = GetCompressedAnnotation(Next);
     324           3 :       Result.U2 = GetCompressedAnnotation(Next);
     325           3 :       break;
     326             :     }
     327             :     }
     328          83 :     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          52 : class InlineSiteSym : public SymbolRecord {
     339             : public:
     340         104 :   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         104 :     return make_range(BinaryAnnotationIterator(AnnotationData),
     347         104 :                       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          27 :   explicit PublicSym32(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     362             :   explicit PublicSym32(uint32_t RecordOffset)
     363         178 :       : SymbolRecord(SymbolRecordKind::PublicSym32),
     364         445 :         RecordOffset(RecordOffset) {}
     365             : 
     366             :   PublicSymFlags Flags = PublicSymFlags::None;
     367             :   uint32_t Offset = 0;
     368             :   uint16_t Segment = 0;
     369             :   StringRef Name;
     370             : 
     371             :   uint32_t RecordOffset = 0;
     372             : };
     373             : 
     374             : // S_REGISTER
     375             : class RegisterSym : public SymbolRecord {
     376             : public:
     377           0 :   explicit RegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     378             :   RegisterSym(uint32_t RecordOffset)
     379             :       : SymbolRecord(SymbolRecordKind::RegisterSym),
     380             :         RecordOffset(RecordOffset) {}
     381             : 
     382             :   TypeIndex Index;
     383             :   RegisterId Register;
     384             :   StringRef Name;
     385             : 
     386             :   uint32_t RecordOffset;
     387             : };
     388             : 
     389             : // S_PROCREF, S_LPROCREF
     390             : class ProcRefSym : public SymbolRecord {
     391             : public:
     392         144 :   explicit ProcRefSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     393             :   explicit ProcRefSym(uint32_t RecordOffset)
     394             :       : SymbolRecord(SymbolRecordKind::ProcRefSym), RecordOffset(RecordOffset) {
     395             :   }
     396             : 
     397             :   uint32_t SumName;
     398             :   uint32_t SymOffset;
     399             :   uint16_t Module;
     400             :   StringRef Name;
     401             : 
     402             :   uint32_t RecordOffset;
     403             : };
     404             : 
     405             : // S_LOCAL
     406             : class LocalSym : public SymbolRecord {
     407             : public:
     408         452 :   explicit LocalSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     409             :   explicit LocalSym(uint32_t RecordOffset)
     410             :       : SymbolRecord(SymbolRecordKind::LocalSym), RecordOffset(RecordOffset) {}
     411             : 
     412             :   TypeIndex Type;
     413             :   LocalSymFlags Flags;
     414             :   StringRef Name;
     415             : 
     416             :   uint32_t RecordOffset;
     417             : };
     418             : 
     419             : struct LocalVariableAddrRange {
     420             :   uint32_t OffsetStart;
     421             :   uint16_t ISectStart;
     422             :   uint16_t Range;
     423             : };
     424             : 
     425             : struct LocalVariableAddrGap {
     426             :   uint16_t GapStartOffset;
     427             :   uint16_t Range;
     428             : };
     429             : 
     430             : enum : uint16_t { MaxDefRange = 0xf000 };
     431             : 
     432             : // S_DEFRANGE
     433           0 : class DefRangeSym : public SymbolRecord {
     434             :   static constexpr uint32_t RelocationOffset = 8;
     435             : 
     436             : public:
     437           0 :   explicit DefRangeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     438             :   explicit DefRangeSym(uint32_t RecordOffset)
     439             :       : SymbolRecord(SymbolRecordKind::DefRangeSym),
     440             :         RecordOffset(RecordOffset) {}
     441             : 
     442             :   uint32_t getRelocationOffset() const {
     443           0 :     return RecordOffset + RelocationOffset;
     444             :   }
     445             : 
     446             :   uint32_t Program;
     447             :   LocalVariableAddrRange Range;
     448             :   std::vector<LocalVariableAddrGap> Gaps;
     449             : 
     450             :   uint32_t RecordOffset;
     451             : };
     452             : 
     453             : // S_DEFRANGE_SUBFIELD
     454           0 : class DefRangeSubfieldSym : public SymbolRecord {
     455             :   static constexpr uint32_t RelocationOffset = 12;
     456             : 
     457             : public:
     458           0 :   explicit DefRangeSubfieldSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     459             :   DefRangeSubfieldSym(uint32_t RecordOffset)
     460             :       : SymbolRecord(SymbolRecordKind::DefRangeSubfieldSym),
     461             :         RecordOffset(RecordOffset) {}
     462             : 
     463             :   uint32_t getRelocationOffset() const {
     464           0 :     return RecordOffset + RelocationOffset;
     465             :   }
     466             : 
     467             :   uint32_t Program;
     468             :   uint16_t OffsetInParent;
     469             :   LocalVariableAddrRange Range;
     470             :   std::vector<LocalVariableAddrGap> Gaps;
     471             : 
     472             :   uint32_t RecordOffset;
     473             : };
     474             : 
     475             : // S_DEFRANGE_REGISTER
     476          72 : class DefRangeRegisterSym : public SymbolRecord {
     477             : public:
     478             :   struct Header {
     479             :     ulittle16_t Register;
     480             :     ulittle16_t MayHaveNoName;
     481             :   };
     482             : 
     483          45 :   explicit DefRangeRegisterSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     484             :   DefRangeRegisterSym(uint32_t RecordOffset)
     485          21 :       : SymbolRecord(SymbolRecordKind::DefRangeRegisterSym),
     486          63 :         RecordOffset(RecordOffset) {}
     487             : 
     488          15 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     489             : 
     490             :   Header Hdr;
     491             :   LocalVariableAddrRange Range;
     492             :   std::vector<LocalVariableAddrGap> Gaps;
     493             : 
     494             :   uint32_t RecordOffset;
     495             : };
     496             : 
     497             : // S_DEFRANGE_SUBFIELD_REGISTER
     498          30 : class DefRangeSubfieldRegisterSym : public SymbolRecord {
     499             : public:
     500             :   struct Header {
     501             :     ulittle16_t Register;
     502             :     ulittle16_t MayHaveNoName;
     503             :     ulittle32_t OffsetInParent;
     504             :   };
     505             : 
     506             :   explicit DefRangeSubfieldRegisterSym(SymbolRecordKind Kind)
     507          15 :       : SymbolRecord(Kind) {}
     508             :   DefRangeSubfieldRegisterSym(uint32_t RecordOffset)
     509          10 :       : SymbolRecord(SymbolRecordKind::DefRangeSubfieldRegisterSym),
     510          30 :         RecordOffset(RecordOffset) {}
     511             : 
     512           5 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     513             : 
     514             :   Header Hdr;
     515             :   LocalVariableAddrRange Range;
     516             :   std::vector<LocalVariableAddrGap> Gaps;
     517             : 
     518             :   uint32_t RecordOffset;
     519             : };
     520             : 
     521             : // S_DEFRANGE_FRAMEPOINTER_REL
     522           2 : class DefRangeFramePointerRelSym : public SymbolRecord {
     523             :   static constexpr uint32_t RelocationOffset = 8;
     524             : 
     525             : public:
     526             :   explicit DefRangeFramePointerRelSym(SymbolRecordKind Kind)
     527           3 :       : SymbolRecord(Kind) {}
     528             :   DefRangeFramePointerRelSym(uint32_t RecordOffset)
     529             :       : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelSym),
     530             :         RecordOffset(RecordOffset) {}
     531             : 
     532             :   uint32_t getRelocationOffset() const {
     533           1 :     return RecordOffset + RelocationOffset;
     534             :   }
     535             : 
     536             :   int32_t Offset;
     537             :   LocalVariableAddrRange Range;
     538             :   std::vector<LocalVariableAddrGap> Gaps;
     539             : 
     540             :   uint32_t RecordOffset;
     541             : };
     542             : 
     543             : // S_DEFRANGE_REGISTER_REL
     544         412 : class DefRangeRegisterRelSym : public SymbolRecord {
     545             : public:
     546             :   struct Header {
     547             :     ulittle16_t Register;
     548             :     ulittle16_t Flags;
     549             :     little32_t BasePointerOffset;
     550             :   };
     551             : 
     552         300 :   explicit DefRangeRegisterRelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     553             :   explicit DefRangeRegisterRelSym(uint32_t RecordOffset)
     554         106 :       : SymbolRecord(SymbolRecordKind::DefRangeRegisterRelSym),
     555         318 :         RecordOffset(RecordOffset) {}
     556             : 
     557             :   // The flags implement this notional bitfield:
     558             :   //   uint16_t IsSubfield : 1;
     559             :   //   uint16_t Padding : 3;
     560             :   //   uint16_t OffsetInParent : 12;
     561             :   enum : uint16_t {
     562             :     IsSubfieldFlag = 1,
     563             :     OffsetInParentShift = 4,
     564             :   };
     565             : 
     566         190 :   bool hasSpilledUDTMember() const { return Hdr.Flags & IsSubfieldFlag; }
     567         190 :   uint16_t offsetInParent() const { return Hdr.Flags >> OffsetInParentShift; }
     568             : 
     569          87 :   uint32_t getRelocationOffset() const { return RecordOffset + sizeof(Header); }
     570             : 
     571             :   Header Hdr;
     572             :   LocalVariableAddrRange Range;
     573             :   std::vector<LocalVariableAddrGap> Gaps;
     574             : 
     575             :   uint32_t RecordOffset;
     576             : };
     577             : 
     578             : // S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE
     579             : class DefRangeFramePointerRelFullScopeSym : public SymbolRecord {
     580             : public:
     581             :   explicit DefRangeFramePointerRelFullScopeSym(SymbolRecordKind Kind)
     582           0 :       : SymbolRecord(Kind) {}
     583             :   explicit DefRangeFramePointerRelFullScopeSym(uint32_t RecordOffset)
     584             :       : SymbolRecord(SymbolRecordKind::DefRangeFramePointerRelFullScopeSym),
     585             :         RecordOffset(RecordOffset) {}
     586             : 
     587             :   int32_t Offset;
     588             : 
     589             :   uint32_t RecordOffset;
     590             : };
     591             : 
     592             : // S_BLOCK32
     593             : class BlockSym : public SymbolRecord {
     594             :   static constexpr uint32_t RelocationOffset = 16;
     595             : 
     596             : public:
     597          24 :   explicit BlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     598             :   explicit BlockSym(uint32_t RecordOffset)
     599             :       : SymbolRecord(SymbolRecordKind::BlockSym), RecordOffset(RecordOffset) {}
     600             : 
     601             :   uint32_t getRelocationOffset() const {
     602           0 :     return RecordOffset + RelocationOffset;
     603             :   }
     604             : 
     605             :   uint32_t Parent;
     606             :   uint32_t End;
     607             :   uint32_t CodeSize;
     608             :   uint32_t CodeOffset;
     609             :   uint16_t Segment;
     610             :   StringRef Name;
     611             : 
     612             :   uint32_t RecordOffset;
     613             : };
     614             : 
     615             : // S_LABEL32
     616             : class LabelSym : public SymbolRecord {
     617             :   static constexpr uint32_t RelocationOffset = 4;
     618             : 
     619             : public:
     620           3 :   explicit LabelSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     621             :   explicit LabelSym(uint32_t RecordOffset)
     622             :       : SymbolRecord(SymbolRecordKind::LabelSym), RecordOffset(RecordOffset) {}
     623             : 
     624             :   uint32_t getRelocationOffset() const {
     625           1 :     return RecordOffset + RelocationOffset;
     626             :   }
     627             : 
     628             :   uint32_t CodeOffset;
     629             :   uint16_t Segment;
     630             :   ProcSymFlags Flags;
     631             :   StringRef Name;
     632             : 
     633             :   uint32_t RecordOffset;
     634             : };
     635             : 
     636             : // S_OBJNAME
     637             : class ObjNameSym : public SymbolRecord {
     638             : public:
     639         308 :   explicit ObjNameSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     640             :   ObjNameSym(uint32_t RecordOffset)
     641             :       : SymbolRecord(SymbolRecordKind::ObjNameSym), RecordOffset(RecordOffset) {
     642             :   }
     643             : 
     644             :   uint32_t Signature;
     645             :   StringRef Name;
     646             : 
     647             :   uint32_t RecordOffset;
     648             : };
     649             : 
     650             : // S_ENVBLOCK
     651         116 : class EnvBlockSym : public SymbolRecord {
     652             : public:
     653         174 :   explicit EnvBlockSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     654             :   EnvBlockSym(uint32_t RecordOffset)
     655             :       : SymbolRecord(SymbolRecordKind::EnvBlockSym),
     656             :         RecordOffset(RecordOffset) {}
     657             : 
     658             :   std::vector<StringRef> Fields;
     659             : 
     660             :   uint32_t RecordOffset;
     661             : };
     662             : 
     663             : // S_EXPORT
     664             : class ExportSym : public SymbolRecord {
     665             : public:
     666           0 :   explicit ExportSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     667             :   ExportSym(uint32_t RecordOffset)
     668             :       : SymbolRecord(SymbolRecordKind::ExportSym), RecordOffset(RecordOffset) {}
     669             : 
     670             :   uint16_t Ordinal;
     671             :   ExportFlags Flags;
     672             :   StringRef Name;
     673             : 
     674             :   uint32_t RecordOffset;
     675             : };
     676             : 
     677             : // S_FILESTATIC
     678             : class FileStaticSym : public SymbolRecord {
     679             : public:
     680           0 :   explicit FileStaticSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     681             :   FileStaticSym(uint32_t RecordOffset)
     682             :       : SymbolRecord(SymbolRecordKind::FileStaticSym),
     683             :         RecordOffset(RecordOffset) {}
     684             : 
     685             :   TypeIndex Index;
     686             :   uint32_t ModFilenameOffset;
     687             :   LocalSymFlags Flags;
     688             :   StringRef Name;
     689             : 
     690             :   uint32_t RecordOffset;
     691             : };
     692             : 
     693             : // S_COMPILE2
     694           0 : class Compile2Sym : public SymbolRecord {
     695             : public:
     696           0 :   explicit Compile2Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     697             :   Compile2Sym(uint32_t RecordOffset)
     698             :       : SymbolRecord(SymbolRecordKind::Compile2Sym),
     699             :         RecordOffset(RecordOffset) {}
     700             : 
     701             :   CompileSym2Flags Flags;
     702             :   CPUType Machine;
     703             :   uint16_t VersionFrontendMajor;
     704             :   uint16_t VersionFrontendMinor;
     705             :   uint16_t VersionFrontendBuild;
     706             :   uint16_t VersionBackendMajor;
     707             :   uint16_t VersionBackendMinor;
     708             :   uint16_t VersionBackendBuild;
     709             :   StringRef Version;
     710             :   std::vector<StringRef> ExtraStrings;
     711             : 
     712             :   uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
     713           0 :   uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
     714             : 
     715             :   uint32_t RecordOffset;
     716             : };
     717             : 
     718             : // S_COMPILE3
     719             : class Compile3Sym : public SymbolRecord {
     720             : public:
     721         473 :   explicit Compile3Sym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     722             :   Compile3Sym(uint32_t RecordOffset)
     723             :       : SymbolRecord(SymbolRecordKind::Compile3Sym),
     724             :         RecordOffset(RecordOffset) {}
     725             : 
     726             :   CompileSym3Flags Flags;
     727             :   CPUType Machine;
     728             :   uint16_t VersionFrontendMajor;
     729             :   uint16_t VersionFrontendMinor;
     730             :   uint16_t VersionFrontendBuild;
     731             :   uint16_t VersionFrontendQFE;
     732             :   uint16_t VersionBackendMajor;
     733             :   uint16_t VersionBackendMinor;
     734             :   uint16_t VersionBackendBuild;
     735             :   uint16_t VersionBackendQFE;
     736             :   StringRef Version;
     737             : 
     738             :   void setLanguage(SourceLanguage Lang) {
     739          40 :     Flags = CompileSym3Flags((uint32_t(Flags) & 0xFFFFFF00) | uint32_t(Lang));
     740             :   }
     741             : 
     742             :   uint8_t getLanguage() const { return static_cast<uint32_t>(Flags) & 0xFF; }
     743          74 :   uint32_t getFlags() const { return static_cast<uint32_t>(Flags) & ~0xFF; }
     744             : 
     745             :   uint32_t RecordOffset;
     746             : };
     747             : 
     748             : // S_FRAMEPROC
     749             : class FrameProcSym : public SymbolRecord {
     750             : public:
     751         164 :   explicit FrameProcSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     752             :   explicit FrameProcSym(uint32_t RecordOffset)
     753             :       : SymbolRecord(SymbolRecordKind::FrameProcSym),
     754             :         RecordOffset(RecordOffset) {}
     755             : 
     756             :   uint32_t TotalFrameBytes;
     757             :   uint32_t PaddingFrameBytes;
     758             :   uint32_t OffsetToPadding;
     759             :   uint32_t BytesOfCalleeSavedRegisters;
     760             :   uint32_t OffsetOfExceptionHandler;
     761             :   uint16_t SectionIdOfExceptionHandler;
     762             :   FrameProcedureOptions Flags;
     763             : 
     764             :   uint32_t RecordOffset;
     765             : };
     766             : 
     767             : // S_CALLSITEINFO
     768             : class CallSiteInfoSym : public SymbolRecord {
     769             :   static constexpr uint32_t RelocationOffset = 4;
     770             : 
     771             : public:
     772           0 :   explicit CallSiteInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     773             :   explicit CallSiteInfoSym(uint32_t RecordOffset)
     774             :       : SymbolRecord(SymbolRecordKind::CallSiteInfoSym) {}
     775             : 
     776             :   uint32_t getRelocationOffset() const {
     777           0 :     return RecordOffset + RelocationOffset;
     778             :   }
     779             : 
     780             :   uint32_t CodeOffset;
     781             :   uint16_t Segment;
     782             :   TypeIndex Type;
     783             : 
     784             :   uint32_t RecordOffset;
     785             : };
     786             : 
     787             : // S_HEAPALLOCSITE
     788             : class HeapAllocationSiteSym : public SymbolRecord {
     789             :   static constexpr uint32_t RelocationOffset = 4;
     790             : 
     791             : public:
     792           0 :   explicit HeapAllocationSiteSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     793             :   explicit HeapAllocationSiteSym(uint32_t RecordOffset)
     794             :       : SymbolRecord(SymbolRecordKind::HeapAllocationSiteSym),
     795             :         RecordOffset(RecordOffset) {}
     796             : 
     797             :   uint32_t getRelocationOffset() const {
     798           0 :     return RecordOffset + RelocationOffset;
     799             :   }
     800             : 
     801             :   uint32_t CodeOffset;
     802             :   uint16_t Segment;
     803             :   uint16_t CallInstructionSize;
     804             :   TypeIndex Type;
     805             : 
     806             :   uint32_t RecordOffset;
     807             : };
     808             : 
     809             : // S_FRAMECOOKIE
     810             : class FrameCookieSym : public SymbolRecord {
     811             :   static constexpr uint32_t RelocationOffset = 4;
     812             : 
     813             : public:
     814           0 :   explicit FrameCookieSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     815             :   explicit FrameCookieSym(uint32_t RecordOffset)
     816             :       : SymbolRecord(SymbolRecordKind::FrameCookieSym) {}
     817             : 
     818             :   uint32_t getRelocationOffset() const {
     819           0 :     return RecordOffset + RelocationOffset;
     820             :   }
     821             : 
     822             :   uint32_t CodeOffset;
     823             :   uint16_t Register;
     824             :   FrameCookieKind CookieKind;
     825             :   uint8_t Flags;
     826             : 
     827             :   uint32_t RecordOffset;
     828             : };
     829             : 
     830             : // S_UDT, S_COBOLUDT
     831             : class UDTSym : public SymbolRecord {
     832             : public:
     833         704 :   explicit UDTSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     834             :   explicit UDTSym(uint32_t RecordOffset)
     835         456 :       : SymbolRecord(SymbolRecordKind::UDTSym) {}
     836             : 
     837             :   TypeIndex Type;
     838             :   StringRef Name;
     839             : 
     840             :   uint32_t RecordOffset;
     841             : };
     842             : 
     843             : // S_BUILDINFO
     844             : class BuildInfoSym : public SymbolRecord {
     845             : public:
     846         159 :   explicit BuildInfoSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     847             :   BuildInfoSym(uint32_t RecordOffset)
     848             :       : SymbolRecord(SymbolRecordKind::BuildInfoSym),
     849             :         RecordOffset(RecordOffset) {}
     850             : 
     851             :   TypeIndex BuildId;
     852             : 
     853             :   uint32_t RecordOffset;
     854             : };
     855             : 
     856             : // S_BPREL32
     857             : class BPRelativeSym : public SymbolRecord {
     858             : public:
     859          36 :   explicit BPRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     860             :   explicit BPRelativeSym(uint32_t RecordOffset)
     861             :       : SymbolRecord(SymbolRecordKind::BPRelativeSym),
     862             :         RecordOffset(RecordOffset) {}
     863             : 
     864             :   int32_t Offset;
     865             :   TypeIndex Type;
     866             :   StringRef Name;
     867             : 
     868             :   uint32_t RecordOffset;
     869             : };
     870             : 
     871             : // S_REGREL32
     872             : class RegRelativeSym : public SymbolRecord {
     873             : public:
     874          92 :   explicit RegRelativeSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     875             :   explicit RegRelativeSym(uint32_t RecordOffset)
     876             :       : SymbolRecord(SymbolRecordKind::RegRelativeSym),
     877             :         RecordOffset(RecordOffset) {}
     878             : 
     879             :   uint32_t Offset;
     880             :   TypeIndex Type;
     881             :   RegisterId Register;
     882             :   StringRef Name;
     883             : 
     884             :   uint32_t RecordOffset;
     885             : };
     886             : 
     887             : // S_CONSTANT, S_MANCONSTANT
     888           0 : class ConstantSym : public SymbolRecord {
     889             : public:
     890           0 :   explicit ConstantSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     891             :   ConstantSym(uint32_t RecordOffset)
     892           0 :       : SymbolRecord(SymbolRecordKind::ConstantSym),
     893           0 :         RecordOffset(RecordOffset) {}
     894             : 
     895             :   TypeIndex Type;
     896             :   APSInt Value;
     897             :   StringRef Name;
     898             : 
     899             :   uint32_t RecordOffset;
     900             : };
     901             : 
     902             : // S_LDATA32, S_GDATA32, S_LMANDATA, S_GMANDATA
     903             : class DataSym : public SymbolRecord {
     904             :   static constexpr uint32_t RelocationOffset = 8;
     905             : 
     906             : public:
     907         304 :   explicit DataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     908             :   DataSym(uint32_t RecordOffset)
     909             :       : SymbolRecord(SymbolRecordKind::DataSym), RecordOffset(RecordOffset) {}
     910             : 
     911             :   uint32_t getRelocationOffset() const {
     912          48 :     return RecordOffset + RelocationOffset;
     913             :   }
     914             : 
     915             :   TypeIndex Type;
     916             :   uint32_t DataOffset;
     917             :   uint16_t Segment;
     918             :   StringRef Name;
     919             : 
     920             :   uint32_t RecordOffset;
     921             : };
     922             : 
     923             : // S_LTHREAD32, S_GTHREAD32
     924             : class ThreadLocalDataSym : public SymbolRecord {
     925             :   static constexpr uint32_t RelocationOffset = 8;
     926             : 
     927             : public:
     928           8 :   explicit ThreadLocalDataSym(SymbolRecordKind Kind) : SymbolRecord(Kind) {}
     929             :   explicit ThreadLocalDataSym(uint32_t RecordOffset)
     930             :       : SymbolRecord(SymbolRecordKind::ThreadLocalDataSym),
     931             :         RecordOffset(RecordOffset) {}
     932             : 
     933             :   uint32_t getRelocationOffset() const {
     934           1 :     return RecordOffset + RelocationOffset;
     935             :   }
     936             : 
     937             :   TypeIndex Type;
     938             :   uint32_t DataOffset;
     939             :   uint16_t Segment;
     940             :   StringRef Name;
     941             : 
     942             :   uint32_t RecordOffset;
     943             : };
     944             : 
     945             : // S_ANNOTATION
     946             : 
     947             : using CVSymbol = CVRecord<SymbolKind>;
     948             : using CVSymbolArray = VarStreamArray<CVSymbol>;
     949             : 
     950             : Expected<CVSymbol> readSymbolFromStream(BinaryStreamRef Stream,
     951             :                                         uint32_t Offset);
     952             : 
     953             : } // end namespace codeview
     954             : } // end namespace llvm
     955             : 
     956             : #endif // LLVM_DEBUGINFO_CODEVIEW_SYMBOLRECORD_H

Generated by: LCOV version 1.13