diff --git a/src/gdbserver.rs b/src/gdbserver.rs index ae11619..70ef3a9 100644 --- a/src/gdbserver.rs +++ b/src/gdbserver.rs @@ -1,4 +1,5 @@ use anyhow::{bail, Result}; +use registers::REGISTERS; use request::{Request, RequestKind}; use response::Response; use std::{ @@ -17,6 +18,7 @@ use tokio::{ use crate::emulator::{EmulatorClient, EmulatorCommand, SimId}; +mod registers; mod request; mod response; @@ -191,6 +193,18 @@ impl GdbConnection { hex::encode("v810-unknown-vb") )); self.send(res).await?; + } else if req.match_str("qRegisterInfo") { + let mut get_reg_info = || { + let register = req.match_hex::()?; + REGISTERS.get(register) + }; + let Some(reg_info) = get_reg_info() else { + let res = self.response(); + self.send(res).await?; + continue; + }; + let res = self.response().write_str(®_info.to_description()); + self.send(res).await?; } else if req.match_str("vCont?") { let res = self.response().write_str("vCont;c;"); self.send(res).await?; diff --git a/src/gdbserver/registers.rs b/src/gdbserver/registers.rs new file mode 100644 index 0000000..ad5f5f4 --- /dev/null +++ b/src/gdbserver/registers.rs @@ -0,0 +1,117 @@ +pub struct RegisterInfo { + index: usize, + name: &'static str, + set: &'static str, + alt_name: Option<&'static str>, + generic: Option<&'static str>, +} + +impl RegisterInfo { + pub fn to_description(&self) -> String { + let mut string = format!("name:{}", self.name); + if let Some(alt) = self.alt_name { + string.push_str(&format!(";alt-name:{}", alt)); + } + string.push_str(&format!( + ";bitsize:32;offset:{};encoding:uint;format:hex;set:{};dwarf:{}", + self.index * 4, + self.set, + self.index + )); + if let Some(generic) = self.generic { + string.push_str(&format!(";generic:{}", generic)); + } + string + } +} + +macro_rules! register { + ($set:expr, $index:expr, $name:expr) => { + RegisterInfo { + index: $index, + name: $name, + set: $set, + alt_name: None, + generic: None, + } + }; + ($set:expr, $index:expr, $name:expr, alt: $alt:expr) => { + RegisterInfo { + index: $index, + name: $name, + set: $set, + alt_name: Some($alt), + generic: None, + } + }; + ($set:expr, $index:expr, $name:expr, generic: $generic:expr) => { + RegisterInfo { + index: $index, + name: $name, + set: $set, + alt_name: None, + generic: Some($generic), + } + }; + ($set:expr, $index:expr, $name:expr, alt: $alt:expr, generic: $generic:expr) => { + RegisterInfo { + index: $index, + name: $name, + set: $set, + alt_name: Some($alt), + generic: Some($generic), + } + }; +} + +const GENERAL: &str = "General Purpose Registers"; +const SPECIAL: &str = "Special Registers"; + +pub const REGISTERS: [RegisterInfo; 46] = [ + register!(GENERAL, 0, "r0"), + register!(GENERAL, 1, "r1"), + register!(GENERAL, 2, "fp", alt: "r2", generic: "fp"), + register!(GENERAL, 3, "sp", alt: "r3", generic: "sp"), + register!(GENERAL, 4, "gp", alt: "r4"), + register!(GENERAL, 5, "tp", alt: "r5"), + register!(GENERAL, 6, "r6", generic: "arg1"), + register!(GENERAL, 7, "r7", generic: "arg2"), + register!(GENERAL, 8, "r8", generic: "arg3"), + register!(GENERAL, 9, "r9", generic: "arg4"), + register!(GENERAL, 10, "r10"), + register!(GENERAL, 11, "r11"), + register!(GENERAL, 12, "r12"), + register!(GENERAL, 13, "r13"), + register!(GENERAL, 14, "r14"), + register!(GENERAL, 15, "r15"), + register!(GENERAL, 16, "r16"), + register!(GENERAL, 17, "r17"), + register!(GENERAL, 18, "r18"), + register!(GENERAL, 19, "r19"), + register!(GENERAL, 20, "r20"), + register!(GENERAL, 21, "r21"), + register!(GENERAL, 22, "r22"), + register!(GENERAL, 23, "r23"), + register!(GENERAL, 24, "r24"), + register!(GENERAL, 25, "r25"), + register!(GENERAL, 26, "r26"), + register!(GENERAL, 27, "r27"), + register!(GENERAL, 28, "r28"), + register!(GENERAL, 29, "r29"), + register!(GENERAL, 30, "r30"), + register!(GENERAL, 31, "lp", alt: "r31", generic: "ra"), + register!(SPECIAL, 32, "eipc", alt: "sr0"), + register!(SPECIAL, 33, "eipsw", alt: "sr1"), + register!(SPECIAL, 34, "fepc", alt: "sr2"), + register!(SPECIAL, 35, "fepsw", alt: "sr3"), + register!(SPECIAL, 36, "ecr", alt: "sr4"), + register!(SPECIAL, 37, "psw", alt: "sr5", generic: "flags"), + register!(SPECIAL, 38, "pir", alt: "sr6"), + register!(SPECIAL, 39, "tkcw", alt: "sr7"), + register!(SPECIAL, 40, "chcw", alt: "sr24"), + register!(SPECIAL, 41, "adtre", alt: "sr25"), + register!(SPECIAL, 42, "sr29"), + register!(SPECIAL, 43, "sr30"), + register!(SPECIAL, 44, "sr31"), + register!(SPECIAL, 45, "pc", generic: "pc"), +];