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