match translate_into_unwind_rule(cfa_rule, &bp_rule, &ra_rule) {
Ok(unwind_rule) => return Ok(UnwindResult::ExecRule(unwind_rule)),
Err(_err) => { // Could not translate into a cacheable unwind rule. Fall back to the generic path. // eprintln!("Unwind rule translation failed: {:?}", err);
}
}
let cfa = eval_cfa_rule::<R, _, ES>(section, cfa_rule, encoding, regs)
.ok_or(DwarfUnwinderError::CouldNotRecoverCfa)?;
let ip = regs.ip(); let bp = regs.bp(); let sp = regs.sp();
if cfa == sp && return_address == ip { return Err(DwarfUnwinderError::DidNotAdvance);
} if !is_first_frame && cfa < regs.sp() { return Err(DwarfUnwinderError::StackPointerMovedBackwards);
}
fn translate_into_unwind_rule<RO: ReaderOffset>(
cfa_rule: &CfaRule<RO>,
bp_rule: &RegisterRule<RO>,
ra_rule: &RegisterRule<RO>,
) -> Result<UnwindRuleX86_64, ConversionError> { match ra_rule {
RegisterRule::Undefined => { // No return address. This means that we've reached the end of the stack. return Ok(UnwindRuleX86_64::EndOfStack);
}
RegisterRule::Offset(offset) if *offset == -8 => { // This is normal case. Return address is [CFA-8].
}
RegisterRule::Offset(_) => { // Unsupported, will have to use the slow path. return Err(ConversionError::ReturnAddressRuleWithUnexpectedOffset);
}
_ => { // Unsupported, will have to use the slow path. return Err(ConversionError::ReturnAddressRuleWasWeird);
}
}
match cfa_rule {
CfaRule::RegisterAndOffset { register, offset } => match *register {
X86_64::RSP => { let sp_offset_by_8 =
u16::try_from(offset / 8).map_err(|_| ConversionError::SpOffsetDoesNotFit)?; let fp_cfa_offset = register_rule_to_cfa_offset(bp_rule)?; match fp_cfa_offset {
None => Ok(UnwindRuleX86_64::OffsetSp { sp_offset_by_8 }),
Some(bp_cfa_offset) => { let bp_storage_offset_from_sp_by_8 =
i16::try_from((offset + bp_cfa_offset) / 8)
.map_err(|_| ConversionError::FpStorageOffsetDoesNotFit)?;
Ok(UnwindRuleX86_64::OffsetSpAndRestoreBp {
sp_offset_by_8,
bp_storage_offset_from_sp_by_8,
})
}
}
}
X86_64::RBP => { let bp_cfa_offset = register_rule_to_cfa_offset(bp_rule)?
.ok_or(ConversionError::FramePointerRuleDoesNotRestoreBp)?; if *offset == 16 && bp_cfa_offset == -16 {
Ok(UnwindRuleX86_64::UseFramePointer)
} else { // TODO: Maybe handle this case. This case has been observed in _ffi_call_unix64, // which has the following unwind table: // // 00000060 00000024 0000001c FDE cie=00000048 pc=000de548...000de6a6 // 0xde548: CFA=reg7+8: reg16=[CFA-8] // 0xde562: CFA=reg6+32: reg6=[CFA-16], reg16=[CFA-8] // 0xde5ad: CFA=reg7+8: reg16=[CFA-8] // 0xde668: CFA=reg7+8: reg6=[CFA-16], reg16=[CFA-8]
Err(ConversionError::FramePointerRuleHasStrangeBpOffset)
}
}
_ => Err(ConversionError::CfaIsOffsetFromUnknownRegister),
},
CfaRule::Expression(_) => Err(ConversionError::CfaIsExpression),
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-06-22)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.