impl core::fmt::Display for DwarfUnwinderError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { matchself { Self::FdeFromOffsetFailed(err) => {
write!(f, "Could not get the FDE for the supplied offset: {err}")
} Self::UnwindInfoForAddressFailed(err) => write!(
f, "Could not find DWARF unwind info for the requested address: {err}"
), Self::StackPointerMovedBackwards => write!(f, "Stack pointer moved backwards"), Self::DidNotAdvance => write!(f, "Did not advance"), Self::CouldNotRecoverCfa => write!(f, "Could not recover the CFA"), Self::CouldNotRecoverReturnAddress => write!(f, "Could not recover the return address"), Self::CouldNotRecoverFramePointer => write!(f, "Could not recover the frame pointer"),
}
}
}
impl core::fmt::Display for DwarfCfiIndexError { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { matchself { Self::Gimli(e) => write!(f, "EhFrame processing failed: {e}"), Self::CouldNotSubtractBaseAddress => {
write!(f, "Could not subtract base address to create relative pc")
} Self::RelativeAddressTooBig => write!(f, "Relative address did not fit into u32"), Self::FdeOffsetTooBig => write!(f, "FDE offset did not fit into u32"),
}
}
}
/// A binary search table for eh_frame FDEs. We generate this whenever a module /// without eh_frame_hdr is added. pubstruct DwarfCfiIndex { /// Contains the initial address for every FDE, relative to the base address. /// This vector is sorted so that it can be used for binary search. /// It has the same length as `fde_offsets`.
sorted_fde_pc_starts: Vec<u32>, /// Contains the FDE offset for every FDE. The FDE at offset `fde_offsets[i]` /// has a PC range which starts at `sorted_fde_pc_starts[i]`.
fde_offsets: Vec<u32>,
}
fn eval_expr<R: Reader, UR: DwarfUnwindRegs, S: EvaluationStorage<R>>(
expr: Expression<R>,
encoding: Encoding,
regs: &UR,
) -> Option<u64> { letmut eval = Evaluation::<R, S>::new_in(expr.0, encoding); letmut result = eval.evaluate().ok()?; loop { match result {
EvaluationResult::Complete => break,
EvaluationResult::RequiresRegister { register, .. } => { let value = regs.get(register)?;
result = eval.resume_with_register(Value::Generic(value as _)).ok()?;
}
_ => return None,
}
} let x = &eval.as_result().last()?.location; iflet Location::Address { address } = x {
Some(*address)
} else {
None
}
}
pubfn eval_register_rule<R, F, UR, S>(
section: &impl UnwindSection<R>,
rule: RegisterRule<R::Offset>,
cfa: u64,
encoding: Encoding,
val: u64,
regs: &UR,
read_stack: &mut F,
) -> Option<u64> where
R: Reader,
F: FnMut(u64) -> Result<u64, ()>,
UR: DwarfUnwindRegs,
S: EvaluationStorage<R>,
{ match rule {
RegisterRule::Undefined => None,
RegisterRule::SameValue => Some(val),
RegisterRule::Offset(offset) => { let cfa_plus_offset =
u64::try_from(i64::try_from(cfa).ok()?.checked_add(offset)?).ok()?;
read_stack(cfa_plus_offset).ok()
}
RegisterRule::ValOffset(offset) => {
u64::try_from(i64::try_from(cfa).ok()?.checked_add(offset)?).ok()
}
RegisterRule::Register(register) => regs.get(register),
RegisterRule::Expression(expr) => { let expr = expr.get(section).ok()?; let val = eval_expr::<R, UR, S>(expr, encoding, regs)?;
read_stack(val).ok()
}
RegisterRule::ValExpression(expr) => { let expr = expr.get(section).ok()?;
eval_expr::<R, UR, S>(expr, encoding, regs)
}
RegisterRule::Architectural => { // Unimplemented // TODO: Find out what the architectural rules for x86_64 and for aarch64 are, if any.
None
}
_ => None,
}
}
Messung V0.5 in Prozent
¤ 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.0.5Bemerkung:
¤
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.