LLVM  15.0.0git
DWARFDebugFrame.cpp
Go to the documentation of this file.
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 
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
17 #include "llvm/MC/MCRegisterInfo.h"
18 #include "llvm/Support/Compiler.h"
20 #include "llvm/Support/Errc.h"
22 #include "llvm/Support/Format.h"
24 #include <algorithm>
25 #include <cassert>
26 #include <cinttypes>
27 #include <cstdint>
28 
29 using namespace llvm;
30 using namespace dwarf;
31 
32 static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
33  unsigned RegNum) {
34  if (MRI) {
35  if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
36  if (const char *RegName = MRI->getName(*LLVMRegNum)) {
37  OS << RegName;
38  return;
39  }
40  }
41  }
42  OS << "reg" << RegNum;
43 }
44 
46 
48 
50 
52  return {Constant, InvalidRegisterNumber, Value, None, false};
53 }
54 
56  return {CFAPlusOffset, InvalidRegisterNumber, Offset, None, false};
57 }
58 
60  return {CFAPlusOffset, InvalidRegisterNumber, Offset, None, true};
61 }
62 
65  Optional<uint32_t> AddrSpace) {
66  return {RegPlusOffset, RegNum, Offset, AddrSpace, false};
67 }
68 
71  Optional<uint32_t> AddrSpace) {
72  return {RegPlusOffset, RegNum, Offset, AddrSpace, true};
73 }
74 
76  return {Expr, false};
77 }
78 
80  return {Expr, true};
81 }
82 
84  bool IsEH) const {
85  if (Dereference)
86  OS << '[';
87  switch (Kind) {
88  case Unspecified:
89  OS << "unspecified";
90  break;
91  case Undefined:
92  OS << "undefined";
93  break;
94  case Same:
95  OS << "same";
96  break;
97  case CFAPlusOffset:
98  OS << "CFA";
99  if (Offset == 0)
100  break;
101  if (Offset > 0)
102  OS << "+";
103  OS << Offset;
104  break;
105  case RegPlusOffset:
106  printRegister(OS, MRI, IsEH, RegNum);
107  if (Offset == 0 && !AddrSpace)
108  break;
109  if (Offset >= 0)
110  OS << "+";
111  OS << Offset;
112  if (AddrSpace)
113  OS << " in addrspace" << *AddrSpace;
114  break;
115  case DWARFExpr:
116  Expr->print(OS, DIDumpOptions(), MRI, nullptr, IsEH);
117  break;
118  case Constant:
119  OS << Offset;
120  break;
121  }
122  if (Dereference)
123  OS << ']';
124 }
125 
127  const UnwindLocation &UL) {
128  UL.dump(OS, nullptr, false);
129  return OS;
130 }
131 
133  if (Kind != RHS.Kind)
134  return false;
135  switch (Kind) {
136  case Unspecified:
137  case Undefined:
138  case Same:
139  return true;
140  case CFAPlusOffset:
141  return Offset == RHS.Offset && Dereference == RHS.Dereference;
142  case RegPlusOffset:
143  return RegNum == RHS.RegNum && Offset == RHS.Offset &&
144  Dereference == RHS.Dereference;
145  case DWARFExpr:
146  return *Expr == *RHS.Expr && Dereference == RHS.Dereference;
147  case Constant:
148  return Offset == RHS.Offset;
149  }
150  return false;
151 }
152 
154  bool IsEH) const {
155  bool First = true;
156  for (const auto &RegLocPair : Locations) {
157  if (First)
158  First = false;
159  else
160  OS << ", ";
161  printRegister(OS, MRI, IsEH, RegLocPair.first);
162  OS << '=';
163  RegLocPair.second.dump(OS, MRI, IsEH);
164  }
165 }
166 
168  const RegisterLocations &RL) {
169  RL.dump(OS, nullptr, false);
170  return OS;
171 }
172 
173 void UnwindRow::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
174  unsigned IndentLevel) const {
175  OS.indent(2 * IndentLevel);
176  if (hasAddress())
177  OS << format("0x%" PRIx64 ": ", *Address);
178  OS << "CFA=";
179  CFAValue.dump(OS, MRI, IsEH);
180  if (RegLocs.hasLocations()) {
181  OS << ": ";
182  RegLocs.dump(OS, MRI, IsEH);
183  }
184  OS << "\n";
185 }
186 
188  Row.dump(OS, nullptr, false, 0);
189  return OS;
190 }
191 
192 void UnwindTable::dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
193  unsigned IndentLevel) const {
194  for (const UnwindRow &Row : Rows)
195  Row.dump(OS, MRI, IsEH, IndentLevel);
196 }
197 
199  Rows.dump(OS, nullptr, false, 0);
200  return OS;
201 }
202 
204  const CIE *Cie = Fde->getLinkedCIE();
205  if (Cie == nullptr)
207  "unable to get CIE for FDE at offset 0x%" PRIx64,
208  Fde->getOffset());
209 
210  // Rows will be empty if there are no CFI instructions.
211  if (Cie->cfis().empty() && Fde->cfis().empty())
212  return UnwindTable();
213 
214  UnwindTable UT;
215  UnwindRow Row;
216  Row.setAddress(Fde->getInitialLocation());
217  UT.EndAddress = Fde->getInitialLocation() + Fde->getAddressRange();
218  if (Error CieError = UT.parseRows(Cie->cfis(), Row, nullptr))
219  return std::move(CieError);
220  // We need to save the initial locations of registers from the CIE parsing
221  // in case we run into DW_CFA_restore or DW_CFA_restore_extended opcodes.
222  const RegisterLocations InitialLocs = Row.getRegisterLocations();
223  if (Error FdeError = UT.parseRows(Fde->cfis(), Row, &InitialLocs))
224  return std::move(FdeError);
225  // May be all the CFI instructions were DW_CFA_nop amd Row becomes empty.
226  // Do not add that to the unwind table.
227  if (Row.getRegisterLocations().hasLocations() ||
228  Row.getCFAValue().getLocation() != UnwindLocation::Unspecified)
229  UT.Rows.push_back(Row);
230  return UT;
231 }
232 
234  // Rows will be empty if there are no CFI instructions.
235  if (Cie->cfis().empty())
236  return UnwindTable();
237 
238  UnwindTable UT;
239  UnwindRow Row;
240  if (Error CieError = UT.parseRows(Cie->cfis(), Row, nullptr))
241  return std::move(CieError);
242  // May be all the CFI instructions were DW_CFA_nop amd Row becomes empty.
243  // Do not add that to the unwind table.
244  if (Row.getRegisterLocations().hasLocations() ||
245  Row.getCFAValue().getLocation() != UnwindLocation::Unspecified)
246  UT.Rows.push_back(Row);
247  return UT;
248 }
249 
250 // See DWARF standard v3, section 7.23
251 const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
252 const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
253 
255  uint64_t EndOffset) {
256  DataExtractor::Cursor C(*Offset);
257  while (C && C.tell() < EndOffset) {
258  uint8_t Opcode = Data.getRelocatedValue(C, 1);
259  if (!C)
260  break;
261 
262  // Some instructions have a primary opcode encoded in the top bits.
263  if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
264  // If it's a primary opcode, the first operand is encoded in the bottom
265  // bits of the opcode itself.
267  switch (Primary) {
268  case DW_CFA_advance_loc:
269  case DW_CFA_restore:
270  addInstruction(Primary, Op1);
271  break;
272  case DW_CFA_offset:
273  addInstruction(Primary, Op1, Data.getULEB128(C));
274  break;
275  default:
276  llvm_unreachable("invalid primary CFI opcode");
277  }
278  continue;
279  }
280 
281  // Extended opcode - its value is Opcode itself.
282  switch (Opcode) {
283  default:
285  "invalid extended CFI opcode 0x%" PRIx8, Opcode);
286  case DW_CFA_nop:
287  case DW_CFA_remember_state:
288  case DW_CFA_restore_state:
289  case DW_CFA_GNU_window_save:
290  // No operands
291  addInstruction(Opcode);
292  break;
293  case DW_CFA_set_loc:
294  // Operands: Address
295  addInstruction(Opcode, Data.getRelocatedAddress(C));
296  break;
297  case DW_CFA_advance_loc1:
298  // Operands: 1-byte delta
299  addInstruction(Opcode, Data.getRelocatedValue(C, 1));
300  break;
301  case DW_CFA_advance_loc2:
302  // Operands: 2-byte delta
303  addInstruction(Opcode, Data.getRelocatedValue(C, 2));
304  break;
305  case DW_CFA_advance_loc4:
306  // Operands: 4-byte delta
307  addInstruction(Opcode, Data.getRelocatedValue(C, 4));
308  break;
309  case DW_CFA_restore_extended:
310  case DW_CFA_undefined:
311  case DW_CFA_same_value:
312  case DW_CFA_def_cfa_register:
313  case DW_CFA_def_cfa_offset:
314  case DW_CFA_GNU_args_size:
315  // Operands: ULEB128
316  addInstruction(Opcode, Data.getULEB128(C));
317  break;
318  case DW_CFA_def_cfa_offset_sf:
319  // Operands: SLEB128
320  addInstruction(Opcode, Data.getSLEB128(C));
321  break;
322  case DW_CFA_LLVM_def_aspace_cfa:
323  case DW_CFA_LLVM_def_aspace_cfa_sf: {
324  auto RegNum = Data.getULEB128(C);
325  auto CfaOffset = Opcode == DW_CFA_LLVM_def_aspace_cfa
326  ? Data.getULEB128(C)
327  : Data.getSLEB128(C);
328  auto AddressSpace = Data.getULEB128(C);
329  addInstruction(Opcode, RegNum, CfaOffset, AddressSpace);
330  break;
331  }
332  case DW_CFA_offset_extended:
333  case DW_CFA_register:
334  case DW_CFA_def_cfa:
335  case DW_CFA_val_offset: {
336  // Operands: ULEB128, ULEB128
337  // Note: We can not embed getULEB128 directly into function
338  // argument list. getULEB128 changes Offset and order of evaluation
339  // for arguments is unspecified.
340  uint64_t op1 = Data.getULEB128(C);
341  uint64_t op2 = Data.getULEB128(C);
342  addInstruction(Opcode, op1, op2);
343  break;
344  }
345  case DW_CFA_offset_extended_sf:
346  case DW_CFA_def_cfa_sf:
347  case DW_CFA_val_offset_sf: {
348  // Operands: ULEB128, SLEB128
349  // Note: see comment for the previous case
350  uint64_t op1 = Data.getULEB128(C);
351  uint64_t op2 = (uint64_t)Data.getSLEB128(C);
352  addInstruction(Opcode, op1, op2);
353  break;
354  }
355  case DW_CFA_def_cfa_expression: {
356  uint64_t ExprLength = Data.getULEB128(C);
357  addInstruction(Opcode, 0);
358  StringRef Expression = Data.getBytes(C, ExprLength);
359 
360  DataExtractor Extractor(Expression, Data.isLittleEndian(),
361  Data.getAddressSize());
362  // Note. We do not pass the DWARF format to DWARFExpression, because
363  // DW_OP_call_ref, the only operation which depends on the format, is
364  // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
365  Instructions.back().Expression =
366  DWARFExpression(Extractor, Data.getAddressSize());
367  break;
368  }
369  case DW_CFA_expression:
370  case DW_CFA_val_expression: {
371  uint64_t RegNum = Data.getULEB128(C);
372  addInstruction(Opcode, RegNum, 0);
373 
374  uint64_t BlockLength = Data.getULEB128(C);
375  StringRef Expression = Data.getBytes(C, BlockLength);
376  DataExtractor Extractor(Expression, Data.isLittleEndian(),
377  Data.getAddressSize());
378  // Note. We do not pass the DWARF format to DWARFExpression, because
379  // DW_OP_call_ref, the only operation which depends on the format, is
380  // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
381  Instructions.back().Expression =
382  DWARFExpression(Extractor, Data.getAddressSize());
383  break;
384  }
385  }
386  }
387 
388  *Offset = C.tell();
389  return C.takeError();
390 }
391 
392 StringRef CFIProgram::callFrameString(unsigned Opcode) const {
393  return dwarf::CallFrameString(Opcode, Arch);
394 }
395 
396 const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT) {
397 #define ENUM_TO_CSTR(e) \
398  case e: \
399  return #e;
400  switch (OT) {
401  ENUM_TO_CSTR(OT_Unset);
402  ENUM_TO_CSTR(OT_None);
403  ENUM_TO_CSTR(OT_Address);
404  ENUM_TO_CSTR(OT_Offset);
405  ENUM_TO_CSTR(OT_FactoredCodeOffset);
406  ENUM_TO_CSTR(OT_SignedFactDataOffset);
407  ENUM_TO_CSTR(OT_UnsignedFactDataOffset);
408  ENUM_TO_CSTR(OT_Register);
409  ENUM_TO_CSTR(OT_AddressSpace);
410  ENUM_TO_CSTR(OT_Expression);
411  }
412  return "<unknown CFIProgram::OperandType>";
413 }
414 
417  uint32_t OperandIdx) const {
418  if (OperandIdx >= MaxOperands)
420  "operand index %" PRIu32 " is not valid",
421  OperandIdx);
422  OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
423  uint64_t Operand = Ops[OperandIdx];
424  switch (Type) {
425  case OT_Unset:
426  case OT_None:
427  case OT_Expression:
429  "op[%" PRIu32 "] has type %s which has no value",
430  OperandIdx, CFIProgram::operandTypeString(Type));
431 
432  case OT_Offset:
433  case OT_SignedFactDataOffset:
434  case OT_UnsignedFactDataOffset:
435  return createStringError(
437  "op[%" PRIu32 "] has OperandType OT_Offset which produces a signed "
438  "result, call getOperandAsSigned instead",
439  OperandIdx);
440 
441  case OT_Address:
442  case OT_Register:
443  case OT_AddressSpace:
444  return Operand;
445 
446  case OT_FactoredCodeOffset: {
447  const uint64_t CodeAlignmentFactor = CFIP.codeAlign();
448  if (CodeAlignmentFactor == 0)
449  return createStringError(
451  "op[%" PRIu32 "] has type OT_FactoredCodeOffset but code alignment "
452  "is zero",
453  OperandIdx);
454  return Operand * CodeAlignmentFactor;
455  }
456  }
457  llvm_unreachable("invalid operand type");
458 }
459 
462  uint32_t OperandIdx) const {
463  if (OperandIdx >= MaxOperands)
465  "operand index %" PRIu32 " is not valid",
466  OperandIdx);
467  OperandType Type = CFIP.getOperandTypes()[Opcode][OperandIdx];
468  uint64_t Operand = Ops[OperandIdx];
469  switch (Type) {
470  case OT_Unset:
471  case OT_None:
472  case OT_Expression:
474  "op[%" PRIu32 "] has type %s which has no value",
475  OperandIdx, CFIProgram::operandTypeString(Type));
476 
477  case OT_Address:
478  case OT_Register:
479  case OT_AddressSpace:
480  return createStringError(
482  "op[%" PRIu32 "] has OperandType %s which produces an unsigned result, "
483  "call getOperandAsUnsigned instead",
484  OperandIdx, CFIProgram::operandTypeString(Type));
485 
486  case OT_Offset:
487  return (int64_t)Operand;
488 
489  case OT_FactoredCodeOffset:
490  case OT_SignedFactDataOffset: {
491  const int64_t DataAlignmentFactor = CFIP.dataAlign();
492  if (DataAlignmentFactor == 0)
494  "op[%" PRIu32 "] has type %s but data "
495  "alignment is zero",
496  OperandIdx, CFIProgram::operandTypeString(Type));
497  return int64_t(Operand) * DataAlignmentFactor;
498  }
499 
500  case OT_UnsignedFactDataOffset: {
501  const int64_t DataAlignmentFactor = CFIP.dataAlign();
502  if (DataAlignmentFactor == 0)
504  "op[%" PRIu32
505  "] has type OT_UnsignedFactDataOffset but data "
506  "alignment is zero",
507  OperandIdx);
508  return Operand * DataAlignmentFactor;
509  }
510  }
511  llvm_unreachable("invalid operand type");
512 }
513 
514 Error UnwindTable::parseRows(const CFIProgram &CFIP, UnwindRow &Row,
515  const RegisterLocations *InitialLocs) {
516  std::vector<RegisterLocations> RegisterStates;
517  for (const CFIProgram::Instruction &Inst : CFIP) {
518  switch (Inst.Opcode) {
519  case dwarf::DW_CFA_set_loc: {
520  // The DW_CFA_set_loc instruction takes a single operand that
521  // represents a target address. The required action is to create a new
522  // table row using the specified address as the location. All other
523  // values in the new row are initially identical to the current row.
524  // The new location value is always greater than the current one. If
525  // the segment_size field of this FDE's CIE is non- zero, the initial
526  // location is preceded by a segment selector of the given length
527  llvm::Expected<uint64_t> NewAddress = Inst.getOperandAsUnsigned(CFIP, 0);
528  if (!NewAddress)
529  return NewAddress.takeError();
530  if (*NewAddress <= Row.getAddress())
531  return createStringError(
533  "%s with adrress 0x%" PRIx64 " which must be greater than the "
534  "current row address 0x%" PRIx64,
535  CFIP.callFrameString(Inst.Opcode).str().c_str(), *NewAddress,
536  Row.getAddress());
537  Rows.push_back(Row);
538  Row.setAddress(*NewAddress);
539  break;
540  }
541 
542  case dwarf::DW_CFA_advance_loc:
543  case dwarf::DW_CFA_advance_loc1:
544  case dwarf::DW_CFA_advance_loc2:
545  case dwarf::DW_CFA_advance_loc4: {
546  // The DW_CFA_advance instruction takes a single operand that
547  // represents a constant delta. The required action is to create a new
548  // table row with a location value that is computed by taking the
549  // current entry‚Äôs location value and adding the value of delta *
550  // code_alignment_factor. All other values in the new row are initially
551  // identical to the current row.
552  Rows.push_back(Row);
553  llvm::Expected<uint64_t> Offset = Inst.getOperandAsUnsigned(CFIP, 0);
554  if (!Offset)
555  return Offset.takeError();
556  Row.slideAddress(*Offset);
557  break;
558  }
559 
560  case dwarf::DW_CFA_restore:
561  case dwarf::DW_CFA_restore_extended: {
562  // The DW_CFA_restore instruction takes a single operand (encoded with
563  // the opcode) that represents a register number. The required action
564  // is to change the rule for the indicated register to the rule
565  // assigned it by the initial_instructions in the CIE.
566  if (InitialLocs == nullptr)
567  return createStringError(
568  errc::invalid_argument, "%s encountered while parsing a CIE",
569  CFIP.callFrameString(Inst.Opcode).str().c_str());
570  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
571  if (!RegNum)
572  return RegNum.takeError();
574  InitialLocs->getRegisterLocation(*RegNum))
575  Row.getRegisterLocations().setRegisterLocation(*RegNum, *O);
576  else
577  Row.getRegisterLocations().removeRegisterLocation(*RegNum);
578  break;
579  }
580 
581  case dwarf::DW_CFA_offset:
582  case dwarf::DW_CFA_offset_extended:
583  case dwarf::DW_CFA_offset_extended_sf: {
584  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
585  if (!RegNum)
586  return RegNum.takeError();
587  llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1);
588  if (!Offset)
589  return Offset.takeError();
590  Row.getRegisterLocations().setRegisterLocation(
591  *RegNum, UnwindLocation::createAtCFAPlusOffset(*Offset));
592  break;
593  }
594 
595  case dwarf::DW_CFA_nop:
596  break;
597 
598  case dwarf::DW_CFA_remember_state:
599  RegisterStates.push_back(Row.getRegisterLocations());
600  break;
601 
602  case dwarf::DW_CFA_restore_state:
603  if (RegisterStates.empty())
605  "DW_CFA_restore_state without a matching "
606  "previous DW_CFA_remember_state");
607  Row.getRegisterLocations() = RegisterStates.back();
608  RegisterStates.pop_back();
609  break;
610 
611  case dwarf::DW_CFA_GNU_window_save:
612  switch (CFIP.triple()) {
613  case Triple::aarch64:
614  case Triple::aarch64_be:
615  case Triple::aarch64_32: {
616  // DW_CFA_GNU_window_save is used for different things on different
617  // architectures. For aarch64 it is known as
618  // DW_CFA_AARCH64_negate_ra_state. The action is to toggle the
619  // value of the return address state between 1 and 0. If there is
620  // no rule for the AARCH64_DWARF_PAUTH_RA_STATE register, then it
621  // should be initially set to 1.
622  constexpr uint32_t AArch64DWARFPAuthRaState = 34;
623  auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
624  AArch64DWARFPAuthRaState);
625  if (LRLoc) {
626  if (LRLoc->getLocation() == UnwindLocation::Constant) {
627  // Toggle the constant value from 0 to 1 or 1 to 0.
628  LRLoc->setConstant(LRLoc->getConstant() ^ 1);
629  } else {
630  return createStringError(
632  "%s encountered when existing rule for this register is not "
633  "a constant",
634  CFIP.callFrameString(Inst.Opcode).str().c_str());
635  }
636  } else {
637  Row.getRegisterLocations().setRegisterLocation(
638  AArch64DWARFPAuthRaState, UnwindLocation::createIsConstant(1));
639  }
640  break;
641  }
642 
643  case Triple::sparc:
644  case Triple::sparcv9:
645  case Triple::sparcel:
646  for (uint32_t RegNum = 16; RegNum < 32; ++RegNum) {
647  Row.getRegisterLocations().setRegisterLocation(
648  RegNum, UnwindLocation::createAtCFAPlusOffset((RegNum - 16) * 8));
649  }
650  break;
651 
652  default: {
653  return createStringError(
655  "DW_CFA opcode %#x is not supported for architecture %s",
656  Inst.Opcode, Triple::getArchTypeName(CFIP.triple()).str().c_str());
657 
658  break;
659  }
660  }
661  break;
662 
663  case dwarf::DW_CFA_undefined: {
664  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
665  if (!RegNum)
666  return RegNum.takeError();
667  Row.getRegisterLocations().setRegisterLocation(
669  break;
670  }
671 
672  case dwarf::DW_CFA_same_value: {
673  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
674  if (!RegNum)
675  return RegNum.takeError();
676  Row.getRegisterLocations().setRegisterLocation(
677  *RegNum, UnwindLocation::createSame());
678  break;
679  }
680 
681  case dwarf::DW_CFA_GNU_args_size:
682  break;
683 
684  case dwarf::DW_CFA_register: {
685  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
686  if (!RegNum)
687  return RegNum.takeError();
688  llvm::Expected<uint64_t> NewRegNum = Inst.getOperandAsUnsigned(CFIP, 1);
689  if (!NewRegNum)
690  return NewRegNum.takeError();
691  Row.getRegisterLocations().setRegisterLocation(
692  *RegNum, UnwindLocation::createIsRegisterPlusOffset(*NewRegNum, 0));
693  break;
694  }
695 
696  case dwarf::DW_CFA_val_offset:
697  case dwarf::DW_CFA_val_offset_sf: {
698  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
699  if (!RegNum)
700  return RegNum.takeError();
701  llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1);
702  if (!Offset)
703  return Offset.takeError();
704  Row.getRegisterLocations().setRegisterLocation(
705  *RegNum, UnwindLocation::createIsCFAPlusOffset(*Offset));
706  break;
707  }
708 
709  case dwarf::DW_CFA_expression: {
710  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
711  if (!RegNum)
712  return RegNum.takeError();
713  Row.getRegisterLocations().setRegisterLocation(
714  *RegNum, UnwindLocation::createAtDWARFExpression(*Inst.Expression));
715  break;
716  }
717 
718  case dwarf::DW_CFA_val_expression: {
719  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
720  if (!RegNum)
721  return RegNum.takeError();
722  Row.getRegisterLocations().setRegisterLocation(
723  *RegNum, UnwindLocation::createIsDWARFExpression(*Inst.Expression));
724  break;
725  }
726 
727  case dwarf::DW_CFA_def_cfa_register: {
728  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
729  if (!RegNum)
730  return RegNum.takeError();
731  if (Row.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset)
732  Row.getCFAValue() =
734  else
735  Row.getCFAValue().setRegister(*RegNum);
736  break;
737  }
738 
739  case dwarf::DW_CFA_def_cfa_offset:
740  case dwarf::DW_CFA_def_cfa_offset_sf: {
741  llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 0);
742  if (!Offset)
743  return Offset.takeError();
744  if (Row.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset) {
745  return createStringError(
747  "%s found when CFA rule was not RegPlusOffset",
748  CFIP.callFrameString(Inst.Opcode).str().c_str());
749  }
750  Row.getCFAValue().setOffset(*Offset);
751  break;
752  }
753 
754  case dwarf::DW_CFA_def_cfa:
755  case dwarf::DW_CFA_def_cfa_sf: {
756  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
757  if (!RegNum)
758  return RegNum.takeError();
759  llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1);
760  if (!Offset)
761  return Offset.takeError();
762  Row.getCFAValue() =
764  break;
765  }
766 
767  case dwarf::DW_CFA_LLVM_def_aspace_cfa:
768  case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {
769  llvm::Expected<uint64_t> RegNum = Inst.getOperandAsUnsigned(CFIP, 0);
770  if (!RegNum)
771  return RegNum.takeError();
772  llvm::Expected<int64_t> Offset = Inst.getOperandAsSigned(CFIP, 1);
773  if (!Offset)
774  return Offset.takeError();
775  llvm::Expected<uint32_t> CFAAddrSpace =
776  Inst.getOperandAsUnsigned(CFIP, 2);
777  if (!CFAAddrSpace)
778  return CFAAddrSpace.takeError();
779  Row.getCFAValue() = UnwindLocation::createIsRegisterPlusOffset(
780  *RegNum, *Offset, *CFAAddrSpace);
781  break;
782  }
783 
784  case dwarf::DW_CFA_def_cfa_expression:
785  Row.getCFAValue() =
786  UnwindLocation::createIsDWARFExpression(*Inst.Expression);
787  break;
788  }
789  }
790  return Error::success();
791 }
792 
794 CFIProgram::getOperandTypes() {
795  static OperandType OpTypes[DW_CFA_restore + 1][MaxOperands];
796  static bool Initialized = false;
797  if (Initialized) {
798  return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
799  }
800  Initialized = true;
801 
802 #define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
803  do { \
804  OpTypes[OP][0] = OPTYPE0; \
805  OpTypes[OP][1] = OPTYPE1; \
806  OpTypes[OP][2] = OPTYPE2; \
807  } while (false)
808 #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
809  DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OT_None)
810 #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
811 #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
812 
813  DECLARE_OP1(DW_CFA_set_loc, OT_Address);
814  DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
815  DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
816  DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
817  DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
818  DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
819  DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
820  DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
821  DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
822  DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa, OT_Register, OT_Offset,
823  OT_AddressSpace);
824  DECLARE_OP3(DW_CFA_LLVM_def_aspace_cfa_sf, OT_Register,
825  OT_SignedFactDataOffset, OT_AddressSpace);
826  DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
827  DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
828  DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
829  DECLARE_OP1(DW_CFA_undefined, OT_Register);
830  DECLARE_OP1(DW_CFA_same_value, OT_Register);
831  DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
832  DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
833  DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
834  DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
835  DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
836  DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
837  DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
838  DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
839  DECLARE_OP1(DW_CFA_restore, OT_Register);
840  DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
841  DECLARE_OP0(DW_CFA_remember_state);
842  DECLARE_OP0(DW_CFA_restore_state);
843  DECLARE_OP0(DW_CFA_GNU_window_save);
844  DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
845  DECLARE_OP0(DW_CFA_nop);
846 
847 #undef DECLARE_OP0
848 #undef DECLARE_OP1
849 #undef DECLARE_OP2
850 
851  return ArrayRef<OperandType[MaxOperands]>(&OpTypes[0], DW_CFA_restore + 1);
852 }
853 
854 /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
855 void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
856  const MCRegisterInfo *MRI, bool IsEH,
857  const Instruction &Instr, unsigned OperandIdx,
858  uint64_t Operand) const {
859  assert(OperandIdx < MaxOperands);
860  uint8_t Opcode = Instr.Opcode;
861  OperandType Type = getOperandTypes()[Opcode][OperandIdx];
862 
863  switch (Type) {
864  case OT_Unset: {
865  OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
866  auto OpcodeName = callFrameString(Opcode);
867  if (!OpcodeName.empty())
868  OS << " " << OpcodeName;
869  else
870  OS << format(" Opcode %x", Opcode);
871  break;
872  }
873  case OT_None:
874  break;
875  case OT_Address:
876  OS << format(" %" PRIx64, Operand);
877  break;
878  case OT_Offset:
879  // The offsets are all encoded in a unsigned form, but in practice
880  // consumers use them signed. It's most certainly legacy due to
881  // the lack of signed variants in the first Dwarf standards.
882  OS << format(" %+" PRId64, int64_t(Operand));
883  break;
884  case OT_FactoredCodeOffset: // Always Unsigned
885  if (CodeAlignmentFactor)
886  OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
887  else
888  OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
889  break;
890  case OT_SignedFactDataOffset:
891  if (DataAlignmentFactor)
892  OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
893  else
894  OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
895  break;
896  case OT_UnsignedFactDataOffset:
897  if (DataAlignmentFactor)
898  OS << format(" %" PRId64, Operand * DataAlignmentFactor);
899  else
900  OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
901  break;
902  case OT_Register:
903  OS << ' ';
904  printRegister(OS, MRI, IsEH, Operand);
905  break;
906  case OT_AddressSpace:
907  OS << format(" in addrspace%" PRId64, Operand);
908  break;
909  case OT_Expression:
910  assert(Instr.Expression && "missing DWARFExpression object");
911  OS << " ";
912  Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
913  break;
914  }
915 }
916 
918  const MCRegisterInfo *MRI, bool IsEH,
919  unsigned IndentLevel) const {
920  for (const auto &Instr : Instructions) {
921  uint8_t Opcode = Instr.Opcode;
922  OS.indent(2 * IndentLevel);
923  OS << callFrameString(Opcode) << ":";
924  for (unsigned i = 0; i < Instr.Ops.size(); ++i)
925  printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
926  OS << '\n';
927  }
928 }
929 
930 // Returns the CIE identifier to be used by the requested format.
931 // CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
932 // For CIE ID in .eh_frame sections see
933 // https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
934 constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
935  if (IsEH)
936  return 0;
937  if (IsDWARF64)
938  return DW64_CIE_ID;
939  return DW_CIE_ID;
940 }
941 
943  const MCRegisterInfo *MRI, bool IsEH) const {
944  // A CIE with a zero length is a terminator entry in the .eh_frame section.
945  if (IsEH && Length == 0) {
946  OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
947  return;
948  }
949 
950  OS << format("%08" PRIx64, Offset)
951  << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
952  << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
953  getCIEId(IsDWARF64, IsEH))
954  << " CIE\n"
955  << " Format: " << FormatString(IsDWARF64) << "\n";
956  if (IsEH && Version != 1)
957  OS << "WARNING: unsupported CIE version\n";
958  OS << format(" Version: %d\n", Version)
959  << " Augmentation: \"" << Augmentation << "\"\n";
960  if (Version >= 4) {
961  OS << format(" Address size: %u\n", (uint32_t)AddressSize);
962  OS << format(" Segment desc size: %u\n",
963  (uint32_t)SegmentDescriptorSize);
964  }
965  OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
966  OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
967  OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister);
968  if (Personality)
969  OS << format(" Personality Address: %016" PRIx64 "\n", *Personality);
970  if (!AugmentationData.empty()) {
971  OS << " Augmentation data: ";
972  for (uint8_t Byte : AugmentationData)
973  OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
974  OS << "\n";
975  }
976  OS << "\n";
977  CFIs.dump(OS, DumpOpts, MRI, IsEH);
978  OS << "\n";
979 
980  if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))
981  RowsOrErr->dump(OS, MRI, IsEH, 1);
982  else {
985  "decoding the CIE opcodes into rows failed"),
986  RowsOrErr.takeError()));
987  }
988  OS << "\n";
989 }
990 
992  const MCRegisterInfo *MRI, bool IsEH) const {
993  OS << format("%08" PRIx64, Offset)
994  << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
995  << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
996  << " FDE cie=";
997  if (LinkedCIE)
998  OS << format("%08" PRIx64, LinkedCIE->getOffset());
999  else
1000  OS << "<invalid offset>";
1001  OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
1002  InitialLocation + AddressRange);
1003  OS << " Format: " << FormatString(IsDWARF64) << "\n";
1004  if (LSDAAddress)
1005  OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
1006  CFIs.dump(OS, DumpOpts, MRI, IsEH);
1007  OS << "\n";
1008 
1009  if (Expected<UnwindTable> RowsOrErr = UnwindTable::create(this))
1010  RowsOrErr->dump(OS, MRI, IsEH, 1);
1011  else {
1014  "decoding the FDE opcodes into rows failed"),
1015  RowsOrErr.takeError()));
1016  }
1017  OS << "\n";
1018 }
1019 
1021  bool IsEH, uint64_t EHFrameAddress)
1022  : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
1023 
1025 
1027  uint64_t Offset, int Length) {
1028  errs() << "DUMP: ";
1029  for (int i = 0; i < Length; ++i) {
1030  uint8_t c = Data.getU8(&Offset);
1031  errs().write_hex(c); errs() << " ";
1032  }
1033  errs() << "\n";
1034 }
1035 
1037  uint64_t Offset = 0;
1039 
1040  while (Data.isValidOffset(Offset)) {
1041  uint64_t StartOffset = Offset;
1042 
1043  uint64_t Length;
1044  DwarfFormat Format;
1045  std::tie(Length, Format) = Data.getInitialLength(&Offset);
1046  bool IsDWARF64 = Format == DWARF64;
1047 
1048  // If the Length is 0, then this CIE is a terminator. We add it because some
1049  // dumper tools might need it to print something special for such entries
1050  // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
1051  if (Length == 0) {
1052  auto Cie = std::make_unique<CIE>(
1053  IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
1054  SmallString<8>(), 0, 0, None, None, Arch);
1055  CIEs[StartOffset] = Cie.get();
1056  Entries.push_back(std::move(Cie));
1057  break;
1058  }
1059 
1060  // At this point, Offset points to the next field after Length.
1061  // Length is the structure size excluding itself. Compute an offset one
1062  // past the end of the structure (needed to know how many instructions to
1063  // read).
1064  uint64_t StartStructureOffset = Offset;
1065  uint64_t EndStructureOffset = Offset + Length;
1066 
1067  // The Id field's size depends on the DWARF format
1068  Error Err = Error::success();
1069  uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
1070  /*SectionIndex=*/nullptr, &Err);
1071  if (Err)
1072  return Err;
1073 
1074  if (Id == getCIEId(IsDWARF64, IsEH)) {
1075  uint8_t Version = Data.getU8(&Offset);
1076  const char *Augmentation = Data.getCStr(&Offset);
1077  StringRef AugmentationString(Augmentation ? Augmentation : "");
1078  uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
1079  Data.getU8(&Offset);
1080  Data.setAddressSize(AddressSize);
1081  uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
1082  uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
1083  int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
1084  uint64_t ReturnAddressRegister =
1085  Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
1086 
1087  // Parse the augmentation data for EH CIEs
1088  StringRef AugmentationData("");
1089  uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
1090  uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
1091  Optional<uint64_t> Personality;
1092  Optional<uint32_t> PersonalityEncoding;
1093  if (IsEH) {
1094  Optional<uint64_t> AugmentationLength;
1095  uint64_t StartAugmentationOffset;
1096  uint64_t EndAugmentationOffset;
1097 
1098  // Walk the augmentation string to get all the augmentation data.
1099  for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
1100  switch (AugmentationString[i]) {
1101  default:
1102  return createStringError(
1104  "unknown augmentation character in entry at 0x%" PRIx64,
1105  StartOffset);
1106  case 'L':
1107  LSDAPointerEncoding = Data.getU8(&Offset);
1108  break;
1109  case 'P': {
1110  if (Personality)
1111  return createStringError(
1113  "duplicate personality in entry at 0x%" PRIx64, StartOffset);
1114  PersonalityEncoding = Data.getU8(&Offset);
1115  Personality = Data.getEncodedPointer(
1116  &Offset, *PersonalityEncoding,
1117  EHFrameAddress ? EHFrameAddress + Offset : 0);
1118  break;
1119  }
1120  case 'R':
1121  FDEPointerEncoding = Data.getU8(&Offset);
1122  break;
1123  case 'S':
1124  // Current frame is a signal trampoline.
1125  break;
1126  case 'z':
1127  if (i)
1128  return createStringError(
1130  "'z' must be the first character at 0x%" PRIx64, StartOffset);
1131  // Parse the augmentation length first. We only parse it if
1132  // the string contains a 'z'.
1133  AugmentationLength = Data.getULEB128(&Offset);
1134  StartAugmentationOffset = Offset;
1135  EndAugmentationOffset = Offset + *AugmentationLength;
1136  break;
1137  case 'B':
1138  // B-Key is used for signing functions associated with this
1139  // augmentation string
1140  break;
1141  }
1142  }
1143 
1144  if (AugmentationLength.hasValue()) {
1145  if (Offset != EndAugmentationOffset)
1147  "parsing augmentation data at 0x%" PRIx64
1148  " failed",
1149  StartOffset);
1150  AugmentationData = Data.getData().slice(StartAugmentationOffset,
1151  EndAugmentationOffset);
1152  }
1153  }
1154 
1155  auto Cie = std::make_unique<CIE>(
1156  IsDWARF64, StartOffset, Length, Version, AugmentationString,
1157  AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
1158  DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
1159  FDEPointerEncoding, LSDAPointerEncoding, Personality,
1160  PersonalityEncoding, Arch);
1161  CIEs[StartOffset] = Cie.get();
1162  Entries.emplace_back(std::move(Cie));
1163  } else {
1164  // FDE
1165  uint64_t CIEPointer = Id;
1166  uint64_t InitialLocation = 0;
1167  uint64_t AddressRange = 0;
1168  Optional<uint64_t> LSDAAddress;
1169  CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
1170 
1171  if (IsEH) {
1172  // The address size is encoded in the CIE we reference.
1173  if (!Cie)
1175  "parsing FDE data at 0x%" PRIx64
1176  " failed due to missing CIE",
1177  StartOffset);
1178  if (auto Val =
1179  Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
1180  EHFrameAddress + Offset)) {
1181  InitialLocation = *Val;
1182  }
1183  if (auto Val = Data.getEncodedPointer(
1184  &Offset, Cie->getFDEPointerEncoding(), 0)) {
1185  AddressRange = *Val;
1186  }
1187 
1188  StringRef AugmentationString = Cie->getAugmentationString();
1189  if (!AugmentationString.empty()) {
1190  // Parse the augmentation length and data for this FDE.
1191  uint64_t AugmentationLength = Data.getULEB128(&Offset);
1192 
1193  uint64_t EndAugmentationOffset = Offset + AugmentationLength;
1194 
1195  // Decode the LSDA if the CIE augmentation string said we should.
1196  if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
1197  LSDAAddress = Data.getEncodedPointer(
1198  &Offset, Cie->getLSDAPointerEncoding(),
1199  EHFrameAddress ? Offset + EHFrameAddress : 0);
1200  }
1201 
1202  if (Offset != EndAugmentationOffset)
1204  "parsing augmentation data at 0x%" PRIx64
1205  " failed",
1206  StartOffset);
1207  }
1208  } else {
1209  InitialLocation = Data.getRelocatedAddress(&Offset);
1210  AddressRange = Data.getRelocatedAddress(&Offset);
1211  }
1212 
1213  Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
1214  InitialLocation, AddressRange, Cie,
1215  LSDAAddress, Arch));
1216  }
1217 
1218  if (Error E =
1219  Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
1220  return E;
1221 
1222  if (Offset != EndStructureOffset)
1223  return createStringError(
1225  "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
1226  }
1227 
1228  return Error::success();
1229 }
1230 
1231 FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
1232  auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) {
1233  return E->getOffset() < Offset;
1234  });
1235  if (It != Entries.end() && (*It)->getOffset() == Offset)
1236  return It->get();
1237  return nullptr;
1238 }
1239 
1241  const MCRegisterInfo *MRI,
1242  Optional<uint64_t> Offset) const {
1243  if (Offset) {
1244  if (auto *Entry = getEntryAtOffset(*Offset))
1245  Entry->dump(OS, DumpOpts, MRI, IsEH);
1246  return;
1247  }
1248 
1249  OS << "\n";
1250  for (const auto &Entry : Entries)
1251  Entry->dump(OS, DumpOpts, MRI, IsEH);
1252 }
llvm::dwarf::UnwindLocation::Undefined
@ Undefined
Register is not available and can't be recovered.
Definition: DWARFDebugFrame.h:42
i
i
Definition: README.txt:29
DWARF_CFI_PRIMARY_OPCODE_MASK
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK
Definition: DWARFDebugFrame.cpp:251
llvm::dwarf::RegisterLocations::getRegisterLocation
Optional< UnwindLocation > getRegisterLocation(uint32_t RegNum) const
Return the location for the register in RegNum if there is a location.
Definition: DWARFDebugFrame.h:190
llvm::errc::invalid_argument
@ invalid_argument
llvm::dwarf::CFIProgram::empty
bool empty() const
Definition: DWARFDebugFrame.h:438
DECLARE_OP0
#define DECLARE_OP0(OP)
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::dwarf::FDE
DWARF Frame Description Entry (FDE)
Definition: DWARFDebugFrame.h:626
Optional.h
llvm::dwarf::UnwindRow::hasAddress
bool hasAddress() const
Returns true if the address is valid in this object.
Definition: DWARFDebugFrame.h:264
StringRef.h
llvm::dwarf::CFIProgram::Instruction
An instruction consists of a DWARF CFI opcode and an optional sequence of operands.
Definition: DWARFDebugFrame.h:413
dumpDataAux
static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data, uint64_t Offset, int Length)
Definition: DWARFDebugFrame.cpp:1026
ErrorHandling.h
llvm::Error::success
static ErrorSuccess success()
Create a success value.
Definition: Error.h:329
llvm::dwarf::UnwindLocation::Constant
@ Constant
Value is a constant value contained in "Offset": reg = Offset.
Definition: DWARFDebugFrame.h:63
llvm::dwarf::UnwindLocation::createAtDWARFExpression
static UnwindLocation createAtDWARFExpression(DWARFExpression Expr)
Definition: DWARFDebugFrame.cpp:79
Errc.h
llvm::dwarf::UnwindTable
A class that contains all UnwindRow objects for an FDE or a single unwind row for a CIE.
Definition: DWARFDebugFrame.h:319
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
DenseMap.h
llvm::dwarf::CFIProgram::Instruction::Opcode
uint8_t Opcode
Definition: DWARFDebugFrame.h:416
llvm::dwarf::UnwindLocation::operator==
bool operator==(const UnwindLocation &RHS) const
Definition: DWARFDebugFrame.cpp:132
llvm::dwarf::UnwindLocation::Same
@ Same
Register value is in the register, nothing needs to be done to unwind it: reg = reg.
Definition: DWARFDebugFrame.h:46
llvm::Optional< unsigned >
llvm::dwarf::UnwindLocation::createIsCFAPlusOffset
static UnwindLocation createIsCFAPlusOffset(int32_t Off)
Create a location that is in (Deref == false) or at (Deref == true) the CFA plus an offset.
Definition: DWARFDebugFrame.cpp:55
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:893
llvm::Expected
Tagged union holding either a T or a Error.
Definition: APFloat.h:41
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::dwarf::CFIProgram::addInstruction
void addInstruction(const Instruction &I)
Definition: DWARFDebugFrame.h:458
llvm::DWARFDataExtractor
A DataExtractor (typically for an in-memory copy of an object-file section) plus a relocation map for...
Definition: DWARFDataExtractor.h:21
LLVM_ATTRIBUTE_UNUSED
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:182
llvm::Triple::aarch64_32
@ aarch64_32
Definition: Triple.h:53
Format.h
llvm::dwarf::UnwindLocation::createUndefined
static UnwindLocation createUndefined()
Create a location where the value is undefined and not available.
Definition: DWARFDebugFrame.cpp:47
llvm::dwarf::UnwindTable::create
static Expected< UnwindTable > create(const CIE *Cie)
Create an UnwindTable from a Common Information Entry (CIE).
Definition: DWARFDebugFrame.cpp:233
llvm::Data
@ Data
Definition: SIMachineScheduler.h:55
llvm::Optional::hasValue
constexpr bool hasValue() const
Definition: Optional.h:283
DECLARE_OP3
#define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2)
ENUM_TO_CSTR
#define ENUM_TO_CSTR(e)
llvm::dwarf::FDE::getInitialLocation
uint64_t getInitialLocation() const
Definition: DWARFDebugFrame.h:641
llvm::dwarf::CallFrameString
StringRef CallFrameString(unsigned Encoding, Triple::ArchType Arch)
Definition: Dwarf.cpp:536
llvm::Triple::sparc
@ sparc
Definition: Triple.h:77
llvm::Triple::sparcv9
@ sparcv9
Definition: Triple.h:78
llvm::Triple::sparcel
@ sparcel
Definition: Triple.h:79
llvm::Triple::ArchType
ArchType
Definition: Triple.h:46
getCIEId
constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH)
Definition: DWARFDebugFrame.cpp:934
DWARFDebugFrame.h
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::dwarf::UnwindLocation::DWARFExpr
@ DWARFExpr
Register or CFA value is in or at a value found by evaluating a DWARF expression: reg = eval(dwarf_ex...
Definition: DWARFDebugFrame.h:60
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::dwarf::UnwindRow
A class that represents a single row in the unwind table that is decoded by parsing the DWARF Call Fr...
Definition: DWARFDebugFrame.h:253
First
into llvm powi allowing the code generator to produce balanced multiplication trees First
Definition: README.txt:54
llvm::dwarf::RegisterLocations::hasLocations
bool hasLocations() const
Returns true if we have any register locations in this object.
Definition: DWARFDebugFrame.h:226
llvm::dwarf::UnwindLocation::createIsDWARFExpression
static UnwindLocation createIsDWARFExpression(DWARFExpression Expr)
Create a location whose value is the result of evaluating a DWARF expression.
Definition: DWARFDebugFrame.cpp:75
llvm::Instruction
Definition: Instruction.h:42
llvm::dwarf::FormatString
StringRef FormatString(DwarfFormat Format)
Definition: Dwarf.cpp:790
llvm::dwarf::CFIProgram::codeAlign
uint64_t codeAlign() const
Definition: DWARFDebugFrame.h:439
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::dwarf::CFIProgram::dataAlign
int64_t dataAlign() const
Definition: DWARFDebugFrame.h:440
llvm::dwarf::CIE::getFDEPointerEncoding
uint32_t getFDEPointerEncoding() const
Definition: DWARFDebugFrame.h:600
llvm::dwarf::UnwindLocation
A class that represents a location for the Call Frame Address (CFA) or a register.
Definition: DWARFDebugFrame.h:36
llvm::dwarf::DwarfFormat
DwarfFormat
Constants that define the DWARF format as 32 or 64 bit.
Definition: Dwarf.h:93
c
the resulting code requires compare and branches when and if the revised code is with conditional branches instead of More there is a byte word extend before each where there should be only and the condition codes are not remembered when the same two values are compared twice More LSR enhancements i8 and i32 load store addressing modes are identical int int c
Definition: README.txt:418
llvm::AddressSpace
AddressSpace
Definition: NVPTXBaseInfo.h:21
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:245
llvm::DWARFDebugFrame::parse
Error parse(DWARFDataExtractor Data)
Parse the section from raw data.
Definition: DWARFDebugFrame.cpp:1036
llvm::None
const NoneType None
Definition: None.h:24
llvm::dwarf::InvalidRegisterNumber
constexpr uint32_t InvalidRegisterNumber
Definition: DWARFDebugFrame.h:31
llvm::SmallString< 8 >
llvm::dwarf::UnwindLocation::Unspecified
@ Unspecified
Not specified.
Definition: DWARFDebugFrame.h:40
DWARF_CFI_PRIMARY_OPERAND_MASK
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK
Definition: DWARFDebugFrame.cpp:252
llvm::errc::illegal_byte_sequence
@ illegal_byte_sequence
llvm::dwarf::CFIProgram::Instruction::Ops
Operands Ops
Definition: DWARFDebugFrame.h:417
DECLARE_OP1
#define DECLARE_OP1(OP, OPTYPE0)
llvm::AddressRange
A class that represents an address range.
Definition: AddressRanges.h:21
llvm::dwarf::RegisterLocations
A class that can track all registers with locations in a UnwindRow object.
Definition: DWARFDebugFrame.h:180
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:239
llvm::dwarf::RegisterLocations::dump
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const
Dump all registers + locations that are currently defined in this object.
Definition: DWARFDebugFrame.cpp:153
llvm::AMDGPU::Hwreg::Offset
Offset
Definition: SIDefines.h:409
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
DECLARE_OP2
#define DECLARE_OP2(OP, OPTYPE0, OPTYPE1)
uint64_t
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::DenseMap
Definition: DenseMap.h:716
StringExtras.h
llvm::dwarf::UnwindLocation::createAtCFAPlusOffset
static UnwindLocation createAtCFAPlusOffset(int32_t Off)
Definition: DWARFDebugFrame.cpp:59
MCRegisterInfo.h
llvm::joinErrors
Error joinErrors(Error E1, Error E2)
Concatenate errors.
Definition: Error.h:426
llvm::DWARFExpression
Definition: DWARFExpression.h:24
llvm::Value::print
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4579
llvm::dwarf::UnwindLocation::CFAPlusOffset
@ CFAPlusOffset
Register is in or at the CFA plus an offset: reg = CFA + offset reg = defef(CFA + offset)
Definition: DWARFDebugFrame.h:50
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::dwarf::CFIProgram
Represent a sequence of Call Frame Information instructions that, when read in order,...
Definition: DWARFDebugFrame.h:405
llvm::dwarf::UnwindLocation::createSame
static UnwindLocation createSame()
Create a location where the value is known to be in the register itself.
Definition: DWARFDebugFrame.cpp:49
llvm::dwarf::CFIProgram::callFrameString
StringRef callFrameString(unsigned Opcode) const
Get a DWARF CFI call frame string for the given DW_CFA opcode.
Definition: DWARFDebugFrame.cpp:392
llvm::DataExtractor::Cursor
A class representing a position in a DataExtractor, as well as any error encountered during extractio...
Definition: DataExtractor.h:54
llvm::Expression
Class representing an expression and its matching format.
Definition: FileCheckImpl.h:237
llvm::dwarf::CIE::getLSDAPointerEncoding
uint32_t getLSDAPointerEncoding() const
Definition: DWARFDebugFrame.h:602
llvm::ArrayRef
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: APInt.h:32
llvm::dwarf::FrameEntry::cfis
const CFIProgram & cfis() const
Definition: DWARFDebugFrame.h:545
llvm::dwarf::CIE::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, bool IsEH) const override
Dump the instructions in this CFI fragment.
Definition: DWARFDebugFrame.cpp:942
llvm::Triple::aarch64_be
@ aarch64_be
Definition: Triple.h:52
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm::errc::not_supported
@ not_supported
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::dwarf::UnwindLocation::createIsConstant
static UnwindLocation createIsConstant(int32_t Value)
Definition: DWARFDebugFrame.cpp:51
uint32_t
Compiler.h
llvm::dwarf::UnwindTable::dump
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel=0) const
Dump the UnwindTable to the stream.
Definition: DWARFDebugFrame.cpp:192
llvm::DWARFDebugFrame::DWARFDebugFrame
DWARFDebugFrame(Triple::ArchType Arch, bool IsEH=false, uint64_t EHFrameAddress=0)
Definition: DWARFDebugFrame.cpp:1020
llvm::dwarf::CFIProgram::Instruction::getOperandAsUnsigned
Expected< uint64_t > getOperandAsUnsigned(const CFIProgram &CFIP, uint32_t OperandIdx) const
Definition: DWARFDebugFrame.cpp:416
llvm::format
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
Definition: Format.h:124
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
llvm::dwarf::CIE::getAugmentationString
StringRef getAugmentationString() const
Definition: DWARFDebugFrame.h:592
llvm::dwarf::UnwindLocation::createAtRegisterPlusOffset
static UnwindLocation createAtRegisterPlusOffset(uint32_t Reg, int32_t Off, Optional< uint32_t > AddrSpace=None)
Definition: DWARFDebugFrame.cpp:70
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::StringRef::size
constexpr LLVM_NODISCARD size_t size() const
size - Get the string size.
Definition: StringRef.h:157
llvm::dwarf::DW_EH_PE_absptr
@ DW_EH_PE_absptr
Definition: Dwarf.h:437
llvm::partition_point
auto partition_point(R &&Range, Predicate P)
Binary search for the first iterator in a range where a predicate is false.
Definition: STLExtras.h:1764
DIContext.h
llvm::createStringError
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1239
llvm::dwarf::operator<<
raw_ostream & operator<<(raw_ostream &OS, const UnwindLocation &R)
Definition: DWARFDebugFrame.cpp:126
llvm::dwarf::UnwindLocation::dump
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH) const
Dump a location expression as text and use the register information if some is provided.
Definition: DWARFDebugFrame.cpp:83
llvm::dwarf::DW_CIE_ID
const uint32_t DW_CIE_ID
Special ID values that distinguish a CIE from a FDE in DWARF CFI.
Definition: Dwarf.h:98
llvm::dwarf::FDE::getLinkedCIE
const CIE * getLinkedCIE() const
Definition: DWARFDebugFrame.h:640
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:155
llvm::DWARFDebugFrame::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, Optional< uint64_t > Offset) const
Dump the section data into the given stream.
Definition: DWARFDebugFrame.cpp:1240
llvm::dwarf::CIE
DWARF Common Information Entry (CIE)
Definition: DWARFDebugFrame.h:567
DataExtractor.h
llvm::dwarf::FDE::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, bool IsEH) const override
Dump the instructions in this CFI fragment.
Definition: DWARFDebugFrame.cpp:991
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::dwarf::FrameEntry
An entry in either debug_frame or eh_frame.
Definition: DWARFDebugFrame.h:531
llvm::dwarf::UnwindLocation::createUnspecified
static UnwindLocation createUnspecified()
Create a location whose rule is set to Unspecified.
Definition: DWARFDebugFrame.cpp:45
llvm::dwarf::UnwindRow::dump
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel=0) const
Dump the UnwindRow to the stream.
Definition: DWARFDebugFrame.cpp:173
printRegister
static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH, unsigned RegNum)
Definition: DWARFDebugFrame.cpp:32
llvm::Expected::takeError
Error takeError()
Take ownership of the stored error.
Definition: Error.h:597
llvm::dwarf::CFIProgram::Instruction::getOperandAsSigned
Expected< int64_t > getOperandAsSigned(const CFIProgram &CFIP, uint32_t OperandIdx) const
Definition: DWARFDebugFrame.cpp:461
llvm::DataExtractor
Definition: DataExtractor.h:41
Version
uint64_t Version
Definition: RawMemProfReader.cpp:40
llvm::raw_ostream::indent
raw_ostream & indent(unsigned NumSpaces)
indent - Insert 'NumSpaces' spaces.
Definition: raw_ostream.cpp:496
llvm::dwarf::UnwindLocation::RegPlusOffset
@ RegPlusOffset
Register or CFA is in or at a register plus offset, optionally in an address space: reg = reg + offse...
Definition: DWARFDebugFrame.h:55
llvm::dwarf::DW_EH_PE_omit
@ DW_EH_PE_omit
Definition: Dwarf.h:438
llvm::Triple::getArchTypeName
static StringRef getArchTypeName(ArchType Kind)
Get the canonical name for the Kind architecture.
Definition: Triple.cpp:23
RegName
#define RegName(no)
llvm::dwarf::DWARF64
@ DWARF64
Definition: Dwarf.h:93
llvm::dwarf::CFIProgram::dump
void dump(raw_ostream &OS, DIDumpOptions DumpOpts, const MCRegisterInfo *MRI, bool IsEH, unsigned IndentLevel=1) const
Definition: DWARFDebugFrame.cpp:917
llvm::dwarf::DW64_CIE_ID
const uint64_t DW64_CIE_ID
Definition: Dwarf.h:99
raw_ostream.h
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:235
llvm::DWARFDebugFrame::~DWARFDebugFrame
~DWARFDebugFrame()
llvm::dwarf::CFIProgram::MaxOperands
static constexpr size_t MaxOperands
Definition: DWARFDebugFrame.h:407
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::dwarf::FDE::getAddressRange
uint64_t getAddressRange() const
Definition: DWARFDebugFrame.h:642
llvm::dwarf::UnwindLocation::createIsRegisterPlusOffset
static UnwindLocation createIsRegisterPlusOffset(uint32_t Reg, int32_t Off, Optional< uint32_t > AddrSpace=None)
Create a location where the saved value is in (Deref == false) or at (Deref == true) a regiser plus a...
Definition: DWARFDebugFrame.cpp:64
llvm::Triple::aarch64
@ aarch64
Definition: Triple.h:51
llvm::dwarf::CFIProgram::parse
Error parse(DWARFDataExtractor Data, uint64_t *Offset, uint64_t EndOffset)
Parse and store a sequence of CFI instructions from Data, starting at *Offset and ending at EndOffset...
Definition: DWARFDebugFrame.cpp:254
llvm::dwarf::FrameEntry::getOffset
uint64_t getOffset() const
Definition: DWARFDebugFrame.h:543
DWARFDataExtractor.h
llvm::DIDumpOptions
Container for dump options that control which debug information will be dumped.
Definition: DIContext.h:186
llvm::raw_ostream::write_hex
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
Definition: raw_ostream.cpp:139
llvm::DIDumpOptions::RecoverableErrorHandler
std::function< void(Error)> RecoverableErrorHandler
Definition: DIContext.h:218