yggdrasil/userspace/rdb/src/aarch64.rs

59 lines
1.6 KiB
Rust

use std::fmt::{self, Display};
use yggdrasil_abi::arch::SavedFrame;
use super::{Error, InstructionFormatter, Target};
pub struct TargetImpl;
pub struct Unsupported;
pub struct FlagFormat(u64);
impl Display for FlagFormat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
const FLAGS: &[(u64, &str)] = &[(27, "Q"), (28, "V"), (29, "C"), (30, "Z"), (31, "N")];
write!(f, " {: <#8x} [ ", self.0)?;
for (bit, flag) in FLAGS {
if self.0 & (1 << bit) != 0 {
write!(f, "{} ", flag)?;
}
}
write!(f, "]")
}
}
impl InstructionFormatter<()> for Unsupported {
fn format_instruction(&mut self, _insn: &(), _out: &mut String) {}
}
impl Target for TargetImpl {
type Instruction = ();
type InstructionFormatter = Unsupported;
type Register = usize;
fn disassemble(
_window: &[u8],
_ip: usize,
_limit: usize,
) -> Result<Vec<(usize, Self::Instruction)>, Error> {
Ok(vec![])
}
fn new_instruction_formatter() -> Self::InstructionFormatter {
Unsupported
}
fn flags_register_as_display(frame: &SavedFrame) -> impl Display {
FlagFormat(frame.spsr_el1)
}
fn register_list(frame: &SavedFrame, out: &mut Vec<(String, Self::Register)>) {
for i in 0..30 {
out.push((format!("x{}", i), frame.gp_regs[i]));
}
out.push(("pc".into(), frame.elr_el1 as _));
out.push(("lr".into(), frame.gp_regs[30]));
}
fn real_ip(frame: &SavedFrame) -> usize {
frame.elr_el1 as _
}
}