1 use crate::gdb::custom_arch::ArmCoreRegIdCustom; 2 use crate::gdb::Emu; 3 use gdbstub::arch::lldb::Encoding; 4 use gdbstub::arch::lldb::Format; 5 use gdbstub::arch::lldb::Generic; 6 use gdbstub::arch::lldb::Register; 7 use gdbstub::arch::RegId; 8 use gdbstub::target; 9 use gdbstub::target::ext::lldb_register_info_override::Callback; 10 use gdbstub::target::ext::lldb_register_info_override::CallbackToken; 11 use gdbstub_arch::arm::reg::id::ArmCoreRegId; 12 13 // (LLDB extension) This implementation is for illustrative purposes only. 14 // 15 // Note: In this implementation, we have r0-pc from 0-16 but cpsr is at offset 16 // 25*4 in the 'g'/'G' packets, so we add 8 padding registers here. Please see 17 // gdbstub/examples/armv4t/gdb/target_description_xml_override.rs for more info. 18 impl target::ext::lldb_register_info_override::LldbRegisterInfoOverride for Emu { lldb_register_info<'a>( &mut self, reg_id: usize, reg_info: Callback<'a>, ) -> Result<CallbackToken<'a>, Self::Error>19 fn lldb_register_info<'a>( 20 &mut self, 21 reg_id: usize, 22 reg_info: Callback<'a>, 23 ) -> Result<CallbackToken<'a>, Self::Error> { 24 match ArmCoreRegIdCustom::from_raw_id(reg_id) { 25 Some((_, None)) | None => Ok(reg_info.done()), 26 Some((r, Some(size))) => { 27 let name: String = match r { 28 // For the purpose of demonstration, we end the qRegisterInfo packet exchange 29 // when reaching the Time register id, so that this register can only be 30 // explicitly queried via the single-register read packet. 31 ArmCoreRegIdCustom::Time => return Ok(reg_info.done()), 32 ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(i)) => match i { 33 0 => "r0", 34 1 => "r1", 35 2 => "r2", 36 3 => "r3", 37 4 => "r4", 38 5 => "r5", 39 6 => "r6", 40 7 => "r7", 41 8 => "r8", 42 9 => "r9", 43 10 => "r10", 44 11 => "r11", 45 12 => "r12", 46 _ => "unknown", 47 }, 48 ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => "sp", 49 ArmCoreRegIdCustom::Core(ArmCoreRegId::Lr) => "lr", 50 ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => "pc", 51 ArmCoreRegIdCustom::Core(ArmCoreRegId::Fpr(_i)) => "padding", 52 ArmCoreRegIdCustom::Core(ArmCoreRegId::Fps) => "padding", 53 ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) => "cpsr", 54 ArmCoreRegIdCustom::Custom => "custom", 55 _ => "unknown", 56 } 57 .into(); 58 let encoding = match r { 59 ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Encoding::Uint, 60 ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) 61 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) 62 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) 63 | ArmCoreRegIdCustom::Custom => Encoding::Uint, 64 _ => Encoding::Vector, 65 }; 66 let format = match r { 67 ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => Format::Hex, 68 ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) 69 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) 70 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) 71 | ArmCoreRegIdCustom::Custom => Format::Hex, 72 _ => Format::VectorUInt8, 73 }; 74 let set: String = match r { 75 ArmCoreRegIdCustom::Core(ArmCoreRegId::Gpr(_i)) => "General Purpose Registers", 76 ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) 77 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) 78 | ArmCoreRegIdCustom::Core(ArmCoreRegId::Cpsr) 79 | ArmCoreRegIdCustom::Custom => "General Purpose Registers", 80 _ => "Floating Point Registers", 81 } 82 .into(); 83 let generic = match r { 84 ArmCoreRegIdCustom::Core(ArmCoreRegId::Sp) => Some(Generic::Sp), 85 ArmCoreRegIdCustom::Core(ArmCoreRegId::Pc) => Some(Generic::Pc), 86 _ => None, 87 }; 88 let reg = Register { 89 name: &name, 90 alt_name: None, 91 bitsize: (usize::from(size)) * 8, 92 offset: reg_id * (usize::from(size)), 93 encoding, 94 format, 95 set: &set, 96 gcc: None, 97 dwarf: Some(reg_id), 98 generic, 99 container_regs: None, 100 invalidate_regs: None, 101 }; 102 Ok(reg_info.write(reg)) 103 } 104 } 105 } 106 } 107