1 //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDebugFrame.h"
10 #include "llvm/ADT/DenseMap.h"
11 #include "llvm/ADT/Optional.h"
12 #include "llvm/ADT/StringExtras.h"
13 #include "llvm/ADT/StringRef.h"
14 #include "llvm/BinaryFormat/Dwarf.h"
15 #include "llvm/MC/MCRegisterInfo.h"
16 #include "llvm/Support/Casting.h"
17 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/DataExtractor.h"
19 #include "llvm/Support/Errc.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include "llvm/Support/Format.h"
22 #include "llvm/Support/raw_ostream.h"
29 using namespace dwarf
;
31 static void printRegister(raw_ostream
&OS
, const MCRegisterInfo
*MRI
, bool IsEH
,
34 if (Optional
<unsigned> LLVMRegNum
= MRI
->getLLVMRegNum(RegNum
, IsEH
)) {
35 if (const char *RegName
= MRI
->getName(*LLVMRegNum
)) {
41 OS
<< "reg" << RegNum
;
44 UnwindLocation
UnwindLocation::createUnspecified() { return {Unspecified
}; }
46 UnwindLocation
UnwindLocation::createUndefined() { return {Undefined
}; }
48 UnwindLocation
UnwindLocation::createSame() { return {Same
}; }
50 UnwindLocation
UnwindLocation::createIsConstant(int32_t Value
) {
51 return {Constant
, InvalidRegisterNumber
, Value
, None
, false};
54 UnwindLocation
UnwindLocation::createIsCFAPlusOffset(int32_t Offset
) {
55 return {CFAPlusOffset
, InvalidRegisterNumber
, Offset
, None
, false};
58 UnwindLocation
UnwindLocation::createAtCFAPlusOffset(int32_t Offset
) {
59 return {CFAPlusOffset
, InvalidRegisterNumber
, Offset
, None
, true};
63 UnwindLocation::createIsRegisterPlusOffset(uint32_t RegNum
, int32_t Offset
,
64 Optional
<uint32_t> AddrSpace
) {
65 return {RegPlusOffset
, RegNum
, Offset
, AddrSpace
, false};
69 UnwindLocation::createAtRegisterPlusOffset(uint32_t RegNum
, int32_t Offset
,
70 Optional
<uint32_t> AddrSpace
) {
71 return {RegPlusOffset
, RegNum
, Offset
, AddrSpace
, true};
74 UnwindLocation
UnwindLocation::createIsDWARFExpression(DWARFExpression Expr
) {
78 UnwindLocation
UnwindLocation::createAtDWARFExpression(DWARFExpression Expr
) {
82 void UnwindLocation::dump(raw_ostream
&OS
, const MCRegisterInfo
*MRI
,
105 printRegister(OS
, MRI
, IsEH
, RegNum
);
106 if (Offset
== 0 && !AddrSpace
)
112 OS
<< " in addrspace" << *AddrSpace
;
115 Expr
->print(OS
, DIDumpOptions(), MRI
, nullptr, IsEH
);
125 raw_ostream
&llvm::dwarf::operator<<(raw_ostream
&OS
,
126 const UnwindLocation
&UL
) {
127 UL
.dump(OS
, nullptr, false);
131 bool UnwindLocation::operator==(const UnwindLocation
&RHS
) const {
132 if (Kind
!= RHS
.Kind
)
140 return Offset
== RHS
.Offset
&& Dereference
== RHS
.Dereference
;
142 return RegNum
== RHS
.RegNum
&& Offset
== RHS
.Offset
&&
143 Dereference
== RHS
.Dereference
;
145 return *Expr
== *RHS
.Expr
&& Dereference
== RHS
.Dereference
;
147 return Offset
== RHS
.Offset
;
152 void RegisterLocations::dump(raw_ostream
&OS
, const MCRegisterInfo
*MRI
,
155 for (const auto &RegLocPair
: Locations
) {
160 printRegister(OS
, MRI
, IsEH
, RegLocPair
.first
);
162 RegLocPair
.second
.dump(OS
, MRI
, IsEH
);
166 raw_ostream
&llvm::dwarf::operator<<(raw_ostream
&OS
,
167 const RegisterLocations
&RL
) {
168 RL
.dump(OS
, nullptr, false);
172 void UnwindRow::dump(raw_ostream
&OS
, const MCRegisterInfo
*MRI
, bool IsEH
,
173 unsigned IndentLevel
) const {
174 OS
.indent(2 * IndentLevel
);
176 OS
<< format("0x%" PRIx64
": ", *Address
);
178 CFAValue
.dump(OS
, MRI
, IsEH
);
179 if (RegLocs
.hasLocations()) {
181 RegLocs
.dump(OS
, MRI
, IsEH
);
186 raw_ostream
&llvm::dwarf::operator<<(raw_ostream
&OS
, const UnwindRow
&Row
) {
187 Row
.dump(OS
, nullptr, false, 0);
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
);
197 raw_ostream
&llvm::dwarf::operator<<(raw_ostream
&OS
, const UnwindTable
&Rows
) {
198 Rows
.dump(OS
, nullptr, false, 0);
202 Expected
<UnwindTable
> UnwindTable::create(const FDE
*Fde
) {
203 const CIE
*Cie
= Fde
->getLinkedCIE();
205 return createStringError(errc::invalid_argument
,
206 "unable to get CIE for FDE at offset 0x%" PRIx64
,
209 // Rows will be empty if there are no CFI instructions.
210 if (Cie
->cfis().empty() && Fde
->cfis().empty())
211 return UnwindTable();
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
);
232 Expected
<UnwindTable
> UnwindTable::create(const CIE
*Cie
) {
233 // Rows will be empty if there are no CFI instructions.
234 if (Cie
->cfis().empty())
235 return UnwindTable();
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
);
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;
253 Error
CFIProgram::parse(DWARFDataExtractor Data
, uint64_t *Offset
,
254 uint64_t EndOffset
) {
255 DataExtractor::Cursor
C(*Offset
);
256 while (C
&& C
.tell() < EndOffset
) {
257 uint8_t Opcode
= Data
.getRelocatedValue(C
, 1);
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.
265 uint64_t Op1
= Opcode
& DWARF_CFI_PRIMARY_OPERAND_MASK
;
267 case DW_CFA_advance_loc
:
269 addInstruction(Primary
, Op1
);
272 addInstruction(Primary
, Op1
, Data
.getULEB128(C
));
275 llvm_unreachable("invalid primary CFI opcode");
280 // Extended opcode - its value is Opcode itself.
283 return createStringError(errc::illegal_byte_sequence
,
284 "invalid extended CFI opcode 0x%" PRIx8
, Opcode
);
286 case DW_CFA_remember_state
:
287 case DW_CFA_restore_state
:
288 case DW_CFA_GNU_window_save
:
290 addInstruction(Opcode
);
294 addInstruction(Opcode
, Data
.getRelocatedAddress(C
));
296 case DW_CFA_advance_loc1
:
297 // Operands: 1-byte delta
298 addInstruction(Opcode
, Data
.getRelocatedValue(C
, 1));
300 case DW_CFA_advance_loc2
:
301 // Operands: 2-byte delta
302 addInstruction(Opcode
, Data
.getRelocatedValue(C
, 2));
304 case DW_CFA_advance_loc4
:
305 // Operands: 4-byte delta
306 addInstruction(Opcode
, Data
.getRelocatedValue(C
, 4));
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
:
315 addInstruction(Opcode
, Data
.getULEB128(C
));
317 case DW_CFA_def_cfa_offset_sf
:
319 addInstruction(Opcode
, Data
.getSLEB128(C
));
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
326 : Data
.getSLEB128(C
);
327 auto AddressSpace
= Data
.getULEB128(C
);
328 addInstruction(Opcode
, RegNum
, CfaOffset
, AddressSpace
);
331 case DW_CFA_offset_extended
:
332 case DW_CFA_register
:
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
);
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
);
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
);
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());
368 case DW_CFA_expression
:
369 case DW_CFA_val_expression
: {
370 uint64_t RegNum
= Data
.getULEB128(C
);
371 addInstruction(Opcode
, RegNum
, 0);
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());
388 return C
.takeError();
391 StringRef
CFIProgram::callFrameString(unsigned Opcode
) const {
392 return dwarf::CallFrameString(Opcode
, Arch
);
395 const char *CFIProgram::operandTypeString(CFIProgram::OperandType OT
) {
396 #define ENUM_TO_CSTR(e) \
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
);
411 return "<unknown CFIProgram::OperandType>";
414 llvm::Expected
<uint64_t>
415 CFIProgram::Instruction::getOperandAsUnsigned(const CFIProgram
&CFIP
,
416 uint32_t OperandIdx
) const {
417 if (OperandIdx
>= MaxOperands
)
418 return createStringError(errc::invalid_argument
,
419 "operand index %" PRIu32
" is not valid",
421 OperandType Type
= CFIP
.getOperandTypes()[Opcode
][OperandIdx
];
422 uint64_t Operand
= Ops
[OperandIdx
];
427 return createStringError(errc::invalid_argument
,
428 "op[%" PRIu32
"] has type %s which has no value",
429 OperandIdx
, CFIProgram::operandTypeString(Type
));
432 case OT_SignedFactDataOffset
:
433 case OT_UnsignedFactDataOffset
:
434 return createStringError(
435 errc::invalid_argument
,
436 "op[%" PRIu32
"] has OperandType OT_Offset which produces a signed "
437 "result, call getOperandAsSigned instead",
442 case OT_AddressSpace
:
445 case OT_FactoredCodeOffset
: {
446 const uint64_t CodeAlignmentFactor
= CFIP
.codeAlign();
447 if (CodeAlignmentFactor
== 0)
448 return createStringError(
449 errc::invalid_argument
,
450 "op[%" PRIu32
"] has type OT_FactoredCodeOffset but code alignment "
453 return Operand
* CodeAlignmentFactor
;
456 llvm_unreachable("invalid operand type");
459 llvm::Expected
<int64_t>
460 CFIProgram::Instruction::getOperandAsSigned(const CFIProgram
&CFIP
,
461 uint32_t OperandIdx
) const {
462 if (OperandIdx
>= MaxOperands
)
463 return createStringError(errc::invalid_argument
,
464 "operand index %" PRIu32
" is not valid",
466 OperandType Type
= CFIP
.getOperandTypes()[Opcode
][OperandIdx
];
467 uint64_t Operand
= Ops
[OperandIdx
];
472 return createStringError(errc::invalid_argument
,
473 "op[%" PRIu32
"] has type %s which has no value",
474 OperandIdx
, CFIProgram::operandTypeString(Type
));
478 case OT_AddressSpace
:
479 return createStringError(
480 errc::invalid_argument
,
481 "op[%" PRIu32
"] has OperandType %s which produces an unsigned result, "
482 "call getOperandAsUnsigned instead",
483 OperandIdx
, CFIProgram::operandTypeString(Type
));
486 return (int64_t)Operand
;
488 case OT_FactoredCodeOffset
:
489 case OT_SignedFactDataOffset
: {
490 const int64_t DataAlignmentFactor
= CFIP
.dataAlign();
491 if (DataAlignmentFactor
== 0)
492 return createStringError(errc::invalid_argument
,
493 "op[%" PRIu32
"] has type %s but data "
495 OperandIdx
, CFIProgram::operandTypeString(Type
));
496 return int64_t(Operand
) * DataAlignmentFactor
;
499 case OT_UnsignedFactDataOffset
: {
500 const int64_t DataAlignmentFactor
= CFIP
.dataAlign();
501 if (DataAlignmentFactor
== 0)
502 return createStringError(errc::invalid_argument
,
504 "] has type OT_UnsignedFactDataOffset but data "
507 return Operand
* DataAlignmentFactor
;
510 llvm_unreachable("invalid operand type");
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);
528 return NewAddress
.takeError();
529 if (*NewAddress
<= Row
.getAddress())
530 return createStringError(
531 errc::invalid_argument
,
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
,
537 Row
.setAddress(*NewAddress
);
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.
552 llvm::Expected
<uint64_t> Offset
= Inst
.getOperandAsUnsigned(CFIP
, 0);
554 return Offset
.takeError();
555 Row
.slideAddress(*Offset
);
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);
571 return RegNum
.takeError();
572 if (Optional
<UnwindLocation
> O
=
573 InitialLocs
->getRegisterLocation(*RegNum
))
574 Row
.getRegisterLocations().setRegisterLocation(*RegNum
, *O
);
576 Row
.getRegisterLocations().removeRegisterLocation(*RegNum
);
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);
585 return RegNum
.takeError();
586 llvm::Expected
<int64_t> Offset
= Inst
.getOperandAsSigned(CFIP
, 1);
588 return Offset
.takeError();
589 Row
.getRegisterLocations().setRegisterLocation(
590 *RegNum
, UnwindLocation::createAtCFAPlusOffset(*Offset
));
594 case dwarf::DW_CFA_nop
:
597 case dwarf::DW_CFA_remember_state
:
598 RegisterStates
.push_back(Row
.getRegisterLocations());
601 case dwarf::DW_CFA_restore_state
:
602 if (RegisterStates
.empty())
603 return createStringError(errc::invalid_argument
,
604 "DW_CFA_restore_state without a matching "
605 "previous DW_CFA_remember_state");
606 Row
.getRegisterLocations() = RegisterStates
.back();
607 RegisterStates
.pop_back();
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
);
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);
629 return createStringError(
630 errc::invalid_argument
,
631 "%s encountered when existing rule for this register is not "
633 CFIP
.callFrameString(Inst
.Opcode
).str().c_str());
636 Row
.getRegisterLocations().setRegisterLocation(
637 AArch64DWARFPAuthRaState
, UnwindLocation::createIsConstant(1));
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));
652 return createStringError(
654 "DW_CFA opcode %#x is not supported for architecture %s",
655 Inst
.Opcode
, Triple::getArchTypeName(CFIP
.triple()).str().c_str());
662 case dwarf::DW_CFA_undefined
: {
663 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
665 return RegNum
.takeError();
666 Row
.getRegisterLocations().setRegisterLocation(
667 *RegNum
, UnwindLocation::createUndefined());
671 case dwarf::DW_CFA_same_value
: {
672 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
674 return RegNum
.takeError();
675 Row
.getRegisterLocations().setRegisterLocation(
676 *RegNum
, UnwindLocation::createSame());
680 case dwarf::DW_CFA_GNU_args_size
:
683 case dwarf::DW_CFA_register
: {
684 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
686 return RegNum
.takeError();
687 llvm::Expected
<uint64_t> NewRegNum
= Inst
.getOperandAsUnsigned(CFIP
, 1);
689 return NewRegNum
.takeError();
690 Row
.getRegisterLocations().setRegisterLocation(
691 *RegNum
, UnwindLocation::createIsRegisterPlusOffset(*NewRegNum
, 0));
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);
699 return RegNum
.takeError();
700 llvm::Expected
<int64_t> Offset
= Inst
.getOperandAsSigned(CFIP
, 1);
702 return Offset
.takeError();
703 Row
.getRegisterLocations().setRegisterLocation(
704 *RegNum
, UnwindLocation::createIsCFAPlusOffset(*Offset
));
708 case dwarf::DW_CFA_expression
: {
709 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
711 return RegNum
.takeError();
712 Row
.getRegisterLocations().setRegisterLocation(
713 *RegNum
, UnwindLocation::createAtDWARFExpression(*Inst
.Expression
));
717 case dwarf::DW_CFA_val_expression
: {
718 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
720 return RegNum
.takeError();
721 Row
.getRegisterLocations().setRegisterLocation(
722 *RegNum
, UnwindLocation::createIsDWARFExpression(*Inst
.Expression
));
726 case dwarf::DW_CFA_def_cfa_register
: {
727 llvm::Expected
<uint64_t> RegNum
= Inst
.getOperandAsUnsigned(CFIP
, 0);
729 return RegNum
.takeError();
730 if (Row
.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset
)
732 UnwindLocation::createIsRegisterPlusOffset(*RegNum
, 0);
734 Row
.getCFAValue().setRegister(*RegNum
);
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);
742 return Offset
.takeError();
743 if (Row
.getCFAValue().getLocation() != UnwindLocation::RegPlusOffset
) {
744 return createStringError(
745 errc::invalid_argument
,
746 "%s found when CFA rule was not RegPlusOffset",
747 CFIP
.callFrameString(Inst
.Opcode
).str().c_str());
749 Row
.getCFAValue().setOffset(*Offset
);
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);
757 return RegNum
.takeError();
758 llvm::Expected
<int64_t> Offset
= Inst
.getOperandAsSigned(CFIP
, 1);
760 return Offset
.takeError();
762 UnwindLocation::createIsRegisterPlusOffset(*RegNum
, *Offset
);
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);
770 return RegNum
.takeError();
771 llvm::Expected
<int64_t> Offset
= Inst
.getOperandAsSigned(CFIP
, 1);
773 return Offset
.takeError();
774 llvm::Expected
<uint32_t> CFAAddrSpace
=
775 Inst
.getOperandAsUnsigned(CFIP
, 2);
777 return CFAAddrSpace
.takeError();
778 Row
.getCFAValue() = UnwindLocation::createIsRegisterPlusOffset(
779 *RegNum
, *Offset
, *CFAAddrSpace
);
783 case dwarf::DW_CFA_def_cfa_expression
:
785 UnwindLocation::createIsDWARFExpression(*Inst
.Expression
);
789 return Error::success();
792 ArrayRef
<CFIProgram::OperandType
[CFIProgram::MaxOperands
]>
793 CFIProgram::getOperandTypes() {
794 static OperandType OpTypes
[DW_CFA_restore
+ 1][MaxOperands
];
795 static bool Initialized
= false;
797 return ArrayRef
<OperandType
[MaxOperands
]>(&OpTypes
[0], DW_CFA_restore
+ 1);
801 #define DECLARE_OP3(OP, OPTYPE0, OPTYPE1, OPTYPE2) \
803 OpTypes[OP][0] = OPTYPE0; \
804 OpTypes[OP][1] = OPTYPE1; \
805 OpTypes[OP][2] = OPTYPE2; \
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)
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
,
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
);
850 return ArrayRef
<OperandType
[MaxOperands
]>(&OpTypes
[0], DW_CFA_restore
+ 1);
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
];
864 OS
<< " Unsupported " << (OperandIdx
? "second" : "first") << " operand to";
865 auto OpcodeName
= callFrameString(Opcode
);
866 if (!OpcodeName
.empty())
867 OS
<< " " << OpcodeName
;
869 OS
<< format(" Opcode %x", Opcode
);
875 OS
<< format(" %" PRIx64
, Operand
);
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
));
883 case OT_FactoredCodeOffset
: // Always Unsigned
884 if (CodeAlignmentFactor
)
885 OS
<< format(" %" PRId64
, Operand
* CodeAlignmentFactor
);
887 OS
<< format(" %" PRId64
"*code_alignment_factor" , Operand
);
889 case OT_SignedFactDataOffset
:
890 if (DataAlignmentFactor
)
891 OS
<< format(" %" PRId64
, int64_t(Operand
) * DataAlignmentFactor
);
893 OS
<< format(" %" PRId64
"*data_alignment_factor" , int64_t(Operand
));
895 case OT_UnsignedFactDataOffset
:
896 if (DataAlignmentFactor
)
897 OS
<< format(" %" PRId64
, Operand
* DataAlignmentFactor
);
899 OS
<< format(" %" PRId64
"*data_alignment_factor" , Operand
);
903 printRegister(OS
, MRI
, IsEH
, Operand
);
905 case OT_AddressSpace
:
906 OS
<< format(" in addrspace%" PRId64
, Operand
);
909 assert(Instr
.Expression
&& "missing DWARFExpression object");
911 Instr
.Expression
->print(OS
, DumpOpts
, MRI
, nullptr, IsEH
);
916 void CFIProgram::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
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
]);
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
) {
941 void CIE::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
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";
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
))
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";
960 OS
<< format(" Address size: %u\n", (uint32_t)AddressSize
);
961 OS
<< format(" Segment desc size: %u\n",
962 (uint32_t)SegmentDescriptorSize
);
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
);
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);
976 CFIs
.dump(OS
, DumpOpts
, MRI
, IsEH
);
979 if (Expected
<UnwindTable
> RowsOrErr
= UnwindTable::create(this))
980 RowsOrErr
->dump(OS
, MRI
, IsEH
, 1);
982 DumpOpts
.RecoverableErrorHandler(joinErrors(
983 createStringError(errc::invalid_argument
,
984 "decoding the CIE opcodes into rows failed"),
985 RowsOrErr
.takeError()));
990 void FDE::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
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
)
997 OS
<< format("%08" PRIx64
, LinkedCIE
->getOffset());
999 OS
<< "<invalid offset>";
1000 OS
<< format(" pc=%08" PRIx64
"...%08" PRIx64
"\n", InitialLocation
,
1001 InitialLocation
+ AddressRange
);
1002 OS
<< " Format: " << FormatString(IsDWARF64
) << "\n";
1004 OS
<< format(" LSDA Address: %016" PRIx64
"\n", *LSDAAddress
);
1005 CFIs
.dump(OS
, DumpOpts
, MRI
, IsEH
);
1008 if (Expected
<UnwindTable
> RowsOrErr
= UnwindTable::create(this))
1009 RowsOrErr
->dump(OS
, MRI
, IsEH
, 1);
1011 DumpOpts
.RecoverableErrorHandler(joinErrors(
1012 createStringError(errc::invalid_argument
,
1013 "decoding the FDE opcodes into rows failed"),
1014 RowsOrErr
.takeError()));
1019 DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch
,
1020 bool IsEH
, uint64_t EHFrameAddress
)
1021 : Arch(Arch
), IsEH(IsEH
), EHFrameAddress(EHFrameAddress
) {}
1023 DWARFDebugFrame::~DWARFDebugFrame() = default;
1025 static void LLVM_ATTRIBUTE_UNUSED
dumpDataAux(DataExtractor Data
,
1026 uint64_t Offset
, int Length
) {
1028 for (int i
= 0; i
< Length
; ++i
) {
1029 uint8_t c
= Data
.getU8(&Offset
);
1030 errs().write_hex(c
); errs() << " ";
1035 Error
DWARFDebugFrame::parse(DWARFDataExtractor Data
) {
1036 uint64_t Offset
= 0;
1037 DenseMap
<uint64_t, CIE
*> CIEs
;
1039 while (Data
.isValidOffset(Offset
)) {
1040 uint64_t StartOffset
= Offset
;
1044 std::tie(Length
, Format
) = Data
.getInitialLength(&Offset
);
1045 bool IsDWARF64
= Format
== DWARF64
;
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").
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
));
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
1063 uint64_t StartStructureOffset
= Offset
;
1064 uint64_t EndStructureOffset
= Offset
+ Length
;
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
);
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
);
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
;
1093 Optional
<uint64_t> AugmentationLength
;
1094 uint64_t StartAugmentationOffset
;
1095 uint64_t EndAugmentationOffset
;
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
]) {
1101 return createStringError(
1102 errc::invalid_argument
,
1103 "unknown augmentation character in entry at 0x%" PRIx64
,
1106 LSDAPointerEncoding
= Data
.getU8(&Offset
);
1110 return createStringError(
1111 errc::invalid_argument
,
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);
1120 FDEPointerEncoding
= Data
.getU8(&Offset
);
1123 // Current frame is a signal trampoline.
1127 return createStringError(
1128 errc::invalid_argument
,
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
;
1137 // B-Key is used for signing functions associated with this
1138 // augmentation string
1143 if (AugmentationLength
.hasValue()) {
1144 if (Offset
!= EndAugmentationOffset
)
1145 return createStringError(errc::invalid_argument
,
1146 "parsing augmentation data at 0x%" PRIx64
1149 AugmentationData
= Data
.getData().slice(StartAugmentationOffset
,
1150 EndAugmentationOffset
);
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
));
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
];
1171 // The address size is encoded in the CIE we reference.
1173 return createStringError(errc::invalid_argument
,
1174 "parsing FDE data at 0x%" PRIx64
1175 " failed due to missing CIE",
1178 Data
.getEncodedPointer(&Offset
, Cie
->getFDEPointerEncoding(),
1179 EHFrameAddress
+ Offset
)) {
1180 InitialLocation
= *Val
;
1182 if (auto Val
= Data
.getEncodedPointer(
1183 &Offset
, Cie
->getFDEPointerEncoding(), 0)) {
1184 AddressRange
= *Val
;
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
);
1192 uint64_t EndAugmentationOffset
= Offset
+ AugmentationLength
;
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);
1201 if (Offset
!= EndAugmentationOffset
)
1202 return createStringError(errc::invalid_argument
,
1203 "parsing augmentation data at 0x%" PRIx64
1208 InitialLocation
= Data
.getRelocatedAddress(&Offset
);
1209 AddressRange
= Data
.getRelocatedAddress(&Offset
);
1212 Entries
.emplace_back(new FDE(IsDWARF64
, StartOffset
, Length
, CIEPointer
,
1213 InitialLocation
, AddressRange
, Cie
,
1214 LSDAAddress
, Arch
));
1218 Entries
.back()->cfis().parse(Data
, &Offset
, EndStructureOffset
))
1221 if (Offset
!= EndStructureOffset
)
1222 return createStringError(
1223 errc::invalid_argument
,
1224 "parsing entry instructions at 0x%" PRIx64
" failed", StartOffset
);
1227 return Error::success();
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
;
1234 if (It
!= Entries
.end() && (*It
)->getOffset() == Offset
)
1239 void DWARFDebugFrame::dump(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
1240 const MCRegisterInfo
*MRI
,
1241 Optional
<uint64_t> Offset
) const {
1243 if (auto *Entry
= getEntryAtOffset(*Offset
))
1244 Entry
->dump(OS
, DumpOpts
, MRI
, IsEH
);
1249 for (const auto &Entry
: Entries
)
1250 Entry
->dump(OS
, DumpOpts
, MRI
, IsEH
);