mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
std: unsafe-wrap personality::dwarf::eh
In so doing, move the forbid up to the top of personality::dwarf
This commit is contained in:
parent
92c6c03805
commit
e2137a2487
@ -70,45 +70,51 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
|
||||
|
||||
let func_start = context.func_start;
|
||||
let mut reader = DwarfReader::new(lsda);
|
||||
|
||||
let start_encoding = reader.read::<u8>();
|
||||
// base address for landing pad offsets
|
||||
let lpad_base = if start_encoding != DW_EH_PE_omit {
|
||||
read_encoded_pointer(&mut reader, context, start_encoding)?
|
||||
} else {
|
||||
func_start
|
||||
let lpad_base = unsafe {
|
||||
let start_encoding = reader.read::<u8>();
|
||||
// base address for landing pad offsets
|
||||
if start_encoding != DW_EH_PE_omit {
|
||||
read_encoded_pointer(&mut reader, context, start_encoding)?
|
||||
} else {
|
||||
func_start
|
||||
}
|
||||
};
|
||||
let call_site_encoding = unsafe {
|
||||
let ttype_encoding = reader.read::<u8>();
|
||||
if ttype_encoding != DW_EH_PE_omit {
|
||||
// Rust doesn't analyze exception types, so we don't care about the type table
|
||||
reader.read_uleb128();
|
||||
}
|
||||
|
||||
let ttype_encoding = reader.read::<u8>();
|
||||
if ttype_encoding != DW_EH_PE_omit {
|
||||
// Rust doesn't analyze exception types, so we don't care about the type table
|
||||
reader.read_uleb128();
|
||||
}
|
||||
|
||||
let call_site_encoding = reader.read::<u8>();
|
||||
let call_site_table_length = reader.read_uleb128();
|
||||
let action_table = reader.ptr.add(call_site_table_length as usize);
|
||||
reader.read::<u8>()
|
||||
};
|
||||
let action_table = unsafe {
|
||||
let call_site_table_length = reader.read_uleb128();
|
||||
reader.ptr.add(call_site_table_length as usize)
|
||||
};
|
||||
let ip = context.ip;
|
||||
|
||||
if !USING_SJLJ_EXCEPTIONS {
|
||||
// read the callsite table
|
||||
while reader.ptr < action_table {
|
||||
// these are offsets rather than pointers;
|
||||
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_action_entry = reader.read_uleb128();
|
||||
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
||||
// may stop searching.
|
||||
if ip < func_start.wrapping_add(cs_start) {
|
||||
break;
|
||||
}
|
||||
if ip < func_start.wrapping_add(cs_start + cs_len) {
|
||||
if cs_lpad == 0 {
|
||||
return Ok(EHAction::None);
|
||||
} else {
|
||||
let lpad = lpad_base.wrapping_add(cs_lpad);
|
||||
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
|
||||
unsafe {
|
||||
// these are offsets rather than pointers;
|
||||
let cs_start = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_len = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_lpad = read_encoded_offset(&mut reader, call_site_encoding)?;
|
||||
let cs_action_entry = reader.read_uleb128();
|
||||
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
||||
// may stop searching.
|
||||
if ip < func_start.wrapping_add(cs_start) {
|
||||
break;
|
||||
}
|
||||
if ip < func_start.wrapping_add(cs_start + cs_len) {
|
||||
if cs_lpad == 0 {
|
||||
return Ok(EHAction::None);
|
||||
} else {
|
||||
let lpad = lpad_base.wrapping_add(cs_lpad);
|
||||
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -125,15 +131,15 @@ pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result
|
||||
}
|
||||
let mut idx = ip.addr();
|
||||
loop {
|
||||
let cs_lpad = reader.read_uleb128();
|
||||
let cs_action_entry = reader.read_uleb128();
|
||||
let cs_lpad = unsafe { reader.read_uleb128() };
|
||||
let cs_action_entry = unsafe { reader.read_uleb128() };
|
||||
idx -= 1;
|
||||
if idx == 0 {
|
||||
// Can never have null landing pad for sjlj -- that would have
|
||||
// been indicated by a -1 call site index.
|
||||
// FIXME(strict provenance)
|
||||
let lpad = ptr::with_exposed_provenance((cs_lpad + 1) as usize);
|
||||
return Ok(interpret_cs_action(action_table, cs_action_entry, lpad));
|
||||
return Ok(unsafe { interpret_cs_action(action_table, cs_action_entry, lpad) });
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -151,9 +157,9 @@ unsafe fn interpret_cs_action(
|
||||
} else {
|
||||
// If lpad != 0 and cs_action_entry != 0, we have to check ttype_index.
|
||||
// If ttype_index == 0 under the condition, we take cleanup action.
|
||||
let action_record = action_table.offset(cs_action_entry as isize - 1);
|
||||
let action_record = unsafe { action_table.offset(cs_action_entry as isize - 1) };
|
||||
let mut action_reader = DwarfReader::new(action_record);
|
||||
let ttype_index = action_reader.read_sleb128();
|
||||
let ttype_index = unsafe { action_reader.read_sleb128() };
|
||||
if ttype_index == 0 {
|
||||
EHAction::Cleanup(lpad)
|
||||
} else if ttype_index > 0 {
|
||||
@ -186,18 +192,20 @@ unsafe fn read_encoded_offset(reader: &mut DwarfReader, encoding: u8) -> Result<
|
||||
if encoding == DW_EH_PE_omit || encoding & 0xF0 != 0 {
|
||||
return Err(());
|
||||
}
|
||||
let result = match encoding & 0x0F {
|
||||
// despite the name, LLVM also uses absptr for offsets instead of pointers
|
||||
DW_EH_PE_absptr => reader.read::<usize>(),
|
||||
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
|
||||
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
|
||||
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
|
||||
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
|
||||
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
|
||||
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
|
||||
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
||||
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
||||
_ => return Err(()),
|
||||
let result = unsafe {
|
||||
match encoding & 0x0F {
|
||||
// despite the name, LLVM also uses absptr for offsets instead of pointers
|
||||
DW_EH_PE_absptr => reader.read::<usize>(),
|
||||
DW_EH_PE_uleb128 => reader.read_uleb128() as usize,
|
||||
DW_EH_PE_udata2 => reader.read::<u16>() as usize,
|
||||
DW_EH_PE_udata4 => reader.read::<u32>() as usize,
|
||||
DW_EH_PE_udata8 => reader.read::<u64>() as usize,
|
||||
DW_EH_PE_sleb128 => reader.read_sleb128() as usize,
|
||||
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
|
||||
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
||||
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
||||
_ => return Err(()),
|
||||
}
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
@ -250,14 +258,14 @@ unsafe fn read_encoded_pointer(
|
||||
if encoding & 0x0F != DW_EH_PE_absptr {
|
||||
return Err(());
|
||||
}
|
||||
reader.read::<*const u8>()
|
||||
unsafe { reader.read::<*const u8>() }
|
||||
} else {
|
||||
let offset = read_encoded_offset(reader, encoding & 0x0F)?;
|
||||
let offset = unsafe { read_encoded_offset(reader, encoding & 0x0F)? };
|
||||
base_ptr.wrapping_add(offset)
|
||||
};
|
||||
|
||||
if encoding & DW_EH_PE_indirect != 0 {
|
||||
ptr = *(ptr.cast::<*const u8>());
|
||||
ptr = unsafe { *(ptr.cast::<*const u8>()) };
|
||||
}
|
||||
|
||||
Ok(ptr)
|
||||
|
@ -5,6 +5,7 @@
|
||||
// This module is used only by x86_64-pc-windows-gnu for now, but we
|
||||
// are compiling it everywhere to avoid regressions.
|
||||
#![allow(unused)]
|
||||
#![forbid(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
@ -17,7 +18,6 @@ pub struct DwarfReader {
|
||||
pub ptr: *const u8,
|
||||
}
|
||||
|
||||
#[forbid(unsafe_op_in_unsafe_fn)]
|
||||
impl DwarfReader {
|
||||
pub fn new(ptr: *const u8) -> DwarfReader {
|
||||
DwarfReader { ptr }
|
||||
|
Loading…
Reference in New Issue
Block a user