run rustfmt on libpanic_unwind folder
This commit is contained in:
parent
8cbffc5bcf
commit
00bbc27276
7 changed files with 152 additions and 187 deletions
|
@ -24,25 +24,25 @@
|
||||||
use dwarf::DwarfReader;
|
use dwarf::DwarfReader;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
pub const DW_EH_PE_omit : u8 = 0xFF;
|
pub const DW_EH_PE_omit: u8 = 0xFF;
|
||||||
pub const DW_EH_PE_absptr : u8 = 0x00;
|
pub const DW_EH_PE_absptr: u8 = 0x00;
|
||||||
|
|
||||||
pub const DW_EH_PE_uleb128 : u8 = 0x01;
|
pub const DW_EH_PE_uleb128: u8 = 0x01;
|
||||||
pub const DW_EH_PE_udata2 : u8 = 0x02;
|
pub const DW_EH_PE_udata2: u8 = 0x02;
|
||||||
pub const DW_EH_PE_udata4 : u8 = 0x03;
|
pub const DW_EH_PE_udata4: u8 = 0x03;
|
||||||
pub const DW_EH_PE_udata8 : u8 = 0x04;
|
pub const DW_EH_PE_udata8: u8 = 0x04;
|
||||||
pub const DW_EH_PE_sleb128 : u8 = 0x09;
|
pub const DW_EH_PE_sleb128: u8 = 0x09;
|
||||||
pub const DW_EH_PE_sdata2 : u8 = 0x0A;
|
pub const DW_EH_PE_sdata2: u8 = 0x0A;
|
||||||
pub const DW_EH_PE_sdata4 : u8 = 0x0B;
|
pub const DW_EH_PE_sdata4: u8 = 0x0B;
|
||||||
pub const DW_EH_PE_sdata8 : u8 = 0x0C;
|
pub const DW_EH_PE_sdata8: u8 = 0x0C;
|
||||||
|
|
||||||
pub const DW_EH_PE_pcrel : u8 = 0x10;
|
pub const DW_EH_PE_pcrel: u8 = 0x10;
|
||||||
pub const DW_EH_PE_textrel : u8 = 0x20;
|
pub const DW_EH_PE_textrel: u8 = 0x20;
|
||||||
pub const DW_EH_PE_datarel : u8 = 0x30;
|
pub const DW_EH_PE_datarel: u8 = 0x30;
|
||||||
pub const DW_EH_PE_funcrel : u8 = 0x40;
|
pub const DW_EH_PE_funcrel: u8 = 0x40;
|
||||||
pub const DW_EH_PE_aligned : u8 = 0x50;
|
pub const DW_EH_PE_aligned: u8 = 0x50;
|
||||||
|
|
||||||
pub const DW_EH_PE_indirect : u8 = 0x80;
|
pub const DW_EH_PE_indirect: u8 = 0x80;
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
pub struct EHContext {
|
pub struct EHContext {
|
||||||
|
@ -52,8 +52,7 @@ pub struct EHContext {
|
||||||
pub data_start: usize, // Address of the data section
|
pub data_start: usize, // Address of the data section
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext) -> Option<usize> {
|
||||||
-> Option<usize> {
|
|
||||||
if lsda.is_null() {
|
if lsda.is_null() {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -80,7 +79,7 @@ pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
||||||
let action_table = reader.ptr.offset(call_site_table_length as isize);
|
let action_table = reader.ptr.offset(call_site_table_length as isize);
|
||||||
// Return addresses point 1 byte past the call instruction, which could
|
// Return addresses point 1 byte past the call instruction, which could
|
||||||
// be in the next IP range.
|
// be in the next IP range.
|
||||||
let ip = context.ip-1;
|
let ip = context.ip - 1;
|
||||||
|
|
||||||
while reader.ptr < action_table {
|
while reader.ptr < action_table {
|
||||||
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
|
let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding);
|
||||||
|
@ -90,7 +89,7 @@ pub unsafe fn find_landing_pad(lsda: *const u8, context: &EHContext)
|
||||||
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
// Callsite table is sorted by cs_start, so if we've passed the ip, we
|
||||||
// may stop searching.
|
// may stop searching.
|
||||||
if ip < func_start + cs_start {
|
if ip < func_start + cs_start {
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
if ip < func_start + cs_start + cs_len {
|
if ip < func_start + cs_start + cs_len {
|
||||||
if cs_lpad != 0 {
|
if cs_lpad != 0 {
|
||||||
|
@ -114,13 +113,13 @@ fn round_up(unrounded: usize, align: usize) -> usize {
|
||||||
|
|
||||||
unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
||||||
context: &EHContext,
|
context: &EHContext,
|
||||||
encoding: u8) -> usize {
|
encoding: u8)
|
||||||
|
-> usize {
|
||||||
assert!(encoding != DW_EH_PE_omit);
|
assert!(encoding != DW_EH_PE_omit);
|
||||||
|
|
||||||
// DW_EH_PE_aligned implies it's an absolute pointer value
|
// DW_EH_PE_aligned implies it's an absolute pointer value
|
||||||
if encoding == DW_EH_PE_aligned {
|
if encoding == DW_EH_PE_aligned {
|
||||||
reader.ptr = round_up(reader.ptr as usize,
|
reader.ptr = round_up(reader.ptr as usize, mem::size_of::<usize>()) as *const u8;
|
||||||
mem::size_of::<usize>()) as *const u8;
|
|
||||||
return reader.read::<usize>();
|
return reader.read::<usize>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,20 +133,26 @@ unsafe fn read_encoded_pointer(reader: &mut DwarfReader,
|
||||||
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
|
DW_EH_PE_sdata2 => reader.read::<i16>() as usize,
|
||||||
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
DW_EH_PE_sdata4 => reader.read::<i32>() as usize,
|
||||||
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
DW_EH_PE_sdata8 => reader.read::<i64>() as usize,
|
||||||
_ => panic!()
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
result += match encoding & 0x70 {
|
result += match encoding & 0x70 {
|
||||||
DW_EH_PE_absptr => 0,
|
DW_EH_PE_absptr => 0,
|
||||||
// relative to address of the encoded value, despite the name
|
// relative to address of the encoded value, despite the name
|
||||||
DW_EH_PE_pcrel => reader.ptr as usize,
|
DW_EH_PE_pcrel => reader.ptr as usize,
|
||||||
DW_EH_PE_textrel => { assert!(context.text_start != 0);
|
DW_EH_PE_textrel => {
|
||||||
context.text_start },
|
assert!(context.text_start != 0);
|
||||||
DW_EH_PE_datarel => { assert!(context.data_start != 0);
|
context.text_start
|
||||||
context.data_start },
|
}
|
||||||
DW_EH_PE_funcrel => { assert!(context.func_start != 0);
|
DW_EH_PE_datarel => {
|
||||||
context.func_start },
|
assert!(context.data_start != 0);
|
||||||
_ => panic!()
|
context.data_start
|
||||||
|
}
|
||||||
|
DW_EH_PE_funcrel => {
|
||||||
|
assert!(context.func_start != 0);
|
||||||
|
context.func_start
|
||||||
|
}
|
||||||
|
_ => panic!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
if encoding & DW_EH_PE_indirect != 0 {
|
if encoding & DW_EH_PE_indirect != 0 {
|
||||||
|
|
|
@ -21,25 +21,22 @@ pub mod eh;
|
||||||
use core::mem;
|
use core::mem;
|
||||||
|
|
||||||
pub struct DwarfReader {
|
pub struct DwarfReader {
|
||||||
pub ptr : *const u8
|
pub ptr: *const u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C,packed)]
|
#[repr(C,packed)]
|
||||||
struct Unaligned<T>(T);
|
struct Unaligned<T>(T);
|
||||||
|
|
||||||
impl DwarfReader {
|
impl DwarfReader {
|
||||||
|
pub fn new(ptr: *const u8) -> DwarfReader {
|
||||||
pub fn new(ptr : *const u8) -> DwarfReader {
|
DwarfReader { ptr: ptr }
|
||||||
DwarfReader {
|
|
||||||
ptr : ptr
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
|
// DWARF streams are packed, so e.g. a u32 would not necessarily be aligned
|
||||||
// on a 4-byte boundary. This may cause problems on platforms with strict
|
// on a 4-byte boundary. This may cause problems on platforms with strict
|
||||||
// alignment requirements. By wrapping data in a "packed" struct, we are
|
// alignment requirements. By wrapping data in a "packed" struct, we are
|
||||||
// telling the backend to generate "misalignment-safe" code.
|
// telling the backend to generate "misalignment-safe" code.
|
||||||
pub unsafe fn read<T:Copy>(&mut self) -> T {
|
pub unsafe fn read<T: Copy>(&mut self) -> T {
|
||||||
let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
|
let Unaligned(result) = *(self.ptr as *const Unaligned<T>);
|
||||||
self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
|
self.ptr = self.ptr.offset(mem::size_of::<T>() as isize);
|
||||||
result
|
result
|
||||||
|
@ -48,9 +45,9 @@ impl DwarfReader {
|
||||||
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
|
// ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable
|
||||||
// Length Data".
|
// Length Data".
|
||||||
pub unsafe fn read_uleb128(&mut self) -> u64 {
|
pub unsafe fn read_uleb128(&mut self) -> u64 {
|
||||||
let mut shift : usize = 0;
|
let mut shift: usize = 0;
|
||||||
let mut result : u64 = 0;
|
let mut result: u64 = 0;
|
||||||
let mut byte : u8;
|
let mut byte: u8;
|
||||||
loop {
|
loop {
|
||||||
byte = self.read::<u8>();
|
byte = self.read::<u8>();
|
||||||
result |= ((byte & 0x7F) as u64) << shift;
|
result |= ((byte & 0x7F) as u64) << shift;
|
||||||
|
@ -63,9 +60,9 @@ impl DwarfReader {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn read_sleb128(&mut self) -> i64 {
|
pub unsafe fn read_sleb128(&mut self) -> i64 {
|
||||||
let mut shift : usize = 0;
|
let mut shift: usize = 0;
|
||||||
let mut result : u64 = 0;
|
let mut result: u64 = 0;
|
||||||
let mut byte : u8;
|
let mut byte: u8;
|
||||||
loop {
|
loop {
|
||||||
byte = self.read::<u8>();
|
byte = self.read::<u8>();
|
||||||
result |= ((byte & 0x7F) as u64) << shift;
|
result |= ((byte & 0x7F) as u64) << shift;
|
||||||
|
@ -84,12 +81,7 @@ impl DwarfReader {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dwarf_reader() {
|
fn dwarf_reader() {
|
||||||
let encoded: &[u8] = &[1,
|
let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF];
|
||||||
2, 3,
|
|
||||||
4, 5, 6, 7,
|
|
||||||
0xE5, 0x8E, 0x26,
|
|
||||||
0x9B, 0xF1, 0x59,
|
|
||||||
0xFF, 0xFF];
|
|
||||||
|
|
||||||
let mut reader = DwarfReader::new(encoded.as_ptr());
|
let mut reader = DwarfReader::new(encoded.as_ptr());
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||||
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
|
let exception_param = Box::into_raw(exception) as *mut uw::_Unwind_Exception;
|
||||||
return uw::_Unwind_RaiseException(exception_param) as u32;
|
return uw::_Unwind_RaiseException(exception_param) as u32;
|
||||||
|
|
||||||
extern fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
extern "C" fn exception_cleanup(_unwind_code: uw::_Unwind_Reason_Code,
|
||||||
exception: *mut uw::_Unwind_Exception) {
|
exception: *mut uw::_Unwind_Exception) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
|
let _: Box<Exception> = Box::from_raw(exception as *mut Exception);
|
||||||
|
@ -130,7 +130,7 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_v0(version: c_int,
|
fn __gcc_personality_v0(version: c_int,
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
|
@ -141,39 +141,30 @@ pub mod eabi {
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern fn rust_eh_personality(
|
extern "C" fn rust_eh_personality(version: c_int,
|
||||||
version: c_int,
|
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||||
unsafe {
|
|
||||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||||
version: c_int,
|
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
|
||||||
|
|
||||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 {
|
||||||
|
// search phase
|
||||||
uw::_URC_HANDLER_FOUND // catch!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_v0(version, actions, exception_class, ue_header, context) }
|
||||||
__gcc_personality_v0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +177,7 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_sj0(version: c_int,
|
fn __gcc_personality_sj0(version: c_int,
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
|
@ -197,38 +188,29 @@ pub mod eabi {
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality(
|
pub extern "C" fn rust_eh_personality(version: c_int,
|
||||||
version: c_int,
|
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||||
unsafe {
|
|
||||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(version: c_int,
|
||||||
version: c_int,
|
|
||||||
actions: uw::_Unwind_Action,
|
actions: uw::_Unwind_Action,
|
||||||
exception_class: uw::_Unwind_Exception_Class,
|
exception_class: uw::_Unwind_Exception_Class,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 {
|
||||||
if (actions as c_int & uw::_UA_SEARCH_PHASE as c_int) != 0 { // search phase
|
// search phase
|
||||||
uw::_URC_HANDLER_FOUND // catch!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_sj0(version, actions, exception_class, ue_header, context) }
|
||||||
__gcc_personality_sj0(version, actions, exception_class, ue_header,
|
|
||||||
context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -241,7 +223,7 @@ pub mod eabi {
|
||||||
use unwind as uw;
|
use unwind as uw;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
fn __gcc_personality_v0(state: uw::_Unwind_State,
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context)
|
context: *mut uw::_Unwind_Context)
|
||||||
|
@ -250,38 +232,31 @@ pub mod eabi {
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
extern fn rust_eh_personality(
|
extern "C" fn rust_eh_personality(state: uw::_Unwind_State,
|
||||||
state: uw::_Unwind_State,
|
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||||
unsafe {
|
|
||||||
__gcc_personality_v0(state, ue_header, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn rust_eh_personality_catch(
|
pub extern "C" fn rust_eh_personality_catch(state: uw::_Unwind_State,
|
||||||
state: uw::_Unwind_State,
|
|
||||||
ue_header: *mut uw::_Unwind_Exception,
|
ue_header: *mut uw::_Unwind_Exception,
|
||||||
context: *mut uw::_Unwind_Context
|
context: *mut uw::_Unwind_Context)
|
||||||
) -> uw::_Unwind_Reason_Code
|
-> uw::_Unwind_Reason_Code {
|
||||||
{
|
|
||||||
// Backtraces on ARM will call the personality routine with
|
// Backtraces on ARM will call the personality routine with
|
||||||
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
// state == _US_VIRTUAL_UNWIND_FRAME | _US_FORCE_UNWIND. In those cases
|
||||||
// we want to continue unwinding the stack, otherwise all our backtraces
|
// we want to continue unwinding the stack, otherwise all our backtraces
|
||||||
// would end at __rust_try.
|
// would end at __rust_try.
|
||||||
if (state as c_int & uw::_US_ACTION_MASK as c_int)
|
if (state as c_int & uw::_US_ACTION_MASK as c_int) ==
|
||||||
== uw::_US_VIRTUAL_UNWIND_FRAME as c_int
|
uw::_US_VIRTUAL_UNWIND_FRAME as c_int &&
|
||||||
&& (state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 { // search phase
|
(state as c_int & uw::_US_FORCE_UNWIND as c_int) == 0 {
|
||||||
|
// search phase
|
||||||
uw::_URC_HANDLER_FOUND // catch!
|
uw::_URC_HANDLER_FOUND // catch!
|
||||||
}
|
} else {
|
||||||
else { // cleanup phase
|
// cleanup phase
|
||||||
unsafe {
|
unsafe { __gcc_personality_v0(state, ue_header, context) }
|
||||||
__gcc_personality_v0(state, ue_header, context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,7 +265,7 @@ pub mod eabi {
|
||||||
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
|
#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
|
||||||
#[lang = "eh_unwind_resume"]
|
#[lang = "eh_unwind_resume"]
|
||||||
#[unwind]
|
#[unwind]
|
||||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
||||||
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
|
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,21 +289,20 @@ unsafe extern fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
|
||||||
pub mod eh_frame_registry {
|
pub mod eh_frame_registry {
|
||||||
#[link(name = "gcc_eh")]
|
#[link(name = "gcc_eh")]
|
||||||
#[cfg(not(cargobuild))]
|
#[cfg(not(cargobuild))]
|
||||||
extern {}
|
extern "C" {}
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
fn __register_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||||
fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
fn __deregister_frame_info(eh_frame_begin: *const u8, object: *mut u8);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn rust_eh_register_frames(eh_frame_begin: *const u8,
|
pub unsafe extern "C" fn rust_eh_register_frames(eh_frame_begin: *const u8, object: *mut u8) {
|
||||||
object: *mut u8) {
|
|
||||||
__register_frame_info(eh_frame_begin, object);
|
__register_frame_info(eh_frame_begin, object);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
pub unsafe extern "C" fn rust_eh_unregister_frames(eh_frame_begin: *const u8,
|
||||||
object: *mut u8) {
|
object: *mut u8) {
|
||||||
__deregister_frame_info(eh_frame_begin, object);
|
__deregister_frame_info(eh_frame_begin, object);
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,7 @@ mod windows;
|
||||||
// hairy and tightly coupled, for more information see the compiler's
|
// hairy and tightly coupled, for more information see the compiler's
|
||||||
// implementation of this.
|
// implementation of this.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||||
data: *mut u8,
|
data: *mut u8,
|
||||||
data_ptr: *mut usize,
|
data_ptr: *mut usize,
|
||||||
vtable_ptr: *mut usize)
|
vtable_ptr: *mut usize)
|
||||||
|
@ -101,7 +101,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
|
||||||
// Entry point for raising an exception, just delegates to the platform-specific
|
// Entry point for raising an exception, just delegates to the platform-specific
|
||||||
// implementation.
|
// implementation.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
|
pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
|
||||||
imp::panic(mem::transmute(raw::TraitObject {
|
imp::panic(mem::transmute(raw::TraitObject {
|
||||||
data: data as *mut (),
|
data: data as *mut (),
|
||||||
vtable: vtable as *mut (),
|
vtable: vtable as *mut (),
|
||||||
|
|
|
@ -128,7 +128,7 @@ mod imp {
|
||||||
pub const NAME1: [u8; 7] = [b'.', b'P', b'E', b'A', b'_', b'K', 0];
|
pub const NAME1: [u8; 7] = [b'.', b'P', b'E', b'A', b'_', b'K', 0];
|
||||||
pub const NAME2: [u8; 7] = [b'.', b'P', b'E', b'A', b'X', 0, 0];
|
pub const NAME2: [u8; 7] = [b'.', b'P', b'E', b'A', b'X', 0, 0];
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
pub static __ImageBase: u8;
|
pub static __ImageBase: u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,10 +186,7 @@ static mut THROW_INFO: _ThrowInfo = _ThrowInfo {
|
||||||
|
|
||||||
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray {
|
static mut CATCHABLE_TYPE_ARRAY: _CatchableTypeArray = _CatchableTypeArray {
|
||||||
nCatchableTypes: 2,
|
nCatchableTypes: 2,
|
||||||
arrayOfCatchableTypes: [
|
arrayOfCatchableTypes: [ptr!(0), ptr!(0)],
|
||||||
ptr!(0),
|
|
||||||
ptr!(0),
|
|
||||||
],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static mut CATCHABLE_TYPE1: _CatchableType = _CatchableType {
|
static mut CATCHABLE_TYPE1: _CatchableType = _CatchableType {
|
||||||
|
@ -216,7 +213,7 @@ static mut CATCHABLE_TYPE2: _CatchableType = _CatchableType {
|
||||||
copy_function: ptr!(0),
|
copy_function: ptr!(0),
|
||||||
};
|
};
|
||||||
|
|
||||||
extern {
|
extern "C" {
|
||||||
// The leading `\x01` byte here is actually a magical signal to LLVM to
|
// The leading `\x01` byte here is actually a magical signal to LLVM to
|
||||||
// *not* apply any other mangling like prefixing with a `_` character.
|
// *not* apply any other mangling like prefixing with a `_` character.
|
||||||
//
|
//
|
||||||
|
|
|
@ -36,7 +36,7 @@ const RUST_PANIC: c::DWORD = ETYPE | (1 << 24) | MAGIC;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct PanicData {
|
struct PanicData {
|
||||||
data: Box<Any + Send>
|
data: Box<Any + Send>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
pub unsafe fn panic(data: Box<Any + Send>) -> u32 {
|
||||||
|
@ -82,30 +82,29 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box<Any + Send> {
|
||||||
|
|
||||||
#[lang = "eh_personality_catch"]
|
#[lang = "eh_personality_catch"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
unsafe extern fn rust_eh_personality_catch(
|
unsafe extern "C" fn rust_eh_personality_catch(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
|
||||||
establisherFrame: c::LPVOID,
|
establisherFrame: c::LPVOID,
|
||||||
contextRecord: *mut c::CONTEXT,
|
contextRecord: *mut c::CONTEXT,
|
||||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||||
) -> c::EXCEPTION_DISPOSITION
|
-> c::EXCEPTION_DISPOSITION {
|
||||||
{
|
rust_eh_personality(exceptionRecord,
|
||||||
rust_eh_personality(exceptionRecord, establisherFrame,
|
establisherFrame,
|
||||||
contextRecord, dispatcherContext)
|
contextRecord,
|
||||||
|
dispatcherContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lang = "eh_personality"]
|
#[lang = "eh_personality"]
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
unsafe extern fn rust_eh_personality(
|
unsafe extern "C" fn rust_eh_personality(exceptionRecord: *mut c::EXCEPTION_RECORD,
|
||||||
exceptionRecord: *mut c::EXCEPTION_RECORD,
|
|
||||||
establisherFrame: c::LPVOID,
|
establisherFrame: c::LPVOID,
|
||||||
contextRecord: *mut c::CONTEXT,
|
contextRecord: *mut c::CONTEXT,
|
||||||
dispatcherContext: *mut c::DISPATCHER_CONTEXT
|
dispatcherContext: *mut c::DISPATCHER_CONTEXT)
|
||||||
) -> c::EXCEPTION_DISPOSITION
|
-> c::EXCEPTION_DISPOSITION {
|
||||||
{
|
|
||||||
let er = &*exceptionRecord;
|
let er = &*exceptionRecord;
|
||||||
let dc = &*dispatcherContext;
|
let dc = &*dispatcherContext;
|
||||||
|
|
||||||
if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 { // we are in the dispatch phase
|
if er.ExceptionFlags & c::EXCEPTION_UNWIND == 0 {
|
||||||
|
// we are in the dispatch phase
|
||||||
if er.ExceptionCode == RUST_PANIC {
|
if er.ExceptionCode == RUST_PANIC {
|
||||||
if let Some(lpad) = find_landing_pad(dc) {
|
if let Some(lpad) = find_landing_pad(dc) {
|
||||||
c::RtlUnwindEx(establisherFrame,
|
c::RtlUnwindEx(establisherFrame,
|
||||||
|
@ -122,7 +121,7 @@ unsafe extern fn rust_eh_personality(
|
||||||
|
|
||||||
#[lang = "eh_unwind_resume"]
|
#[lang = "eh_unwind_resume"]
|
||||||
#[unwind]
|
#[unwind]
|
||||||
unsafe extern fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
|
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: c::LPVOID) -> ! {
|
||||||
let params = [panic_ctx as c::ULONG_PTR];
|
let params = [panic_ctx as c::ULONG_PTR];
|
||||||
c::RaiseException(RUST_PANIC,
|
c::RaiseException(RUST_PANIC,
|
||||||
c::EXCEPTION_NONCONTINUABLE,
|
c::EXCEPTION_NONCONTINUABLE,
|
||||||
|
@ -136,7 +135,7 @@ unsafe fn find_landing_pad(dc: &c::DISPATCHER_CONTEXT) -> Option<usize> {
|
||||||
ip: dc.ControlPc as usize,
|
ip: dc.ControlPc as usize,
|
||||||
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
func_start: dc.ImageBase as usize + (*dc.FunctionEntry).BeginAddress as usize,
|
||||||
text_start: dc.ImageBase as usize,
|
text_start: dc.ImageBase as usize,
|
||||||
data_start: 0
|
data_start: 0,
|
||||||
};
|
};
|
||||||
eh::find_landing_pad(dc.HandlerData, &eh_ctx)
|
eh::find_landing_pad(dc.HandlerData, &eh_ctx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
#![cfg(windows)]
|
#![cfg(windows)]
|
||||||
|
|
||||||
use libc::{c_void, c_ulong, c_long, c_ulonglong};
|
use libc::{c_long, c_ulong, c_ulonglong, c_void};
|
||||||
|
|
||||||
pub type DWORD = c_ulong;
|
pub type DWORD = c_ulong;
|
||||||
pub type LONG = c_long;
|
pub type LONG = c_long;
|
||||||
|
@ -25,8 +25,7 @@ pub const EXCEPTION_UNWINDING: DWORD = 0x2; // Unwind is in progress
|
||||||
pub const EXCEPTION_EXIT_UNWIND: DWORD = 0x4; // Exit unwind is in progress
|
pub const EXCEPTION_EXIT_UNWIND: DWORD = 0x4; // Exit unwind is in progress
|
||||||
pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20; // Target unwind in progress
|
pub const EXCEPTION_TARGET_UNWIND: DWORD = 0x20; // Target unwind in progress
|
||||||
pub const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
|
pub const EXCEPTION_COLLIDED_UNWIND: DWORD = 0x40; // Collided exception handler call
|
||||||
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING |
|
pub const EXCEPTION_UNWIND: DWORD = EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND |
|
||||||
EXCEPTION_EXIT_UNWIND |
|
|
||||||
EXCEPTION_TARGET_UNWIND |
|
EXCEPTION_TARGET_UNWIND |
|
||||||
EXCEPTION_COLLIDED_UNWIND;
|
EXCEPTION_COLLIDED_UNWIND;
|
||||||
|
|
||||||
|
@ -37,7 +36,7 @@ pub struct EXCEPTION_RECORD {
|
||||||
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
pub ExceptionRecord: *mut EXCEPTION_RECORD,
|
||||||
pub ExceptionAddress: LPVOID,
|
pub ExceptionAddress: LPVOID,
|
||||||
pub NumberParameters: DWORD,
|
pub NumberParameters: DWORD,
|
||||||
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS]
|
pub ExceptionInformation: [LPVOID; EXCEPTION_MAXIMUM_PARAMETERS],
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
@ -75,7 +74,7 @@ pub enum EXCEPTION_DISPOSITION {
|
||||||
ExceptionContinueExecution,
|
ExceptionContinueExecution,
|
||||||
ExceptionContinueSearch,
|
ExceptionContinueSearch,
|
||||||
ExceptionNestedException,
|
ExceptionNestedException,
|
||||||
ExceptionCollidedUnwind
|
ExceptionCollidedUnwind,
|
||||||
}
|
}
|
||||||
pub use self::EXCEPTION_DISPOSITION::*;
|
pub use self::EXCEPTION_DISPOSITION::*;
|
||||||
|
|
||||||
|
@ -93,6 +92,5 @@ extern "system" {
|
||||||
OriginalContext: *const CONTEXT,
|
OriginalContext: *const CONTEXT,
|
||||||
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
HistoryTable: *const UNWIND_HISTORY_TABLE);
|
||||||
#[unwind]
|
#[unwind]
|
||||||
pub fn _CxxThrowException(pExceptionObject: *mut c_void,
|
pub fn _CxxThrowException(pExceptionObject: *mut c_void, pThrowInfo: *mut u8);
|
||||||
pThrowInfo: *mut u8);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue