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