libsdb/
register_info.rs

1use core::mem::offset_of;
2use libc::user;
3use libc::user_fpregs_struct;
4use libc::user_regs_struct;
5use libsdb_register_codegen::generate_registers;
6use nix::libc;
7use num_enum::TryFromPrimitive;
8
9macro_rules! gpr_offset {
10    ($reg:ident) => {
11        offset_of!(user, regs) + offset_of!(user_regs_struct, $reg)
12    };
13}
14
15macro_rules! fpr_offset {
16    ($reg:ident) => {
17        offset_of!(user, i387) + offset_of!(user_fpregs_struct, $reg)
18    };
19}
20
21macro_rules! sizeof_field {
22    ($struct:ty, $field:ident) => {{
23        let uninit = std::mem::MaybeUninit::<$struct>::uninit();
24        let base = uninit.as_ptr();
25        let field = unsafe { &(*base).$field };
26        core::mem::size_of_val(field)
27    }};
28}
29
30macro_rules! fpr_size {
31    ($reg:ident) => {
32        sizeof_field!(user_fpregs_struct, $reg)
33    };
34}
35
36generate_registers!("");
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum RegisterType {
40    Gpr, // General purpose register
41    SubGpr,
42    Fpr, // Float point register
43    Dr,  // Debug register
44}
45
46#[derive(Debug, Clone, Copy, PartialEq, Eq)]
47pub enum RegisterFormat {
48    UInt,
49    DoubleFloat,
50    LongDouble,
51    Vector,
52}
53
54#[derive(Debug, Clone, Copy)]
55pub struct RegisterInfo {
56    pub id: RegisterId,
57    pub name: &'static str,
58    pub dwarf_id: i32,
59    pub size: usize,
60    pub offset: usize,
61    pub type_: RegisterType,
62    pub format: RegisterFormat,
63}
64
65use super::sdb_error::SdbError; // adjust this to your actual module path
66
67pub fn register_info_by_id(id: RegisterId) -> Result<RegisterInfo, SdbError> {
68    GRegisterInfos
69        .iter()
70        .find(|info| info.id == id)
71        .copied()
72        .ok_or_else(|| SdbError::new_err("Can't find register info"))
73}
74
75pub fn register_info_by_name(name: &str) -> Result<RegisterInfo, SdbError> {
76    GRegisterInfos
77        .iter()
78        .find(|info| info.name == name)
79        .copied()
80        .ok_or_else(|| SdbError::new_err("Can't find register info"))
81}
82
83pub fn register_info_by_dwarf(dwarf_id: i32) -> Result<RegisterInfo, SdbError> {
84    GRegisterInfos
85        .iter()
86        .find(|info| info.dwarf_id == dwarf_id)
87        .copied()
88        .ok_or_else(|| SdbError::new_err("Can't find register info"))
89}
90
91#[ignore = "Manual"]
92#[test]
93fn print_codegen() {
94    for i in GRegisterInfos {
95        println!("{:?}", i);
96    }
97}