Skip to content
This repository was archived by the owner on Jan 30, 2024. It is now read-only.

Commit 3fd97a1

Browse files
bors[bot]japaric
andauthored
Merge #207
207: unwind: read as little stacked registers as possible r=jonas-schievink a=japaric the other registers that were being read are not used in the unwinding process closes #187 (this doesn't appear to help with unwinding programs that are in a 'stack overflowed' state however) Co-authored-by: Jorge Aparicio <[email protected]>
2 parents 0d8464f + 65fb514 commit 3fd97a1

File tree

1 file changed

+29
-72
lines changed

1 file changed

+29
-72
lines changed

src/stacked.rs

Lines changed: 29 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ use probe_rs::{Core, MemoryInterface};
44

55
/// Registers stacked on exception entry.
66
#[derive(Debug)]
7-
pub struct Stacked {
8-
r0: u32,
9-
r1: u32,
10-
r2: u32,
11-
r3: u32,
12-
r12: u32,
7+
pub(crate) struct Stacked {
8+
// also pushed onto the stack but we don't need to read them
9+
// r0: u32,
10+
// r1: u32,
11+
// r2: u32,
12+
// r3: u32,
13+
// r12: u32,
1314
pub lr: u32,
1415
pub pc: u32,
15-
xpsr: u32,
16-
fpu_regs: Option<StackedFpuRegs>,
16+
contains_fpu_regs: bool,
1717
}
1818

1919
fn bounds_check(bounds: Range<u32>, start: u32, len: u32) -> Result<(), ()> {
@@ -26,6 +26,15 @@ fn bounds_check(bounds: Range<u32>, start: u32, len: u32) -> Result<(), ()> {
2626
}
2727

2828
impl Stacked {
29+
/// The size of one register / word in bytes
30+
const REGISTER_SIZE: usize = mem::size_of::<u32>();
31+
32+
/// Location (as an offset) of the stacked registers we need for unwinding
33+
const WORDS_OFFSET: usize = 5;
34+
35+
/// Minimum number of stacked registers that we need to read to be able to unwind an exception
36+
const WORDS_MINIMUM: usize = 2;
37+
2938
/// Number of 32-bit words stacked in a basic frame.
3039
const WORDS_BASIC: usize = 8;
3140

@@ -41,89 +50,37 @@ impl Stacked {
4150
fpu: bool,
4251
ram_bounds: Range<u32>,
4352
) -> anyhow::Result<Option<Self>> {
44-
let mut storage = [0; Self::WORDS_EXTENDED];
45-
let registers: &mut [_] = if fpu {
46-
&mut storage
47-
} else {
48-
&mut storage[..Self::WORDS_BASIC]
49-
};
53+
let mut storage = [0; Self::WORDS_MINIMUM];
54+
let registers: &mut [_] = &mut storage;
5055

56+
let start = sp + (Self::REGISTER_SIZE * Self::WORDS_OFFSET) as u32;
5157
if bounds_check(
5258
ram_bounds,
53-
sp,
54-
(registers.len() * mem::size_of::<u32>()) as u32,
59+
start,
60+
(registers.len() * Self::REGISTER_SIZE) as u32,
5561
)
5662
.is_err()
5763
{
5864
return Ok(None);
5965
}
6066

61-
core.read_32(sp, registers)?;
67+
core.read_32(start, registers)?;
6268

6369
Ok(Some(Stacked {
64-
r0: registers[0],
65-
r1: registers[1],
66-
r2: registers[2],
67-
r3: registers[3],
68-
r12: registers[4],
69-
lr: registers[5],
70-
pc: registers[6],
71-
xpsr: registers[7],
72-
fpu_regs: if fpu {
73-
Some(StackedFpuRegs {
74-
s0: f32::from_bits(registers[8]),
75-
s1: f32::from_bits(registers[9]),
76-
s2: f32::from_bits(registers[10]),
77-
s3: f32::from_bits(registers[11]),
78-
s4: f32::from_bits(registers[12]),
79-
s5: f32::from_bits(registers[13]),
80-
s6: f32::from_bits(registers[14]),
81-
s7: f32::from_bits(registers[15]),
82-
s8: f32::from_bits(registers[16]),
83-
s9: f32::from_bits(registers[17]),
84-
s10: f32::from_bits(registers[18]),
85-
s11: f32::from_bits(registers[19]),
86-
s12: f32::from_bits(registers[20]),
87-
s13: f32::from_bits(registers[21]),
88-
s14: f32::from_bits(registers[22]),
89-
s15: f32::from_bits(registers[23]),
90-
fpscr: registers[24],
91-
})
92-
} else {
93-
None
94-
},
70+
lr: registers[0],
71+
pc: registers[1],
72+
contains_fpu_regs: fpu,
9573
}))
9674
}
9775

9876
/// Returns the in-memory size of these stacked registers, in Bytes.
9977
pub fn size(&self) -> u32 {
100-
let num_words = if self.fpu_regs.is_none() {
101-
Self::WORDS_BASIC
102-
} else {
78+
let num_words = if self.contains_fpu_regs {
10379
Self::WORDS_EXTENDED
80+
} else {
81+
Self::WORDS_BASIC
10482
};
10583

10684
num_words as u32 * 4
10785
}
10886
}
109-
110-
#[derive(Debug)]
111-
struct StackedFpuRegs {
112-
s0: f32,
113-
s1: f32,
114-
s2: f32,
115-
s3: f32,
116-
s4: f32,
117-
s5: f32,
118-
s6: f32,
119-
s7: f32,
120-
s8: f32,
121-
s9: f32,
122-
s10: f32,
123-
s11: f32,
124-
s12: f32,
125-
s13: f32,
126-
s14: f32,
127-
s15: f32,
128-
fpscr: u32,
129-
}

0 commit comments

Comments
 (0)