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}