Skip to content

Commit b462967

Browse files
committed
Use pointers instead of usize addresses for landing pads
This bring unwind and personality code more in line with strict-provenance
1 parent 11467b1 commit b462967

File tree

4 files changed

+43
-36
lines changed

4 files changed

+43
-36
lines changed

Diff for: library/panic_unwind/src/gcc.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
6363
_uwe: uw::_Unwind_Exception {
6464
exception_class: rust_exception_class(),
6565
exception_cleanup,
66-
private: [0; uw::unwinder_private_data_size],
66+
private: [core::ptr::null(); uw::unwinder_private_data_size],
6767
},
6868
canary: &CANARY,
6969
cause: data,

Diff for: library/std/src/sys/personality/dwarf/eh.rs

+37-29
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Parsing of GCC-style Language-Specific Data Area (LSDA)
22
//! For details see:
33
//! * <https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA/ehframechpt.html>
4+
//! * <https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/dwarfext.html>
45
//! * <https://itanium-cxx-abi.github.io/cxx-abi/exceptions.pdf>
56
//! * <https://www.airs.com/blog/archives/460>
67
//! * <https://www.airs.com/blog/archives/464>
@@ -37,17 +38,19 @@ pub const DW_EH_PE_indirect: u8 = 0x80;
3738

3839
#[derive(Copy, Clone)]
3940
pub struct EHContext<'a> {
40-
pub ip: usize, // Current instruction pointer
41-
pub func_start: usize, // Address of the current function
42-
pub get_text_start: &'a dyn Fn() -> usize, // Get address of the code section
43-
pub get_data_start: &'a dyn Fn() -> usize, // Get address of the data section
41+
pub ip: *const u8, // Current instruction pointer
42+
pub func_start: *const u8, // Pointer to the current function
43+
pub get_text_start: &'a dyn Fn() -> *const u8, // Get pointer to the code section
44+
pub get_data_start: &'a dyn Fn() -> *const u8, // Get pointer to the data section
4445
}
4546

47+
/// Landing pad.
48+
type LPad = *const u8;
4649
pub enum EHAction {
4750
None,
48-
Cleanup(usize),
49-
Catch(usize),
50-
Filter(usize),
51+
Cleanup(LPad),
52+
Catch(LPad),
53+
Filter(LPad),
5154
Terminate,
5255
}
5356

@@ -82,21 +85,21 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
8285

8386
if !USING_SJLJ_EXCEPTIONS {
8487
while reader.ptr < action_table {
85-
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding)?;
86-
let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding)?;
87-
let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding)?;
88+
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding)?.addr();
89+
let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding)?.addr();
90+
let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding)?.addr();
8891
let cs_action_entry = reader.read_uleb128();
8992
// Callsite table is sorted by cs_start, so if we've passed the ip, we
9093
// may stop searching.
91-
if ip < func_start + cs_start {
94+
if ip < func_start.wrapping_add(cs_start) {
9295
break;
9396
}
94-
if ip < func_start + cs_start + cs_len {
97+
if ip < func_start.wrapping_add(cs_start + cs_len) {
9598
if cs_lpad == 0 {
9699
return Ok(EHAction::None);
97100
} else {
98-
let lpad = lpad_base + cs_lpad;
99-
return Ok(interpret_cs_action(action_table as *mut u8, cs_action_entry, lpad));
101+
let lpad = lpad_base.wrapping_add(cs_lpad);
102+
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
100103
}
101104
}
102105
}
@@ -106,30 +109,31 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
106109
// SjLj version:
107110
// The "IP" is an index into the call-site table, with two exceptions:
108111
// -1 means 'no-action', and 0 means 'terminate'.
109-
match ip as isize {
112+
match ip.addr() as isize {
110113
-1 => return Ok(EHAction::None),
111114
0 => return Ok(EHAction::Terminate),
112115
_ => (),
113116
}
114-
let mut idx = ip;
117+
let mut idx = ip.addr();
115118
loop {
116119
let cs_lpad = reader.read_uleb128();
117120
let cs_action_entry = reader.read_uleb128();
118121
idx -= 1;
119122
if idx == 0 {
120123
// Can never have null landing pad for sjlj -- that would have
121124
// been indicated by a -1 call site index.
122-
let lpad = (cs_lpad + 1) as usize;
123-
return Ok(interpret_cs_action(action_table as *mut u8, cs_action_entry, lpad));
125+
// FIXME(strict provenance)
126+
let lpad = ptr::from_exposed_addr((cs_lpad + 1) as usize);
127+
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
124128
}
125129
}
126130
}
127131
}
128132

129133
unsafe fn interpret_cs_action(
130-
action_table: *mut u8,
134+
action_table: *const u8,
131135
cs_action_entry: u64,
132-
lpad: usize,
136+
lpad: LPad,
133137
) -> EHAction {
134138
if cs_action_entry == 0 {
135139
// If cs_action_entry is 0 then this is a cleanup (Drop::drop). We run these
@@ -138,7 +142,7 @@ unsafe fn interpret_cs_action(
138142
} else {
139143
// If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
140144
// If ttype_index == 0 under the condition, we take cleanup action.
141-
let action_record = (action_table as *mut u8).offset(cs_action_entry as isize - 1);
145+
let action_record = action_table.offset(cs_action_entry as isize - 1);
142146
let mut action_reader = DwarfReader::new(action_record);
143147
let ttype_index = action_reader.read_sleb128();
144148
if ttype_index == 0 {
@@ -161,15 +165,16 @@ unsafe fn read_encoded_pointer(
161165
reader: &mut DwarfReader,
162166
context: &EHContext<'_>,
163167
encoding: u8,
164-
) -> Result<usize, ()> {
168+
) -> Result<*const u8, ()> {
165169
if encoding == DW_EH_PE_omit {
166170
return Err(());
167171
}
168172

169173
// DW_EH_PE_aligned implies it's an absolute pointer value
170174
if encoding == DW_EH_PE_aligned {
171-
reader.ptr = reader.ptr.with_addr(round_up(reader.ptr.addr(), mem::size_of::<usize>())?);
172-
return Ok(reader.read::<usize>());
175+
reader.ptr =
176+
reader.ptr.with_addr(round_up(reader.ptr.addr(), mem::size_of::<*const u8>())?);
177+
return Ok(reader.read::<*const u8>());
173178
}
174179

175180
let mut result = match encoding & 0x0F {
@@ -190,18 +195,21 @@ unsafe fn read_encoded_pointer(
190195
// relative to address of the encoded value, despite the name
191196
DW_EH_PE_pcrel => reader.ptr.expose_addr(),
192197
DW_EH_PE_funcrel => {
193-
if context.func_start == 0 {
198+
if context.func_start.is_null() {
194199
return Err(());
195200
}
196-
context.func_start
201+
context.func_start.expose_addr()
197202
}
198-
DW_EH_PE_textrel => (*context.get_text_start)(),
199-
DW_EH_PE_datarel => (*context.get_data_start)(),
203+
DW_EH_PE_textrel => (*context.get_text_start)().expose_addr(),
204+
DW_EH_PE_datarel => (*context.get_data_start)().expose_addr(),
200205
_ => return Err(()),
201206
};
202207

208+
// FIXME(strict provenance)
209+
let mut result: *const u8 = ptr::from_exposed_addr::<u8>(result);
210+
203211
if encoding & DW_EH_PE_indirect != 0 {
204-
result = *ptr::from_exposed_addr::<usize>(result);
212+
result = *(result.cast::<*const u8>());
205213
}
206214

207215
Ok(result)

Diff for: library/std/src/sys/personality/gcc.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
3939
use super::dwarf::eh::{self, EHAction, EHContext};
4040
use crate::ffi::c_int;
41-
use libc::uintptr_t;
4241
use unwind as uw;
4342

4443
// Register ids were lifted from LLVM's TargetLowering::getExceptionPointerRegister()
@@ -219,9 +218,9 @@ cfg_if::cfg_if! {
219218
uw::_Unwind_SetGR(
220219
context,
221220
UNWIND_DATA_REG.0,
222-
exception_object as uintptr_t,
221+
exception_object.cast(),
223222
);
224-
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, 0);
223+
uw::_Unwind_SetGR(context, UNWIND_DATA_REG.1, core::ptr::null());
225224
uw::_Unwind_SetIP(context, lpad);
226225
uw::_URC_INSTALL_CONTEXT
227226
}

Diff for: library/unwind/src/libunwind.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(nonstandard_style)]
22

3-
use libc::{c_int, c_void, uintptr_t};
3+
use libc::{c_int, c_void};
44

55
#[repr(C)]
66
#[derive(Debug, Copy, Clone, PartialEq)]
@@ -19,8 +19,8 @@ pub enum _Unwind_Reason_Code {
1919
pub use _Unwind_Reason_Code::*;
2020

2121
pub type _Unwind_Exception_Class = u64;
22-
pub type _Unwind_Word = uintptr_t;
23-
pub type _Unwind_Ptr = uintptr_t;
22+
pub type _Unwind_Word = *const u8;
23+
pub type _Unwind_Ptr = *const u8;
2424
pub type _Unwind_Trace_Fn =
2525
extern "C" fn(ctx: *mut _Unwind_Context, arg: *mut c_void) -> _Unwind_Reason_Code;
2626

0 commit comments

Comments
 (0)