LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugFrame.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 227 270 84.1 %
Date: 2018-07-13 00:08:38 Functions: 10 11 90.9 %
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/DenseMap.h"
      12             : #include "llvm/ADT/Optional.h"
      13             : #include "llvm/ADT/StringExtras.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/BinaryFormat/Dwarf.h"
      16             : #include "llvm/Support/Casting.h"
      17             : #include "llvm/Support/Compiler.h"
      18             : #include "llvm/Support/DataExtractor.h"
      19             : #include "llvm/Support/ErrorHandling.h"
      20             : #include "llvm/Support/Format.h"
      21             : #include "llvm/Support/raw_ostream.h"
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : #include <cinttypes>
      25             : #include <cstdint>
      26             : #include <string>
      27             : #include <vector>
      28             : 
      29             : using namespace llvm;
      30             : using namespace dwarf;
      31             : 
      32             : 
      33             : // See DWARF standard v3, section 7.23
      34             : const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
      35             : const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
      36             : 
      37         399 : Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
      38             :                         uint32_t EndOffset) {
      39        3195 :   while (*Offset < EndOffset) {
      40        2796 :     uint8_t Opcode = Data.getU8(Offset);
      41             :     // Some instructions have a primary opcode encoded in the top bits.
      42        2796 :     uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
      43             : 
      44        2796 :     if (Primary) {
      45             :       // If it's a primary opcode, the first operand is encoded in the bottom
      46             :       // bits of the opcode itself.
      47         797 :       uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
      48         797 :       switch (Primary) {
      49             :       default:
      50             :         return make_error<StringError>(
      51             :             "Invalid primary CFI opcode",
      52           0 :             std::make_error_code(std::errc::illegal_byte_sequence));
      53         491 :       case DW_CFA_advance_loc:
      54             :       case DW_CFA_restore:
      55         491 :         addInstruction(Primary, Op1);
      56         491 :         break;
      57         306 :       case DW_CFA_offset:
      58         306 :         addInstruction(Primary, Op1, Data.getULEB128(Offset));
      59         306 :         break;
      60             :       }
      61             :     } else {
      62             :       // Extended opcode - its value is Opcode itself.
      63        1999 :       switch (Opcode) {
      64             :       default:
      65             :         return make_error<StringError>(
      66             :             "Invalid extended CFI opcode",
      67           0 :             std::make_error_code(std::errc::illegal_byte_sequence));
      68        1387 :       case DW_CFA_nop:
      69             :       case DW_CFA_remember_state:
      70             :       case DW_CFA_restore_state:
      71             :       case DW_CFA_GNU_window_save:
      72             :         // No operands
      73        1387 :         addInstruction(Opcode);
      74        1387 :         break;
      75             :       case DW_CFA_set_loc:
      76             :         // Operands: Address
      77           0 :         addInstruction(Opcode, Data.getAddress(Offset));
      78           0 :         break;
      79           6 :       case DW_CFA_advance_loc1:
      80             :         // Operands: 1-byte delta
      81           6 :         addInstruction(Opcode, Data.getU8(Offset));
      82           6 :         break;
      83           1 :       case DW_CFA_advance_loc2:
      84             :         // Operands: 2-byte delta
      85           1 :         addInstruction(Opcode, Data.getU16(Offset));
      86           1 :         break;
      87           0 :       case DW_CFA_advance_loc4:
      88             :         // Operands: 4-byte delta
      89           0 :         addInstruction(Opcode, Data.getU32(Offset));
      90           0 :         break;
      91         419 :       case DW_CFA_restore_extended:
      92             :       case DW_CFA_undefined:
      93             :       case DW_CFA_same_value:
      94             :       case DW_CFA_def_cfa_register:
      95             :       case DW_CFA_def_cfa_offset:
      96             :       case DW_CFA_GNU_args_size:
      97             :         // Operands: ULEB128
      98         419 :         addInstruction(Opcode, Data.getULEB128(Offset));
      99         419 :         break;
     100           0 :       case DW_CFA_def_cfa_offset_sf:
     101             :         // Operands: SLEB128
     102           0 :         addInstruction(Opcode, Data.getSLEB128(Offset));
     103           0 :         break;
     104         179 :       case DW_CFA_offset_extended:
     105             :       case DW_CFA_register:
     106             :       case DW_CFA_def_cfa:
     107             :       case DW_CFA_val_offset: {
     108             :         // Operands: ULEB128, ULEB128
     109             :         // Note: We can not embed getULEB128 directly into function
     110             :         // argument list. getULEB128 changes Offset and order of evaluation
     111             :         // for arguments is unspecified.
     112         179 :         auto op1 = Data.getULEB128(Offset);
     113         179 :         auto op2 = Data.getULEB128(Offset);
     114         179 :         addInstruction(Opcode, op1, op2);
     115         179 :         break;
     116             :         }
     117           0 :         case DW_CFA_offset_extended_sf:
     118             :         case DW_CFA_def_cfa_sf:
     119             :         case DW_CFA_val_offset_sf: {
     120             :           // Operands: ULEB128, SLEB128
     121             :           // Note: see comment for the previous case
     122           0 :           auto op1 = Data.getULEB128(Offset);
     123           0 :           auto op2 = (uint64_t)Data.getSLEB128(Offset);
     124           0 :           addInstruction(Opcode, op1, op2);
     125           0 :           break;
     126             :         }
     127           6 :         case DW_CFA_def_cfa_expression: {
     128           6 :           uint32_t ExprLength = Data.getULEB128(Offset);
     129           6 :           addInstruction(Opcode, 0);
     130             :           DataExtractor Extractor(
     131          12 :               Data.getData().slice(*Offset, *Offset + ExprLength),
     132          12 :               Data.isLittleEndian(), Data.getAddressSize());
     133             :           Instructions.back().Expression = DWARFExpression(
     134             :               Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);
     135           6 :           *Offset += ExprLength;
     136             :           break;
     137             :         }
     138           1 :         case DW_CFA_expression:
     139             :         case DW_CFA_val_expression: {
     140           1 :           auto RegNum = Data.getULEB128(Offset);
     141           1 :           auto BlockLength = Data.getULEB128(Offset);
     142           1 :           addInstruction(Opcode, RegNum, 0);
     143             :           DataExtractor Extractor(
     144           2 :               Data.getData().slice(*Offset, *Offset + BlockLength),
     145           2 :               Data.isLittleEndian(), Data.getAddressSize());
     146             :           Instructions.back().Expression = DWARFExpression(
     147             :               Extractor, Data.getAddressSize(), dwarf::DWARF_VERSION);
     148           1 :           *Offset += BlockLength;
     149             :           break;
     150             :         }
     151             :       }
     152             :     }
     153             :   }
     154             : 
     155             :   return Error::success();
     156             : }
     157             : 
     158             : namespace {
     159             : 
     160             : 
     161             : } // end anonymous namespace
     162             : 
     163        1881 : ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
     164             :   static OperandType OpTypes[DW_CFA_restore+1][2];
     165             :   static bool Initialized = false;
     166        1881 :   if (Initialized) {
     167        1773 :     return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
     168             :   }
     169         108 :   Initialized = true;
     170             : 
     171             : #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)       \
     172             :   do {                                          \
     173             :     OpTypes[OP][0] = OPTYPE0;                   \
     174             :     OpTypes[OP][1] = OPTYPE1;                   \
     175             :   } while (false)
     176             : #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
     177             : #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
     178             : 
     179         108 :   DECLARE_OP1(DW_CFA_set_loc, OT_Address);
     180         108 :   DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
     181         108 :   DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
     182         108 :   DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
     183         108 :   DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
     184         108 :   DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
     185         108 :   DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
     186         108 :   DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
     187         108 :   DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
     188         108 :   DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
     189         108 :   DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
     190         108 :   DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
     191         108 :   DECLARE_OP1(DW_CFA_undefined, OT_Register);
     192         108 :   DECLARE_OP1(DW_CFA_same_value, OT_Register);
     193         108 :   DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
     194         108 :   DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
     195         108 :   DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
     196         108 :   DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
     197         108 :   DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
     198         108 :   DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
     199         108 :   DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
     200         108 :   DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
     201         108 :   DECLARE_OP1(DW_CFA_restore, OT_Register);
     202         108 :   DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
     203         108 :   DECLARE_OP0(DW_CFA_remember_state);
     204         108 :   DECLARE_OP0(DW_CFA_restore_state);
     205         108 :   DECLARE_OP0(DW_CFA_GNU_window_save);
     206         108 :   DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
     207         108 :   DECLARE_OP0(DW_CFA_nop);
     208             : 
     209             : #undef DECLARE_OP0
     210             : #undef DECLARE_OP1
     211             : #undef DECLARE_OP2
     212             : 
     213         108 :   return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
     214             : }
     215             : 
     216             : /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
     217        1881 : void CFIProgram::printOperand(raw_ostream &OS, const MCRegisterInfo *MRI,
     218             :                               bool IsEH, const Instruction &Instr,
     219             :                               unsigned OperandIdx, uint64_t Operand) const {
     220             :   assert(OperandIdx < 2);
     221        1881 :   uint8_t Opcode = Instr.Opcode;
     222        3762 :   OperandType Type = getOperandTypes()[Opcode][OperandIdx];
     223             : 
     224        1881 :   switch (Type) {
     225           0 :   case OT_Unset: {
     226           0 :     OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
     227           0 :     auto OpcodeName = CallFrameString(Opcode);
     228           0 :     if (!OpcodeName.empty())
     229           0 :       OS << " " << OpcodeName;
     230             :     else
     231           0 :       OS << format(" Opcode %x",  Opcode);
     232             :     break;
     233             :   }
     234             :   case OT_None:
     235             :     break;
     236           0 :   case OT_Address:
     237           0 :     OS << format(" %" PRIx64, Operand);
     238           0 :     break;
     239         430 :   case OT_Offset:
     240             :     // The offsets are all encoded in a unsigned form, but in practice
     241             :     // consumers use them signed. It's most certainly legacy due to
     242             :     // the lack of signed variants in the first Dwarf standards.
     243         860 :     OS << format(" %+" PRId64, int64_t(Operand));
     244         430 :     break;
     245         489 :   case OT_FactoredCodeOffset: // Always Unsigned
     246         489 :     if (CodeAlignmentFactor)
     247         978 :       OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
     248             :     else
     249           0 :       OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
     250             :     break;
     251           0 :   case OT_SignedFactDataOffset:
     252           0 :     if (DataAlignmentFactor)
     253           0 :       OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
     254             :     else
     255           0 :       OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
     256             :     break;
     257         303 :   case OT_UnsignedFactDataOffset:
     258         303 :     if (DataAlignmentFactor)
     259         606 :       OS << format(" %" PRId64, Operand * DataAlignmentFactor);
     260             :     else
     261           0 :       OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
     262             :     break;
     263         652 :   case OT_Register:
     264         652 :     OS << format(" reg%" PRId64, Operand);
     265         652 :     break;
     266           7 :   case OT_Expression:
     267             :     assert(Instr.Expression && "missing DWARFExpression object");
     268           7 :     OS << " ";
     269           7 :     Instr.Expression->print(OS, MRI, IsEH);
     270           7 :     break;
     271             :   }
     272        1881 : }
     273             : 
     274         396 : void CFIProgram::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
     275             :                       unsigned IndentLevel) const {
     276         396 :   for (const auto &Instr : Instructions) {
     277        2783 :     uint8_t Opcode = Instr.Opcode;
     278        2783 :     if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
     279             :       Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
     280        2783 :     OS.indent(2 * IndentLevel);
     281        2783 :     OS << CallFrameString(Opcode) << ":";
     282       11209 :     for (unsigned i = 0; i < Instr.Ops.size(); ++i)
     283        1881 :       printOperand(OS, MRI, IsEH, Instr, i, Instr.Ops[i]);
     284             :     OS << '\n';
     285             :   }
     286         396 : }
     287             : 
     288         125 : void CIE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
     289         250 :   OS << format("%08x %08x %08x CIE", (uint32_t)Offset, (uint32_t)Length,
     290         125 :                DW_CIE_ID)
     291         125 :      << "\n";
     292         125 :   OS << format("  Version:               %d\n", Version);
     293         250 :   OS << "  Augmentation:          \"" << Augmentation << "\"\n";
     294         125 :   if (Version >= 4) {
     295          36 :     OS << format("  Address size:          %u\n", (uint32_t)AddressSize);
     296          18 :     OS << format("  Segment desc size:     %u\n",
     297          18 :                  (uint32_t)SegmentDescriptorSize);
     298             :   }
     299         250 :   OS << format("  Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
     300         250 :   OS << format("  Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
     301         250 :   OS << format("  Return address column: %d\n", (int32_t)ReturnAddressRegister);
     302         125 :   if (Personality)
     303          14 :     OS << format("  Personality Address: %08x\n", *Personality);
     304         125 :   if (!AugmentationData.empty()) {
     305          82 :     OS << "  Augmentation data:    ";
     306         332 :     for (uint8_t Byte : AugmentationData)
     307         250 :       OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
     308          82 :     OS << "\n";
     309             :   }
     310         125 :   OS << "\n";
     311         125 :   CFIs.dump(OS, MRI, IsEH);
     312         125 :   OS << "\n";
     313         125 : }
     314             : 
     315         262 : void FDE::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const {
     316         524 :   OS << format("%08x %08x %08x FDE ", (uint32_t)Offset, (uint32_t)Length,
     317         262 :                (int32_t)LinkedCIEOffset);
     318         524 :   OS << format("cie=%08x pc=%08x...%08x\n", (int32_t)LinkedCIEOffset,
     319             :                (uint32_t)InitialLocation,
     320         262 :                (uint32_t)InitialLocation + (uint32_t)AddressRange);
     321         262 :   if (LSDAAddress)
     322          22 :     OS << format("  LSDA Address: %08x\n", *LSDAAddress);
     323         262 :   CFIs.dump(OS, MRI, IsEH);
     324         262 :   OS << "\n";
     325         262 : }
     326             : 
     327         132 : DWARFDebugFrame::DWARFDebugFrame(bool IsEH, uint64_t EHFrameAddress)
     328         264 :     : IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
     329             : 
     330             : DWARFDebugFrame::~DWARFDebugFrame() = default;
     331             : 
     332             : static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
     333             :                                               uint32_t Offset, int Length) {
     334             :   errs() << "DUMP: ";
     335             :   for (int i = 0; i < Length; ++i) {
     336             :     uint8_t c = Data.getU8(&Offset);
     337             :     errs().write_hex(c); errs() << " ";
     338             :   }
     339             :   errs() << "\n";
     340             : }
     341             : 
     342             : // This is a workaround for old compilers which do not allow
     343             : // noreturn attribute usage in lambdas. Once the support for those
     344             : // compilers are phased out, we can remove this and return back to
     345             : // a ReportError lambda: [StartOffset](const char *ErrorMsg).
     346           0 : static void LLVM_ATTRIBUTE_NORETURN ReportError(uint32_t StartOffset,
     347             :                                                 const char *ErrorMsg) {
     348             :   std::string Str;
     349             :   raw_string_ostream OS(Str);
     350           0 :   OS << format(ErrorMsg, StartOffset);
     351             :   OS.flush();
     352           0 :   report_fatal_error(Str);
     353             : }
     354             : 
     355         132 : void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
     356         132 :   uint32_t Offset = 0;
     357             :   DenseMap<uint32_t, CIE *> CIEs;
     358             : 
     359        1461 :   while (Data.isValidOffset(Offset)) {
     360         399 :     uint32_t StartOffset = Offset;
     361             : 
     362             :     bool IsDWARF64 = false;
     363         399 :     uint64_t Length = Data.getU32(&Offset);
     364             :     uint64_t Id;
     365             : 
     366         399 :     if (Length == UINT32_MAX) {
     367             :       // DWARF-64 is distinguished by the first 32 bits of the initial length
     368             :       // field being 0xffffffff. Then, the next 64 bits are the actual entry
     369             :       // length.
     370             :       IsDWARF64 = true;
     371           0 :       Length = Data.getU64(&Offset);
     372             :     }
     373             : 
     374             :     // At this point, Offset points to the next field after Length.
     375             :     // Length is the structure size excluding itself. Compute an offset one
     376             :     // past the end of the structure (needed to know how many instructions to
     377             :     // read).
     378             :     // TODO: For honest DWARF64 support, DataExtractor will have to treat
     379             :     //       offset_ptr as uint64_t*
     380         399 :     uint32_t StartStructureOffset = Offset;
     381         399 :     uint32_t EndStructureOffset = Offset + static_cast<uint32_t>(Length);
     382             : 
     383             :     // The Id field's size depends on the DWARF format
     384         399 :     Id = Data.getUnsigned(&Offset, (IsDWARF64 && !IsEH) ? 8 : 4);
     385             :     bool IsCIE =
     386         399 :         ((IsDWARF64 && Id == DW64_CIE_ID) || Id == DW_CIE_ID || (IsEH && !Id));
     387             : 
     388             :     if (IsCIE) {
     389         130 :       uint8_t Version = Data.getU8(&Offset);
     390         130 :       const char *Augmentation = Data.getCStr(&Offset);
     391         130 :       StringRef AugmentationString(Augmentation ? Augmentation : "");
     392         130 :       uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
     393         130 :                                           Data.getU8(&Offset);
     394             :       Data.setAddressSize(AddressSize);
     395         130 :       uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
     396         130 :       uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
     397         130 :       int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
     398         130 :       uint64_t ReturnAddressRegister = Data.getULEB128(&Offset);
     399             : 
     400             :       // Parse the augmentation data for EH CIEs
     401             :       StringRef AugmentationData("");
     402         130 :       uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
     403         130 :       uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
     404             :       Optional<uint64_t> Personality;
     405             :       Optional<uint32_t> PersonalityEncoding;
     406         130 :       if (IsEH) {
     407             :         Optional<uint64_t> AugmentationLength;
     408             :         uint32_t StartAugmentationOffset;
     409             :         uint32_t EndAugmentationOffset;
     410             : 
     411             :         // Walk the augmentation string to get all the augmentation data.
     412         282 :         for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
     413         370 :           switch (AugmentationString[i]) {
     414           0 :             default:
     415           0 :               ReportError(StartOffset,
     416             :                           "Unknown augmentation character in entry at %lx");
     417           8 :             case 'L':
     418           8 :               LSDAPointerEncoding = Data.getU8(&Offset);
     419           8 :               break;
     420           7 :             case 'P': {
     421           7 :               if (Personality)
     422           0 :                 ReportError(StartOffset,
     423             :                             "Duplicate personality in entry at %lx");
     424           7 :               PersonalityEncoding = Data.getU8(&Offset);
     425          21 :               Personality = Data.getEncodedPointer(
     426           7 :                   &Offset, *PersonalityEncoding,
     427           7 :                   EHFrameAddress ? EHFrameAddress + Offset : 0);
     428           7 :               break;
     429             :             }
     430          85 :             case 'R':
     431          85 :               FDEPointerEncoding = Data.getU8(&Offset);
     432          85 :               break;
     433             :             case 'S':
     434             :               // Current frame is a signal trampoline.
     435             :               break;
     436          85 :             case 'z':
     437          85 :               if (i)
     438           0 :                 ReportError(StartOffset,
     439             :                             "'z' must be the first character at %lx");
     440             :               // Parse the augmentation length first.  We only parse it if
     441             :               // the string contains a 'z'.
     442          85 :               AugmentationLength = Data.getULEB128(&Offset);
     443          85 :               StartAugmentationOffset = Offset;
     444          85 :               EndAugmentationOffset = Offset +
     445             :                 static_cast<uint32_t>(*AugmentationLength);
     446             :           }
     447             :         }
     448             : 
     449          97 :         if (AugmentationLength.hasValue()) {
     450          85 :           if (Offset != EndAugmentationOffset)
     451           0 :             ReportError(StartOffset, "Parsing augmentation data at %lx failed");
     452             : 
     453         170 :           AugmentationData = Data.getData().slice(StartAugmentationOffset,
     454          85 :                                                   EndAugmentationOffset);
     455             :         }
     456             :       }
     457             : 
     458             :       auto Cie = llvm::make_unique<CIE>(
     459             :           StartOffset, Length, Version, AugmentationString, AddressSize,
     460             :           SegmentDescriptorSize, CodeAlignmentFactor, DataAlignmentFactor,
     461             :           ReturnAddressRegister, AugmentationData, FDEPointerEncoding,
     462         130 :           LSDAPointerEncoding, Personality, PersonalityEncoding);
     463         130 :       CIEs[StartOffset] = Cie.get();
     464         130 :       Entries.emplace_back(std::move(Cie));
     465             :     } else {
     466             :       // FDE
     467             :       uint64_t CIEPointer = Id;
     468             :       uint64_t InitialLocation = 0;
     469             :       uint64_t AddressRange = 0;
     470             :       Optional<uint64_t> LSDAAddress;
     471         768 :       CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
     472             : 
     473         269 :       if (IsEH) {
     474             :         // The address size is encoded in the CIE we reference.
     475         230 :         if (!Cie)
     476           0 :           ReportError(StartOffset,
     477             :                       "Parsing FDE data at %lx failed due to missing CIE");
     478             : 
     479         230 :         if (auto Val = Data.getEncodedPointer(
     480         230 :                 &Offset, Cie->getFDEPointerEncoding(),
     481         460 :                 EHFrameAddress ? EHFrameAddress + Offset : 0)) {
     482         230 :           InitialLocation = *Val;
     483             :         }
     484         230 :         if (auto Val = Data.getEncodedPointer(
     485         230 :                 &Offset, Cie->getFDEPointerEncoding(), 0)) {
     486         230 :           AddressRange = *Val;
     487             :         }
     488             : 
     489             :         StringRef AugmentationString = Cie->getAugmentationString();
     490         230 :         if (!AugmentationString.empty()) {
     491             :           // Parse the augmentation length and data for this FDE.
     492         230 :           uint64_t AugmentationLength = Data.getULEB128(&Offset);
     493             : 
     494         230 :           uint32_t EndAugmentationOffset =
     495         230 :             Offset + static_cast<uint32_t>(AugmentationLength);
     496             : 
     497             :           // Decode the LSDA if the CIE augmentation string said we should.
     498         230 :           if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
     499          22 :             LSDAAddress = Data.getEncodedPointer(
     500             :                 &Offset, Cie->getLSDAPointerEncoding(),
     501          11 :                 EHFrameAddress ? Offset + EHFrameAddress : 0);
     502             :           }
     503             : 
     504         230 :           if (Offset != EndAugmentationOffset)
     505           0 :             ReportError(StartOffset, "Parsing augmentation data at %lx failed");
     506             :         }
     507             :       } else {
     508             :         InitialLocation = Data.getAddress(&Offset);
     509             :         AddressRange = Data.getAddress(&Offset);
     510             :       }
     511             : 
     512         538 :       Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,
     513             :                                    InitialLocation, AddressRange,
     514         269 :                                    Cie, LSDAAddress));
     515             :     }
     516             : 
     517         399 :     if (Error E =
     518         399 :             Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset)) {
     519           0 :       report_fatal_error(toString(std::move(E)));
     520             :     }
     521             : 
     522         399 :     if (Offset != EndStructureOffset)
     523           0 :       ReportError(StartOffset, "Parsing entry instructions at %lx failed");
     524             :   }
     525         132 : }
     526             : 
     527           4 : FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
     528             :   auto It =
     529             :       std::lower_bound(Entries.begin(), Entries.end(), Offset,
     530             :                        [](const std::unique_ptr<FrameEntry> &E,
     531           8 :                           uint64_t Offset) { return E->getOffset() < Offset; });
     532           6 :   if (It != Entries.end() && (*It)->getOffset() == Offset)
     533             :     return It->get();
     534             :   return nullptr;
     535             : }
     536             : 
     537         131 : void DWARFDebugFrame::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
     538             :                            Optional<uint64_t> Offset) const {
     539         131 :   if (Offset) {
     540           4 :     if (auto *Entry = getEntryAtOffset(*Offset))
     541           2 :       Entry->dump(OS, MRI, IsEH);
     542             :     return;
     543             :   }
     544             : 
     545         127 :   OS << "\n";
     546         127 :   for (const auto &Entry : Entries)
     547         385 :     Entry->dump(OS, MRI, IsEH);
     548             : }

Generated by: LCOV version 1.13