debug_worker/gdb/targets/target_aarch64/
mod.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Target implementation for aarch64.
5
6use super::ArchError;
7use super::TargetArch;
8use aarch64defs::Cpsr64;
9use gdbstub_arch::aarch64::reg::AArch64CoreRegs;
10use vmm_core_defs::debug_rpc::DebuggerVpState;
11
12impl TargetArch for gdbstub_arch::aarch64::AArch64 {
13    type Address = u64;
14
15    fn register(
16        state: &DebuggerVpState,
17        reg_id: Self::RegId,
18        buf: &mut [u8],
19    ) -> Result<usize, ArchError> {
20        let DebuggerVpState::Aarch64(state) = state else {
21            return Err(ArchError);
22        };
23        let n = match reg_id {
24            gdbstub_arch::aarch64::reg::id::AArch64RegId::X(i) => {
25                buf[..8].copy_from_slice(&state.x[i as usize].to_le_bytes());
26                8
27            }
28            gdbstub_arch::aarch64::reg::id::AArch64RegId::Sp => {
29                let sp = if Cpsr64::from(state.cpsr).el() == 1 {
30                    state.sp_el1
31                } else {
32                    state.sp_el0
33                };
34                buf[..8].copy_from_slice(&sp.to_le_bytes());
35                8
36            }
37            gdbstub_arch::aarch64::reg::id::AArch64RegId::Pc => {
38                buf[..8].copy_from_slice(&state.pc.to_le_bytes());
39                8
40            }
41            gdbstub_arch::aarch64::reg::id::AArch64RegId::Pstate => {
42                buf[..4].copy_from_slice(&(state.cpsr as u32).to_le_bytes());
43                4
44            }
45            gdbstub_arch::aarch64::reg::id::AArch64RegId::System(id) => {
46                // System Registers encoded as (Op0:2, Op1:3, CRn:4, CRm:4, Op2:2)
47                let reg = aarch64defs::SystemReg(
48                    aarch64defs::SystemRegEncoding::new()
49                        .with_op0((id >> 14) as u8)
50                        .with_op1(((id >> 11) & 0b111) as u8)
51                        .with_crn(((id >> 7) & 0b1111) as u8)
52                        .with_crm(((id >> 3) & 0b1111) as u8)
53                        .with_op2((id & 0b11) as u8),
54                );
55                tracing::warn!(?reg, "unsupported system register");
56                return Err(ArchError);
57            }
58            _ => return Err(ArchError),
59        };
60        Ok(n)
61    }
62
63    fn registers(state: &DebuggerVpState, regs: &mut Self::Registers) -> Result<(), ArchError> {
64        let DebuggerVpState::Aarch64(state) = state else {
65            return Err(ArchError);
66        };
67        *regs = AArch64CoreRegs {
68            x: state.x,
69            sp: if Cpsr64::from(state.cpsr).el() == 1 {
70                state.sp_el1
71            } else {
72                state.sp_el0
73            },
74            pc: state.pc,
75            cpsr: state.cpsr as u32,
76            v: [0; 32], // TODO: plumb floating point register state
77            fpcr: 0,
78            fpsr: 0,
79        };
80        Ok(())
81    }
82
83    fn update_registers(
84        _state: &mut DebuggerVpState,
85        _regs: &Self::Registers,
86    ) -> Result<(), ArchError> {
87        Err(ArchError)
88    }
89
90    fn update_register(
91        _state: &mut DebuggerVpState,
92        _reg_id: Self::RegId,
93        _val: &[u8],
94    ) -> Result<(), ArchError> {
95        Err(ArchError)
96    }
97}