Skip to content

Commit 1ca3abd

Browse files
committed
Use -data-list-register-names for register names
1 parent 12e451b commit 1ca3abd

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

src/main.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,9 @@ use Constraint::{Fill, Length, Max, Min};
2929

3030
mod mi;
3131
use mi::{
32-
data_disassemble, data_read_memory_bytes, parse_asm_insns_values, parse_key_value_pairs,
33-
parse_register_values, register_x86_64, Asm, MIResponse, Register,
32+
data_disassemble, data_read_memory_bytes, join_registers, parse_asm_insns_values,
33+
parse_key_value_pairs, parse_register_names_values, parse_register_values, Asm, MIResponse,
34+
Register, REGISTER_COUNT_MAX,
3435
};
3536

3637
enum InputMode {
@@ -100,6 +101,7 @@ struct App {
100101
current_pc: Arc<Mutex<u64>>, // TODO: replace with AtomicU64?
101102
parsed_responses: Arc<Mutex<LimitedBuffer<MIResponse>>>,
102103
gdb_stdin: Arc<Mutex<dyn Write + Send>>,
104+
register_names: Arc<Mutex<Vec<String>>>,
103105
registers: Arc<Mutex<Vec<(String, Register)>>>,
104106
stack: Arc<Mutex<HashMap<u64, u64>>>,
105107
asm: Arc<Mutex<Vec<Asm>>>,
@@ -151,6 +153,7 @@ impl App {
151153
messages: LimitedBuffer::new(10),
152154
current_pc: Arc::new(Mutex::new(0)),
153155
parsed_responses: Arc::new(Mutex::new(LimitedBuffer::new(30))),
156+
register_names: Arc::new(Mutex::new(vec![])),
154157
gdb_stdin,
155158
registers: Arc::new(Mutex::new(vec![])),
156159
stack: Arc::new(Mutex::new(HashMap::new())),
@@ -190,6 +193,7 @@ fn main() -> Result<(), Box<dyn Error>> {
190193
let gdb_stdin_arc = Arc::clone(&app.gdb_stdin);
191194
let current_pc_arc = Arc::clone(&app.current_pc);
192195
let parsed_reponses_arc = Arc::clone(&app.parsed_responses);
196+
let register_names_arc = Arc::clone(&app.register_names);
193197
let registers_arc = Arc::clone(&app.registers);
194198
let stack_arc = Arc::clone(&app.stack);
195199
let asm_arc = Arc::clone(&app.asm);
@@ -198,6 +202,7 @@ fn main() -> Result<(), Box<dyn Error>> {
198202
thread::spawn(move || {
199203
gdb_interact(
200204
gdb_stdout,
205+
register_names_arc,
201206
registers_arc,
202207
current_pc_arc,
203208
stack_arc,
@@ -228,6 +233,7 @@ fn main() -> Result<(), Box<dyn Error>> {
228233

229234
fn gdb_interact(
230235
gdb_stdout: BufReader<Box<dyn Read + Send>>,
236+
register_names_arc: Arc<Mutex<Vec<String>>>,
231237
registers_arc: Arc<Mutex<Vec<(String, Register)>>>,
232238
current_pc_arc: Arc<Mutex<u64>>,
233239
stack_arc: Arc<Mutex<HashMap<u64, u64>>>,
@@ -249,15 +255,21 @@ fn gdb_interact(
249255
debug!("{arch}");
250256
}
251257
// When a breakpoint is hit, query for register values
258+
next_write.push("-data-list-register-names".to_string());
252259
next_write.push("-data-list-register-values x".to_string());
253260
}
254261
}
255262
MIResponse::ExecResult(_, kv) => {
256-
if let Some(register_values) = kv.get("register-values") {
263+
if let Some(register_names) = kv.get("register-names") {
264+
let register_names = parse_register_names_values(register_names);
265+
let mut regs_names = register_names_arc.lock().unwrap();
266+
*regs_names = register_names;
267+
} else if let Some(register_values) = kv.get("register-values") {
257268
let registers = parse_register_values(register_values);
258269
// Check if response is register data
259270
let mut regs = registers_arc.lock().unwrap();
260-
let registers = register_x86_64(&registers);
271+
let mut regs_names = register_names_arc.lock().unwrap();
272+
let registers = join_registers(&regs_names, &registers);
261273
for s in registers.iter() {
262274
if s.0 == "rsp" {
263275
let start_addr = s.1.value.as_ref().unwrap();
@@ -441,7 +453,7 @@ fn update_from_previous_input(app: &mut App) {
441453

442454
fn ui(f: &mut Frame, app: &App) {
443455
// TODO: register size should depend on arch
444-
let register_size = Length(26);
456+
let register_size = Length(REGISTER_COUNT_MAX as u16 + 1);
445457
let stack_size = Min(10);
446458
let asm_size = Min(10);
447459
let info_size = Length(5);

src/mi.rs

+24-7
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use std::collections::HashMap;
44
use log::debug;
55
use regex::Regex;
66

7+
pub const REGISTER_COUNT_MAX: usize = 25;
8+
79
// Define Register struct to hold register data
810
#[derive(Debug, Clone)]
911
pub struct Register {
@@ -104,14 +106,17 @@ pub fn parse_key_value_pairs(input: &str) -> HashMap<String, String> {
104106
map
105107
}
106108

107-
// TODO: this could come from: -data-list-register-names
108-
pub fn register_x86_64(registers: &[Register]) -> Vec<(String, Register)> {
109-
let register_names = vec![
110-
"rax", "rbx", "rcx", "rdx", "rsi", "rdi", "rbp", "rsp", "r8", "r9", "r10", "r11", "r12",
111-
"r13", "r14", "r15", "rip", "eflags", "cs", "ss", "ds", "es", "fs", "gs",
112-
];
109+
pub fn join_registers(
110+
register_names: &Vec<String>,
111+
registers: &[Register],
112+
) -> Vec<(String, Register)> {
113113
let mut registers_arch = vec![];
114-
for (i, (register, name)) in registers.iter().zip(register_names.iter()).enumerate() {
114+
for (i, (register, name)) in registers
115+
.iter()
116+
.take(REGISTER_COUNT_MAX)
117+
.zip(register_names.iter().take(REGISTER_COUNT_MAX))
118+
.enumerate()
119+
{
115120
if !register.number.is_empty() {
116121
registers_arch.push((name.to_string(), register.clone()));
117122
debug!("[{i}] register({name}): {:?}", register);
@@ -161,6 +166,18 @@ pub fn parse_register_values(input: &str) -> Vec<Register> {
161166
registers
162167
}
163168

169+
// Function to parse register-values as an array of Registers
170+
pub fn parse_register_names_values(input: &str) -> Vec<String> {
171+
let registers: Vec<String> = input
172+
.trim_matches(|c| c == '[' || c == ']')
173+
.split(',')
174+
.map(|s| s.trim_matches('"').to_string())
175+
.filter(|s| !s.is_empty())
176+
.collect();
177+
178+
registers
179+
}
180+
164181
// Function to parse register-values as an array of Registers
165182
pub fn parse_asm_insns_values(input: &str) -> Vec<Asm> {
166183
let mut asms = Vec::new();

0 commit comments

Comments
 (0)