LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugFrame.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 252 315 80.0 %
Date: 2017-09-14 15:23:50 Functions: 19 22 86.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
       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             : #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
      11             : #include "llvm/ADT/ArrayRef.h"
      12             : #include "llvm/ADT/DenseMap.h"
      13             : #include "llvm/ADT/Optional.h"
      14             : #include "llvm/ADT/STLExtras.h"
      15             : #include "llvm/ADT/SmallString.h"
      16             : #include "llvm/ADT/StringExtras.h"
      17             : #include "llvm/ADT/StringRef.h"
      18             : #include "llvm/BinaryFormat/Dwarf.h"
      19             : #include "llvm/Support/Casting.h"
      20             : #include "llvm/Support/Compiler.h"
      21             : #include "llvm/Support/DataExtractor.h"
      22             : #include "llvm/Support/ErrorHandling.h"
      23             : #include "llvm/Support/Format.h"
      24             : #include "llvm/Support/raw_ostream.h"
      25             : #include <algorithm>
      26             : #include <cassert>
      27             : #include <cinttypes>
      28             : #include <cstdint>
      29             : #include <string>
      30             : #include <vector>
      31             : 
      32             : using namespace llvm;
      33             : using namespace dwarf;
      34             : 
      35             : /// \brief Abstract frame entry defining the common interface concrete
      36             : /// entries implement.
      37             : class llvm::FrameEntry {
      38             : public:
      39             :   enum FrameKind {FK_CIE, FK_FDE};
      40             : 
      41             :   FrameEntry(FrameKind K, uint64_t Offset, uint64_t Length)
      42         178 :       : Kind(K), Offset(Offset), Length(Length) {}
      43             : 
      44          89 :   virtual ~FrameEntry() = default;
      45             : 
      46             :   FrameKind getKind() const { return Kind; }
      47           0 :   virtual uint64_t getOffset() const { return Offset; }
      48             : 
      49             :   /// \brief Parse and store a sequence of CFI instructions from Data,
      50             :   /// starting at *Offset and ending at EndOffset. If everything
      51             :   /// goes well, *Offset should be equal to EndOffset when this method
      52             :   /// returns. Otherwise, an error occurred.
      53             :   virtual void parseInstructions(DataExtractor Data, uint32_t *Offset,
      54             :                                  uint32_t EndOffset);
      55             : 
      56             :   /// \brief Dump the entry header to the given output stream.
      57             :   virtual void dumpHeader(raw_ostream &OS) const = 0;
      58             : 
      59             :   /// \brief Dump the entry's instructions to the given output stream.
      60             :   virtual void dumpInstructions(raw_ostream &OS) const;
      61             : 
      62             : protected:
      63             :   const FrameKind Kind;
      64             : 
      65             :   /// \brief Offset of this entry in the section.
      66             :   uint64_t Offset;
      67             : 
      68             :   /// \brief Entry length as specified in DWARF.
      69             :   uint64_t Length;
      70             : 
      71             :   /// An entry may contain CFI instructions. An instruction consists of an
      72             :   /// opcode and an optional sequence of operands.
      73             :   using Operands = std::vector<uint64_t>;
      74        3984 :   struct Instruction {
      75             :     Instruction(uint8_t Opcode)
      76         764 :       : Opcode(Opcode)
      77             :     {}
      78             : 
      79             :     uint8_t Opcode;
      80             :     Operands Ops;
      81             :   };
      82             : 
      83             :   std::vector<Instruction> Instructions;
      84             : 
      85             :   /// Convenience methods to add a new instruction with the given opcode and
      86             :   /// operands to the Instructions vector.
      87         173 :   void addInstruction(uint8_t Opcode) {
      88         692 :     Instructions.push_back(Instruction(Opcode));
      89         173 :   }
      90             : 
      91         108 :   void addInstruction(uint8_t Opcode, uint64_t Operand1) {
      92         432 :     Instructions.push_back(Instruction(Opcode));
      93         216 :     Instructions.back().Ops.push_back(Operand1);
      94         108 :   }
      95             : 
      96         101 :   void addInstruction(uint8_t Opcode, uint64_t Operand1, uint64_t Operand2) {
      97         404 :     Instructions.push_back(Instruction(Opcode));
      98         202 :     Instructions.back().Ops.push_back(Operand1);
      99         202 :     Instructions.back().Ops.push_back(Operand2);
     100         101 :   }
     101             : };
     102             : 
     103             : // See DWARF standard v3, section 7.23
     104             : const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
     105             : const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
     106             : 
     107          89 : void FrameEntry::parseInstructions(DataExtractor Data, uint32_t *Offset,
     108             :                                    uint32_t EndOffset) {
     109         471 :   while (*Offset < EndOffset) {
     110         382 :     uint8_t Opcode = Data.getU8(Offset);
     111             :     // Some instructions have a primary opcode encoded in the top bits.
     112         382 :     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
     113             : 
     114         382 :     if (Primary) {
     115             :       // If it's a primary opcode, the first operand is encoded in the bottom
     116             :       // bits of the opcode itself.
     117         119 :       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
     118         119 :       switch (Primary) {
     119           0 :         default: llvm_unreachable("Impossible primary CFI opcode");
     120          59 :         case DW_CFA_advance_loc:
     121             :         case DW_CFA_restore:
     122          59 :           addInstruction(Primary, Op1);
     123          59 :           break;
     124          60 :         case DW_CFA_offset:
     125          60 :           addInstruction(Primary, Op1, Data.getULEB128(Offset));
     126          60 :           break;
     127             :       }
     128             :     } else {
     129             :       // Extended opcode - its value is Opcode itself.
     130         263 :       switch (Opcode) {
     131           0 :         default: llvm_unreachable("Invalid extended CFI opcode");
     132         173 :         case DW_CFA_nop:
     133             :         case DW_CFA_remember_state:
     134             :         case DW_CFA_restore_state:
     135             :         case DW_CFA_GNU_window_save:
     136             :           // No operands
     137         173 :           addInstruction(Opcode);
     138         173 :           break;
     139           0 :         case DW_CFA_set_loc:
     140             :           // Operands: Address
     141           0 :           addInstruction(Opcode, Data.getAddress(Offset));
     142           0 :           break;
     143           1 :         case DW_CFA_advance_loc1:
     144             :           // Operands: 1-byte delta
     145           1 :           addInstruction(Opcode, Data.getU8(Offset));
     146           1 :           break;
     147           0 :         case DW_CFA_advance_loc2:
     148             :           // Operands: 2-byte delta
     149           0 :           addInstruction(Opcode, Data.getU16(Offset));
     150           0 :           break;
     151           0 :         case DW_CFA_advance_loc4:
     152             :           // Operands: 4-byte delta
     153           0 :           addInstruction(Opcode, Data.getU32(Offset));
     154           0 :           break;
     155          48 :         case DW_CFA_restore_extended:
     156             :         case DW_CFA_undefined:
     157             :         case DW_CFA_same_value:
     158             :         case DW_CFA_def_cfa_register:
     159             :         case DW_CFA_def_cfa_offset:
     160             :           // Operands: ULEB128
     161          48 :           addInstruction(Opcode, Data.getULEB128(Offset));
     162          48 :           break;
     163           0 :         case DW_CFA_def_cfa_offset_sf:
     164             :           // Operands: SLEB128
     165           0 :           addInstruction(Opcode, Data.getSLEB128(Offset));
     166           0 :           break;
     167          41 :         case DW_CFA_offset_extended:
     168             :         case DW_CFA_register:
     169             :         case DW_CFA_def_cfa:
     170             :         case DW_CFA_val_offset: {
     171             :           // Operands: ULEB128, ULEB128
     172             :           // Note: We can not embed getULEB128 directly into function
     173             :           // argument list. getULEB128 changes Offset and order of evaluation
     174             :           // for arguments is unspecified.
     175          41 :           auto op1 = Data.getULEB128(Offset);
     176          41 :           auto op2 = Data.getULEB128(Offset);
     177          41 :           addInstruction(Opcode, op1, op2);
     178          41 :           break;
     179             :         }
     180           0 :         case DW_CFA_offset_extended_sf:
     181             :         case DW_CFA_def_cfa_sf:
     182             :         case DW_CFA_val_offset_sf: {
     183             :           // Operands: ULEB128, SLEB128
     184             :           // Note: see comment for the previous case
     185           0 :           auto op1 = Data.getULEB128(Offset);
     186           0 :           auto op2 = (uint64_t)Data.getSLEB128(Offset);
     187           0 :           addInstruction(Opcode, op1, op2);
     188           0 :           break;
     189             :         }
     190           0 :         case DW_CFA_def_cfa_expression:
     191             :         case DW_CFA_expression:
     192             :         case DW_CFA_val_expression:
     193             :           // TODO: implement this
     194           0 :           report_fatal_error("Values with expressions not implemented yet!");
     195             :       }
     196             :     }
     197             :   }
     198          89 : }
     199             : 
     200             : namespace {
     201             : 
     202             : /// \brief DWARF Common Information Entry (CIE)
     203             : class CIE : public FrameEntry {
     204             : public:
     205             :   // CIEs (and FDEs) are simply container classes, so the only sensible way to
     206             :   // create them is by providing the full parsed contents in the constructor.
     207          42 :   CIE(uint64_t Offset, uint64_t Length, uint8_t Version,
     208             :       SmallString<8> Augmentation, uint8_t AddressSize,
     209             :       uint8_t SegmentDescriptorSize, uint64_t CodeAlignmentFactor,
     210             :       int64_t DataAlignmentFactor, uint64_t ReturnAddressRegister,
     211             :       SmallString<8> AugmentationData, uint32_t FDEPointerEncoding,
     212             :       uint32_t LSDAPointerEncoding)
     213          42 :       : FrameEntry(FK_CIE, Offset, Length), Version(Version),
     214          42 :         Augmentation(std::move(Augmentation)), AddressSize(AddressSize),
     215             :         SegmentDescriptorSize(SegmentDescriptorSize),
     216             :         CodeAlignmentFactor(CodeAlignmentFactor),
     217             :         DataAlignmentFactor(DataAlignmentFactor),
     218             :         ReturnAddressRegister(ReturnAddressRegister),
     219          42 :         AugmentationData(std::move(AugmentationData)),
     220             :         FDEPointerEncoding(FDEPointerEncoding),
     221         168 :         LSDAPointerEncoding(LSDAPointerEncoding) {}
     222             : 
     223         210 :   ~CIE() override = default;
     224             : 
     225          20 :   StringRef getAugmentationString() const { return Augmentation; }
     226             :   uint64_t getCodeAlignmentFactor() const { return CodeAlignmentFactor; }
     227             :   int64_t getDataAlignmentFactor() const { return DataAlignmentFactor; }
     228             : 
     229             :   uint32_t getFDEPointerEncoding() const {
     230             :     return FDEPointerEncoding;
     231             :   }
     232             : 
     233             :   uint32_t getLSDAPointerEncoding() const {
     234             :     return LSDAPointerEncoding;
     235             :   }
     236             : 
     237          42 :   void dumpHeader(raw_ostream &OS) const override {
     238         126 :     OS << format("%08x %08x %08x CIE",
     239          84 :                  (uint32_t)Offset, (uint32_t)Length, DW_CIE_ID)
     240          42 :        << "\n";
     241          84 :     OS << format("  Version:               %d\n", Version);
     242          84 :     OS << "  Augmentation:          \"" << Augmentation << "\"\n";
     243          42 :     if (Version >= 4) {
     244          36 :       OS << format("  Address size:          %u\n",
     245          18 :                    (uint32_t)AddressSize);
     246          36 :       OS << format("  Segment desc size:     %u\n",
     247          18 :                    (uint32_t)SegmentDescriptorSize);
     248             :     }
     249          84 :     OS << format("  Code alignment factor: %u\n",
     250          42 :                  (uint32_t)CodeAlignmentFactor);
     251          84 :     OS << format("  Data alignment factor: %d\n",
     252          42 :                  (int32_t)DataAlignmentFactor);
     253          84 :     OS << format("  Return address column: %d\n",
     254          42 :                  (int32_t)ReturnAddressRegister);
     255          42 :     if (!AugmentationData.empty()) {
     256           8 :       OS << "  Augmentation data:    ";
     257          45 :       for (uint8_t Byte : AugmentationData)
     258         105 :         OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
     259           8 :       OS << "\n";
     260             :     }
     261          42 :     OS << "\n";
     262          42 :   }
     263             : 
     264             :   static bool classof(const FrameEntry *FE) {
     265          89 :     return FE->getKind() == FK_CIE;
     266             :   }
     267             : 
     268             : private:
     269             :   /// The following fields are defined in section 6.4.1 of the DWARF standard v4
     270             :   uint8_t Version;
     271             :   SmallString<8> Augmentation;
     272             :   uint8_t AddressSize;
     273             :   uint8_t SegmentDescriptorSize;
     274             :   uint64_t CodeAlignmentFactor;
     275             :   int64_t DataAlignmentFactor;
     276             :   uint64_t ReturnAddressRegister;
     277             : 
     278             :   // The following are used when the CIE represents an EH frame entry.
     279             :   SmallString<8> AugmentationData;
     280             :   uint32_t FDEPointerEncoding;
     281             :   uint32_t LSDAPointerEncoding;
     282             : };
     283             : 
     284             : /// \brief DWARF Frame Description Entry (FDE)
     285             : class FDE : public FrameEntry {
     286             : public:
     287             :   // Each FDE has a CIE it's "linked to". Our FDE contains is constructed with
     288             :   // an offset to the CIE (provided by parsing the FDE header). The CIE itself
     289             :   // is obtained lazily once it's actually required.
     290             :   FDE(uint64_t Offset, uint64_t Length, int64_t LinkedCIEOffset,
     291             :       uint64_t InitialLocation, uint64_t AddressRange,
     292             :       CIE *Cie)
     293          47 :       : FrameEntry(FK_FDE, Offset, Length), LinkedCIEOffset(LinkedCIEOffset),
     294             :         InitialLocation(InitialLocation), AddressRange(AddressRange),
     295          94 :         LinkedCIE(Cie) {}
     296             : 
     297          94 :   ~FDE() override = default;
     298             : 
     299             :   CIE *getLinkedCIE() const { return LinkedCIE; }
     300             : 
     301          47 :   void dumpHeader(raw_ostream &OS) const override {
     302          94 :     OS << format("%08x %08x %08x FDE ",
     303          47 :                  (uint32_t)Offset, (uint32_t)Length, (int32_t)LinkedCIEOffset);
     304          94 :     OS << format("cie=%08x pc=%08x...%08x\n",
     305          47 :                  (int32_t)LinkedCIEOffset,
     306             :                  (uint32_t)InitialLocation,
     307          47 :                  (uint32_t)InitialLocation + (uint32_t)AddressRange);
     308          47 :   }
     309             : 
     310             :   static bool classof(const FrameEntry *FE) {
     311             :     return FE->getKind() == FK_FDE;
     312             :   }
     313             : 
     314             : private:
     315             :   /// The following fields are defined in section 6.4.1 of the DWARF standard v3
     316             :   uint64_t LinkedCIEOffset;
     317             :   uint64_t InitialLocation;
     318             :   uint64_t AddressRange;
     319             :   CIE *LinkedCIE;
     320             : };
     321             : 
     322             : /// \brief Types of operands to CF instructions.
     323             : enum OperandType {
     324             :   OT_Unset,
     325             :   OT_None,
     326             :   OT_Address,
     327             :   OT_Offset,
     328             :   OT_FactoredCodeOffset,
     329             :   OT_SignedFactDataOffset,
     330             :   OT_UnsignedFactDataOffset,
     331             :   OT_Register,
     332             :   OT_Expression
     333             : };
     334             : 
     335             : } // end anonymous namespace
     336             : 
     337             : /// \brief Initialize the array describing the types of operands.
     338       72306 : static ArrayRef<OperandType[2]> getOperandTypes() {
     339             :   static OperandType OpTypes[DW_CFA_restore+1][2];
     340             : 
     341             : #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
     342             :   do {                                          \
     343             :     OpTypes[OP][0] = OPTYPE0;                   \
     344             :     OpTypes[OP][1] = OPTYPE1;                   \
     345             :   } while (false)
     346             : #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
     347             : #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
     348             : 
     349       72306 :   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
     350       72306 :   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
     351       72306 :   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
     352       72306 :   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
     353       72306 :   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
     354       72306 :   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
     355       72306 :   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
     356       72306 :   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
     357       72306 :   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
     358       72306 :   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
     359       72306 :   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
     360       72306 :   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
     361       72306 :   DECLARE_OP1(DW_CFA_undefined, OT_Register);
     362       72306 :   DECLARE_OP1(DW_CFA_same_value, OT_Register);
     363       72306 :   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
     364       72306 :   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
     365       72306 :   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
     366       72306 :   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
     367       72306 :   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
     368       72306 :   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
     369       72306 :   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
     370       72306 :   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
     371       72306 :   DECLARE_OP1(DW_CFA_restore, OT_Register);
     372       72306 :   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
     373       72306 :   DECLARE_OP0(DW_CFA_remember_state);
     374       72306 :   DECLARE_OP0(DW_CFA_restore_state);
     375       72306 :   DECLARE_OP0(DW_CFA_GNU_window_save);
     376       72306 :   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
     377       72306 :   DECLARE_OP0(DW_CFA_nop);
     378             : 
     379             : #undef DECLARE_OP0
     380             : #undef DECLARE_OP1
     381             : #undef DECLARE_OP2
     382             : 
     383       72306 :   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
     384             : }
     385             : 
     386       72306 : static ArrayRef<OperandType[2]> OpTypes = getOperandTypes();
     387             : 
     388             : /// \brief Print \p Opcode's operand number \p OperandIdx which has
     389             : /// value \p Operand.
     390         310 : static void printOperand(raw_ostream &OS, uint8_t Opcode, unsigned OperandIdx,
     391             :                          uint64_t Operand, uint64_t CodeAlignmentFactor,
     392             :                          int64_t DataAlignmentFactor) {
     393             :   assert(OperandIdx < 2);
     394         620 :   OperandType Type = OpTypes[Opcode][OperandIdx];
     395             : 
     396         310 :   switch (Type) {
     397           0 :   case OT_Unset: {
     398           0 :     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
     399           0 :     auto OpcodeName = CallFrameString(Opcode);
     400           0 :     if (!OpcodeName.empty())
     401           0 :       OS << " " << OpcodeName;
     402             :     else
     403           0 :       OS << format(" Opcode %x",  Opcode);
     404             :     break;
     405             :   }
     406             :   case OT_None:
     407             :     break;
     408           0 :   case OT_Address:
     409           0 :     OS << format(" %" PRIx64, Operand);
     410           0 :     break;
     411          67 :   case OT_Offset:
     412             :     // The offsets are all encoded in a unsigned form, but in practice
     413             :     // consumers use them signed. It's most certainly legacy due to
     414             :     // the lack of signed variants in the first Dwarf standards.
     415         134 :     OS << format(" %+" PRId64, int64_t(Operand));
     416          67 :     break;
     417          53 :   case OT_FactoredCodeOffset: // Always Unsigned
     418          53 :     if (CodeAlignmentFactor)
     419         106 :       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
     420             :     else
     421           0 :       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
     422             :     break;
     423           0 :   case OT_SignedFactDataOffset:
     424           0 :     if (DataAlignmentFactor)
     425           0 :       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
     426             :     else
     427           0 :       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
     428             :     break;
     429          60 :   case OT_UnsignedFactDataOffset:
     430          60 :     if (DataAlignmentFactor)
     431         120 :       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
     432             :     else
     433           0 :       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
     434             :     break;
     435         130 :   case OT_Register:
     436         260 :     OS << format(" reg%" PRId64, Operand);
     437         130 :     break;
     438           0 :   case OT_Expression:
     439           0 :     OS << " expression";
     440           0 :     break;
     441             :   }
     442         310 : }
     443             : 
     444          89 : void FrameEntry::dumpInstructions(raw_ostream &OS) const {
     445          89 :   uint64_t CodeAlignmentFactor = 0;
     446          89 :   int64_t DataAlignmentFactor = 0;
     447             :   const CIE *Cie = dyn_cast<CIE>(this);
     448             : 
     449             :   if (!Cie)
     450          47 :     Cie = cast<FDE>(this)->getLinkedCIE();
     451          89 :   if (Cie) {
     452          89 :     CodeAlignmentFactor = Cie->getCodeAlignmentFactor();
     453          89 :     DataAlignmentFactor = Cie->getDataAlignmentFactor();
     454             :   }
     455             : 
     456         738 :   for (const auto &Instr : Instructions) {
     457         382 :     uint8_t Opcode = Instr.Opcode;
     458         382 :     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
     459         119 :       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
     460         382 :     OS << "  " << CallFrameString(Opcode) << ":";
     461        1384 :     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
     462         620 :       printOperand(OS, Opcode, i, Instr.Ops[i], CodeAlignmentFactor,
     463             :                    DataAlignmentFactor);
     464         382 :     OS << '\n';
     465             :   }
     466          89 : }
     467             : 
     468         376 : DWARFDebugFrame::DWARFDebugFrame(bool IsEH) : IsEH(IsEH) {}
     469             : 
     470             : DWARFDebugFrame::~DWARFDebugFrame() = default;
     471             : 
     472             : static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
     473             :                                               uint32_t Offset, int Length) {
     474             :   errs() << "DUMP: ";
     475             :   for (int i = 0; i < Length; ++i) {
     476             :     uint8_t c = Data.getU8(&Offset);
     477             :     errs().write_hex(c); errs() << " ";
     478             :   }
     479             :   errs() << "\n";
     480             : }
     481             : 
     482          25 : static unsigned getSizeForEncoding(const DataExtractor &Data,
     483             :                                    unsigned symbolEncoding) {
     484          25 :   unsigned format = symbolEncoding & 0x0f;
     485          25 :   switch (format) {
     486           0 :     default: llvm_unreachable("Unknown Encoding");
     487           5 :     case DW_EH_PE_absptr:
     488             :     case DW_EH_PE_signed:
     489           5 :       return Data.getAddressSize();
     490             :     case DW_EH_PE_udata2:
     491             :     case DW_EH_PE_sdata2:
     492             :       return 2;
     493          20 :     case DW_EH_PE_udata4:
     494             :     case DW_EH_PE_sdata4:
     495          20 :       return 4;
     496           0 :     case DW_EH_PE_udata8:
     497             :     case DW_EH_PE_sdata8:
     498           0 :       return 8;
     499             :   }
     500             : }
     501             : 
     502          25 : static uint64_t readPointer(const DataExtractor &Data, uint32_t &Offset,
     503             :                             unsigned Encoding) {
     504          25 :   switch (getSizeForEncoding(Data, Encoding)) {
     505           0 :     case 2:
     506           0 :       return Data.getU16(&Offset);
     507          23 :     case 4:
     508          23 :       return Data.getU32(&Offset);
     509           2 :     case 8:
     510           2 :       return Data.getU64(&Offset);
     511           0 :     default:
     512           0 :       llvm_unreachable("Illegal data size");
     513             :   }
     514             : }
     515             : 
     516             : // This is a workaround for old compilers which do not allow
     517             : // noreturn attribute usage in lambdas. Once the support for those
     518             : // compilers are phased out, we can remove this and return back to
     519             : // a ReportError lambda: [StartOffset](const char *ErrorMsg).
     520           0 : static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset,
     521             :                                                 const char *ErrorMsg) {
     522           0 :   std::string Str;
     523           0 :   raw_string_ostream OS(Str);
     524           0 :   OS << format(ErrorMsg, StartOffset);
     525           0 :   OS.flush();
     526           0 :   report_fatal_error(Str);
     527             : }
     528             : 
     529         188 : void DWARFDebugFrame::parse(DataExtractor Data) {
     530         188 :   uint32_t Offset = 0;
     531         188 :   DenseMap<uint32_t, CIE *> CIEs;
     532             : 
     533         643 :   while (Data.isValidOffset(Offset)) {
     534          89 :     uint32_t StartOffset = Offset;
     535             : 
     536          89 :     bool IsDWARF64 = false;
     537          89 :     uint64_t Length = Data.getU32(&Offset);
     538             :     uint64_t Id;
     539             : 
     540          89 :     if (Length == UINT32_MAX) {
     541             :       // DWARF-64 is distinguished by the first 32 bits of the initial length
     542             :       // field being 0xffffffff. Then, the next 64 bits are the actual entry
     543             :       // length.
     544           0 :       IsDWARF64 = true;
     545           0 :       Length = Data.getU64(&Offset);
     546             :     }
     547             : 
     548             :     // At this point, Offset points to the next field after Length.
     549             :     // Length is the structure size excluding itself. Compute an offset one
     550             :     // past the end of the structure (needed to know how many instructions to
     551             :     // read).
     552             :     // TODO: For honest DWARF64 support, DataExtractor will have to treat
     553             :     //       offset_ptr as uint64_t*
     554          89 :     uint32_t StartStructureOffset = Offset;
     555          89 :     uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
     556             : 
     557             :     // The Id field's size depends on the DWARF format
     558          89 :     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
     559         225 :     bool IsCIE = ((IsDWARF64 && Id == DW64_CIE_ID) ||
     560         146 :                   Id == DW_CIE_ID ||
     561          77 :                   (IsEH && !Id));
     562             : 
     563             :     if (IsCIE) {
     564          42 :       uint8_t Version = Data.getU8(&Offset);
     565          42 :       const char *Augmentation = Data.getCStr(&Offset);
     566          84 :       StringRef AugmentationString(Augmentation ? Augmentation : "");
     567          42 :       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
     568          42 :                                           Data.getU8(&Offset);
     569          84 :       Data.setAddressSize(AddressSize);
     570          42 :       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
     571          42 :       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
     572          42 :       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
     573          42 :       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
     574             : 
     575             :       // Parse the augmentation data for EH CIEs
     576          42 :       StringRef AugmentationData("");
     577          42 :       uint32_t FDEPointerEncoding = DW_EH_PE_omit;
     578          42 :       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
     579          42 :       if (IsEH) {
     580          20 :         Optional<uint32_t> PersonalityEncoding;
     581          20 :         Optional<uint64_t> Personality;
     582             : 
     583          20 :         Optional<uint64_t> AugmentationLength;
     584             :         uint32_t StartAugmentationOffset;
     585             :         uint32_t EndAugmentationOffset;
     586             : 
     587             :         // Walk the augmentation string to get all the augmentation data.
     588          41 :         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
     589          42 :           switch (AugmentationString[i]) {
     590           0 :             default:
     591           0 :               ReportError(StartOffset,
     592             :                           "Unknown augmentation character in entry at %lx");
     593           3 :             case 'L':
     594           3 :               LSDAPointerEncoding = Data.getU8(&Offset);
     595           3 :               break;
     596           2 :             case 'P': {
     597           2 :               if (Personality)
     598           0 :                 ReportError(StartOffset,
     599             :                             "Duplicate personality in entry at %lx");
     600           2 :               PersonalityEncoding = Data.getU8(&Offset);
     601           4 :               Personality = readPointer(Data, Offset, *PersonalityEncoding);
     602           2 :               break;
     603             :             }
     604           8 :             case 'R':
     605           8 :               FDEPointerEncoding = Data.getU8(&Offset);
     606           8 :               break;
     607           8 :             case 'z':
     608           8 :               if (i)
     609           0 :                 ReportError(StartOffset,
     610             :                             "'z' must be the first character at %lx");
     611             :               // Parse the augmentation length first.  We only parse it if
     612             :               // the string contains a 'z'.
     613          16 :               AugmentationLength = Data.getULEB128(&Offset);
     614           8 :               StartAugmentationOffset = Offset;
     615           8 :               EndAugmentationOffset = Offset +
     616           8 :                 static_cast<uint32_t>(*AugmentationLength);
     617             :           }
     618             :         }
     619             : 
     620          10 :         if (AugmentationLength.hasValue()) {
     621           8 :           if (Offset != EndAugmentationOffset)
     622           0 :             ReportError(StartOffset, "Parsing augmentation data at %lx failed");
     623             : 
     624          16 :           AugmentationData = Data.getData().slice(StartAugmentationOffset,
     625           8 :                                                   EndAugmentationOffset);
     626             :         }
     627             :       }
     628             : 
     629             :       auto Cie = llvm::make_unique<CIE>(StartOffset, Length, Version,
     630             :                                         AugmentationString, AddressSize,
     631             :                                         SegmentDescriptorSize,
     632             :                                         CodeAlignmentFactor,
     633             :                                         DataAlignmentFactor,
     634             :                                         ReturnAddressRegister,
     635             :                                         AugmentationData, FDEPointerEncoding,
     636          84 :                                         LSDAPointerEncoding);
     637          84 :       CIEs[StartOffset] = Cie.get();
     638          42 :       Entries.emplace_back(std::move(Cie));
     639             :     } else {
     640             :       // FDE
     641          47 :       uint64_t CIEPointer = Id;
     642          47 :       uint64_t InitialLocation = 0;
     643          47 :       uint64_t AddressRange = 0;
     644         104 :       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
     645             : 
     646          47 :       if (IsEH) {
     647             :         // The address size is encoded in the CIE we reference.
     648          10 :         if (!Cie)
     649           0 :           ReportError(StartOffset,
     650             :                       "Parsing FDE data at %lx failed due to missing CIE");
     651             : 
     652          10 :         InitialLocation = readPointer(Data, Offset,
     653             :                                       Cie->getFDEPointerEncoding());
     654          10 :         AddressRange = readPointer(Data, Offset,
     655             :                                    Cie->getFDEPointerEncoding());
     656             : 
     657          10 :         StringRef AugmentationString = Cie->getAugmentationString();
     658          10 :         if (!AugmentationString.empty()) {
     659             :           // Parse the augmentation length and data for this FDE.
     660          10 :           uint64_t AugmentationLength = Data.getULEB128(&Offset);
     661             : 
     662          10 :           uint32_t EndAugmentationOffset =
     663          10 :             Offset + static_cast<uint32_t>(AugmentationLength);
     664             : 
     665             :           // Decode the LSDA if the CIE augmentation string said we should.
     666          10 :           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit)
     667           3 :             readPointer(Data, Offset, Cie->getLSDAPointerEncoding());
     668             : 
     669          10 :           if (Offset != EndAugmentationOffset)
     670           0 :             ReportError(StartOffset, "Parsing augmentation data at %lx failed");
     671             :         }
     672             :       } else {
     673          37 :         InitialLocation = Data.getAddress(&Offset);
     674          37 :         AddressRange = Data.getAddress(&Offset);
     675             :       }
     676             : 
     677          94 :       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
     678             :                                    InitialLocation, AddressRange,
     679          94 :                                    Cie));
     680             :     }
     681             : 
     682         267 :     Entries.back()->parseInstructions(Data, &Offset, EndStructureOffset);
     683             : 
     684          89 :     if (Offset != EndStructureOffset)
     685           0 :       ReportError(StartOffset, "Parsing entry instructions at %lx failed");
     686             :   }
     687         188 : }
     688             : 
     689         188 : void DWARFDebugFrame::dump(raw_ostream &OS) const {
     690         188 :   OS << "\n";
     691         841 :   for (const auto &Entry : Entries) {
     692          89 :     Entry->dumpHeader(OS);
     693          89 :     Entry->dumpInstructions(OS);
     694          89 :     OS << "\n";
     695             :   }
     696      144800 : }

Generated by: LCOV version 1.13