rust_debug/
registers.rs

1use std::collections::HashMap;
2
3/// A struct to hold the register values and other register information.
4#[derive(Debug, Clone)]
5pub struct Registers {
6    /// Holds all the register values.
7    pub registers: HashMap<u16, u32>,
8
9    /// Holds stashed register values. It is used when evaluating values lower down in the stack.
10    stashed_registers: Option<HashMap<u16, u32>>,
11
12    /// The register number which is the program counter register.
13    pub program_counter_register: Option<usize>,
14
15    /// The register number which is the link register.
16    pub link_register: Option<usize>,
17
18    /// The register number which is the stack pointer register.
19    pub stack_pointer_register: Option<usize>,
20
21    /// Canonical Frame Address, which is sometimes needed to evaluate variables.
22    pub cfa: Option<u32>, // Canonical Frame Address
23}
24
25impl Default for Registers {
26    /// Creates a empty `Registers` struct.
27    fn default() -> Registers {
28        Registers {
29            registers: HashMap::new(),
30            stashed_registers: None,
31            program_counter_register: None,
32            link_register: None,
33            stack_pointer_register: None,
34            cfa: None,
35        }
36    }
37}
38impl Registers {
39    /// Add a register value to the struct.
40    ///
41    /// Description:
42    ///
43    /// * `register` - The register to add a value for.
44    /// * `value` - The value that will be stored for that registry.
45    ///
46    /// This function will add the `value` to the `self.registers` HashMap with `register` as the hash
47    /// number.
48    pub fn add_register_value(&mut self, register: u16, value: u32) {
49        self.registers.insert(register, value);
50    }
51
52    /// Retrieve a register value.
53    ///
54    /// Description:
55    ///
56    /// * `register` - The register to get the value from.
57    ///
58    /// Will retrieve the `register` value from the `self.registers` HashMap.
59    pub fn get_register_value(&self, register: &u16) -> Option<&u32> {
60        self.registers.get(register)
61    }
62
63    /// Sets all the register values to `None` in the struct.
64    pub fn clear(&mut self) {
65        self.registers = HashMap::new();
66        self.stashed_registers = None;
67    }
68
69    /// Temporally stash the current register values.
70    ///
71    /// Description:
72    ///
73    /// The current register values will be stashed allowing for other register values to be used
74    /// in the evaluation of variables.
75    /// This is only used when evaluating `StackFrame`s because preserved register values need to
76    /// be used in the evaluation.
77    pub fn stash_registers(&mut self) {
78        self.stashed_registers = Some(self.registers.clone());
79        self.registers = HashMap::new();
80    }
81
82    /// Pop the stashed register values.
83    ///
84    /// Description:
85    ///
86    /// This is used to pop back the stashed registers into `self.registers`.
87    /// This function is only called after doing a stack trace because preserved register values is
88    /// used for evaluating the `StackFrame`s.
89    pub fn pop_stashed_registers(&mut self) {
90        if let Some(registers) = self.stashed_registers.clone() {
91            self.registers = registers;
92        }
93        self.stashed_registers = None;
94    }
95
96    /// Get registers as a Vec of `Variables`
97    ///
98    /// Description:
99    ///
100    /// This is used to get the register as a Vec of Variables.
101    pub fn get_registers_as_list(&self) -> Vec<(u16, u32)> {
102        let mut res: Vec<(u16, u32)> = self
103            .registers
104            .clone()
105            .into_iter()
106            .map(|(id, score)| (id, score))
107            .collect();
108        res.sort_by(|a, b| b.0.cmp(&a.0));
109        res
110    }
111}