Coverage Report

Created: 2019-07-24 05:18

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