blob: 664cb4573d9f1b42f3cf6cdbceb4c4c96a941471 [file] [log] [blame]
use gdbstub::arch::lldb::{Encoding, Format, Generic, Register};
use gdbstub::arch::RegId;
use gdbstub::target;
use gdbstub::target::ext::lldb_register_info_override::{Callback, CallbackToken};
use gdbstub_arch::arm::reg::id::ArmCoreRegId;
use crate::gdb::custom_arch::ArmCoreRegIdCustom;
use crate::gdb::Emu;
// (LLDB extension) This implementation is for illustrative purposes only.
//
// Note: In this implementation, we have r0-pc from 0-16 but cpsr is at offset
// 25*4 in the 'g'/'G' packets, so we add 8 padding registers here. Please see
// gdbstub/examples/armv4t/gdb/target_description_xml_override.rs for more info.
impl target::ext::lldb_register_info_override::LldbRegisterInfoOverride for Emu {
fn lldb_register_info<'a>(
&mut self,
reg_id: usize,
reg_info: Callback<'a>,
) -> Result<CallbackToken<'a>, Self::Error> {
match ArmCoreRegIdCustom::from_raw_id(reg_id) {
Some((_, None)) | None => Ok(reg_info.done()),
Some((r, Some(size))) => {
let name: String = match r {
// For the purpose of demonstration, we end the qRegisterInfo packet exchange
// when reaching the Time register id, so that this register can only be
// explicitly queried via the single-register read packet.
ArmCoreRegIdCustom::Time => return Ok(reg_info.done()),
ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(i)) => match i {
0 => "r0",
1 => "r1",
2 => "r2",
3 => "r3",
4 => "r4",
5 => "r5",
6 => "r6",
7 => "r7",
8 => "r8",
9 => "r9",
10 => "r10",
11 => "r11",
12 => "r12",
_ => "unknown",
},
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => "sp",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Lr) => "lr",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => "pc",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Fpr(_i)) => "padding",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Fps) => "padding",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) => "cpsr",
ArmCoreRegIdCustom::Custom => "custom",
_ => "unknown",
}
.into();
let encoding = match r {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Encoding::Uint,
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
| ArmCoreRegIdCustom::Custom => Encoding::Uint,
_ => Encoding::Vector,
};
let format = match r {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Format::Hex,
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
| ArmCoreRegIdCustom::Custom => Format::Hex,
_ => Format::VectorUInt8,
};
let set: String = match r {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => "General Purpose Registers",
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc)
| ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr)
| ArmCoreRegIdCustom::Custom => "General Purpose Registers",
_ => "Floating Point Registers",
}
.into();
let generic = match r {
ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => Some(Generic::Sp),
ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => Some(Generic::Pc),
_ => None,
};
let reg = Register {
name: &name,
alt_name: None,
bitsize: (usize::from(size)) * 8,
offset: reg_id * (usize::from(size)),
encoding,
format,
set: &set,
gcc: None,
dwarf: Some(reg_id),
generic,
container_regs: None,
invalidate_regs: None,
};
Ok(reg_info.write(reg))
}
}
}
}