use dbgscope::dbgeng::DebugEngine;
fn kind(value: u32) -> &'static str {
match value {
1 => "int8",
2 => "int16",
3 => "int32",
4 => "int64",
5 => "float32",
6 => "float64",
7 => "float80",
8 => "float82",
9 => "float128",
10 => "vector64",
11 => "vector128",
other => Box::leak(format!("type{other}").into_boxed_str()),
}
}
const SUB_REGISTER: u32 = 0x1;
fn main() {
let Some(path) = std::env::args().nth(1) else {
eprintln!("usage: cargo run --example register_description -- <dump path>");
std::process::exit(2);
};
let e = DebugEngine::new();
if let Err(why) = e.open_dump(&path) {
eprintln!("could not open {path}: {why}");
std::process::exit(1);
}
if let Err(why) = e.wait_for_event(60_000) {
eprintln!("the dump never settled: {why}");
std::process::exit(1);
}
let descriptions = match e.register_descriptions() {
Ok(descriptions) => descriptions,
Err(why) => {
eprintln!("could not describe the registers: {why}");
std::process::exit(1);
}
};
println!("{} registers\n", descriptions.len());
println!(
"{:<12} {:>9} {:>7} {:>7} {:>12} {:>7} {:>7}",
"name", "kind", "flags", "sub?", "master", "length", "shift"
);
for description in &descriptions {
let flagged = description.flags & SUB_REGISTER != 0;
let master = descriptions
.get(description.subreg_master as usize)
.map(|master| master.name.as_str())
.unwrap_or("-");
println!(
"{:<12} {:>9} {:>#7x} {:>7} {:>12} {:>7} {:>7}",
description.name,
kind(description.kind),
description.flags,
if flagged { "yes" } else { "" },
format!("{}({})", master, description.subreg_master),
description.subreg_length,
description.subreg_shift,
);
}
let flagged = descriptions
.iter()
.filter(|d| d.flags & SUB_REGISTER != 0)
.count();
let unflagged_carrying_anything = descriptions
.iter()
.filter(|d| {
d.flags & SUB_REGISTER == 0
&& (d.subreg_master != 0
|| d.subreg_length != 0
|| d.subreg_shift != 0
|| d.subreg_mask != 0)
})
.count();
println!(
"\nflagged as sub-registers: {flagged}\nunflagged, with any sub-register field set: \
{unflagged_carrying_anything}"
);
for name in ["xmm0/0", "w0", "eax"] {
if let Some(d) = descriptions.iter().find(|d| d.name == name) {
let master = descriptions
.get(d.subreg_master as usize)
.map(|m| m.name.as_str())
.unwrap_or("-");
println!(
" {name}: flags={:#x} kind={} master={master}({}) length={} shift={}",
d.flags,
kind(d.kind),
d.subreg_master,
d.subreg_length,
d.subreg_shift
);
}
}
}