From 246f239d9f40f633160f0c18f87a20922d4e77bb Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:06:37 +0200 Subject: Merging debian version 1.65.0+dfsg1-2. Signed-off-by: Daniel Baumann --- library/panic_unwind/src/dwarf/eh.rs | 192 -------------------------------- library/panic_unwind/src/dwarf/mod.rs | 73 ------------ library/panic_unwind/src/dwarf/tests.rs | 19 ---- 3 files changed, 284 deletions(-) delete mode 100644 library/panic_unwind/src/dwarf/eh.rs delete mode 100644 library/panic_unwind/src/dwarf/mod.rs delete mode 100644 library/panic_unwind/src/dwarf/tests.rs (limited to 'library/panic_unwind/src/dwarf') diff --git a/library/panic_unwind/src/dwarf/eh.rs b/library/panic_unwind/src/dwarf/eh.rs deleted file mode 100644 index 7394feab8..000000000 --- a/library/panic_unwind/src/dwarf/eh.rs +++ /dev/null @@ -1,192 +0,0 @@ -//! Parsing of GCC-style Language-Specific Data Area (LSDA) -//! For details see: -//! * -//! * -//! * -//! * -//! -//! A reference implementation may be found in the GCC source tree -//! (`/libgcc/unwind-c.c` as of this writing). - -#![allow(non_upper_case_globals)] -#![allow(unused)] - -use crate::dwarf::DwarfReader; -use core::mem; - -pub const DW_EH_PE_omit: u8 = 0xFF; -pub const DW_EH_PE_absptr: u8 = 0x00; - -pub const DW_EH_PE_uleb128: u8 = 0x01; -pub const DW_EH_PE_udata2: u8 = 0x02; -pub const DW_EH_PE_udata4: u8 = 0x03; -pub const DW_EH_PE_udata8: u8 = 0x04; -pub const DW_EH_PE_sleb128: u8 = 0x09; -pub const DW_EH_PE_sdata2: u8 = 0x0A; -pub const DW_EH_PE_sdata4: u8 = 0x0B; -pub const DW_EH_PE_sdata8: u8 = 0x0C; - -pub const DW_EH_PE_pcrel: u8 = 0x10; -pub const DW_EH_PE_textrel: u8 = 0x20; -pub const DW_EH_PE_datarel: u8 = 0x30; -pub const DW_EH_PE_funcrel: u8 = 0x40; -pub const DW_EH_PE_aligned: u8 = 0x50; - -pub const DW_EH_PE_indirect: u8 = 0x80; - -#[derive(Copy, Clone)] -pub struct EHContext<'a> { - pub ip: usize, // Current instruction pointer - pub func_start: usize, // Address of the current function - pub get_text_start: &'a dyn Fn() -> usize, // Get address of the code section - pub get_data_start: &'a dyn Fn() -> usize, // Get address of the data section -} - -pub enum EHAction { - None, - Cleanup(usize), - Catch(usize), - Terminate, -} - -pub const USING_SJLJ_EXCEPTIONS: bool = cfg!(all(target_os = "ios", target_arch = "arm")); - -pub unsafe fn find_eh_action(lsda: *const u8, context: &EHContext<'_>) -> Result { - if lsda.is_null() { - return Ok(EHAction::None); - } - - let func_start = context.func_start; - let mut reader = DwarfReader::new(lsda); - - let start_encoding = reader.read::(); - // 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 ttype_encoding = reader.read::(); - 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::(); - let call_site_table_length = reader.read_uleb128(); - let action_table = reader.ptr.offset(call_site_table_length as isize); - let ip = context.ip; - - if !USING_SJLJ_EXCEPTIONS { - while reader.ptr < action_table { - let cs_start = read_encoded_pointer(&mut reader, context, call_site_encoding)?; - let cs_len = read_encoded_pointer(&mut reader, context, call_site_encoding)?; - let cs_lpad = read_encoded_pointer(&mut reader, context, call_site_encoding)?; - let cs_action = 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 + cs_start { - break; - } - if ip < func_start + cs_start + cs_len { - if cs_lpad == 0 { - return Ok(EHAction::None); - } else { - let lpad = lpad_base + cs_lpad; - return Ok(interpret_cs_action(cs_action, lpad)); - } - } - } - // Ip is not present in the table. This should not happen... but it does: issue #35011. - // So rather than returning EHAction::Terminate, we do this. - Ok(EHAction::None) - } else { - // SjLj version: - // The "IP" is an index into the call-site table, with two exceptions: - // -1 means 'no-action', and 0 means 'terminate'. - match ip as isize { - -1 => return Ok(EHAction::None), - 0 => return Ok(EHAction::Terminate), - _ => (), - } - let mut idx = ip; - loop { - let cs_lpad = reader.read_uleb128(); - let cs_action = 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. - let lpad = (cs_lpad + 1) as usize; - return Ok(interpret_cs_action(cs_action, lpad)); - } - } - } -} - -fn interpret_cs_action(cs_action: u64, lpad: usize) -> EHAction { - if cs_action == 0 { - // If cs_action is 0 then this is a cleanup (Drop::drop). We run these - // for both Rust panics and foreign exceptions. - EHAction::Cleanup(lpad) - } else { - // Stop unwinding Rust panics at catch_unwind. - EHAction::Catch(lpad) - } -} - -#[inline] -fn round_up(unrounded: usize, align: usize) -> Result { - if align.is_power_of_two() { Ok((unrounded + align - 1) & !(align - 1)) } else { Err(()) } -} - -unsafe fn read_encoded_pointer( - reader: &mut DwarfReader, - context: &EHContext<'_>, - encoding: u8, -) -> Result { - if encoding == DW_EH_PE_omit { - return Err(()); - } - - // DW_EH_PE_aligned implies it's an absolute pointer value - if encoding == DW_EH_PE_aligned { - reader.ptr = round_up(reader.ptr as usize, mem::size_of::())? as *const u8; - return Ok(reader.read::()); - } - - let mut result = match encoding & 0x0F { - DW_EH_PE_absptr => reader.read::(), - DW_EH_PE_uleb128 => reader.read_uleb128() as usize, - DW_EH_PE_udata2 => reader.read::() as usize, - DW_EH_PE_udata4 => reader.read::() as usize, - DW_EH_PE_udata8 => reader.read::() as usize, - DW_EH_PE_sleb128 => reader.read_sleb128() as usize, - DW_EH_PE_sdata2 => reader.read::() as usize, - DW_EH_PE_sdata4 => reader.read::() as usize, - DW_EH_PE_sdata8 => reader.read::() as usize, - _ => return Err(()), - }; - - result += match encoding & 0x70 { - DW_EH_PE_absptr => 0, - // relative to address of the encoded value, despite the name - DW_EH_PE_pcrel => reader.ptr as usize, - DW_EH_PE_funcrel => { - if context.func_start == 0 { - return Err(()); - } - context.func_start - } - DW_EH_PE_textrel => (*context.get_text_start)(), - DW_EH_PE_datarel => (*context.get_data_start)(), - _ => return Err(()), - }; - - if encoding & DW_EH_PE_indirect != 0 { - result = *(result as *const usize); - } - - Ok(result) -} diff --git a/library/panic_unwind/src/dwarf/mod.rs b/library/panic_unwind/src/dwarf/mod.rs deleted file mode 100644 index 652fbe95a..000000000 --- a/library/panic_unwind/src/dwarf/mod.rs +++ /dev/null @@ -1,73 +0,0 @@ -//! Utilities for parsing DWARF-encoded data streams. -//! See , -//! DWARF-4 standard, Section 7 - "Data Representation" - -// This module is used only by x86_64-pc-windows-gnu for now, but we -// are compiling it everywhere to avoid regressions. -#![allow(unused)] - -#[cfg(test)] -mod tests; - -pub mod eh; - -use core::mem; - -pub struct DwarfReader { - pub ptr: *const u8, -} - -#[repr(C, packed)] -struct Unaligned(T); - -impl DwarfReader { - pub fn new(ptr: *const u8) -> DwarfReader { - DwarfReader { ptr } - } - - // 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 - // alignment requirements. By wrapping data in a "packed" struct, we are - // telling the backend to generate "misalignment-safe" code. - pub unsafe fn read(&mut self) -> T { - let Unaligned(result) = *(self.ptr as *const Unaligned); - self.ptr = self.ptr.add(mem::size_of::()); - result - } - - // ULEB128 and SLEB128 encodings are defined in Section 7.6 - "Variable - // Length Data". - pub unsafe fn read_uleb128(&mut self) -> u64 { - let mut shift: usize = 0; - let mut result: u64 = 0; - let mut byte: u8; - loop { - byte = self.read::(); - result |= ((byte & 0x7F) as u64) << shift; - shift += 7; - if byte & 0x80 == 0 { - break; - } - } - result - } - - pub unsafe fn read_sleb128(&mut self) -> i64 { - let mut shift: u32 = 0; - let mut result: u64 = 0; - let mut byte: u8; - loop { - byte = self.read::(); - result |= ((byte & 0x7F) as u64) << shift; - shift += 7; - if byte & 0x80 == 0 { - break; - } - } - // sign-extend - if shift < u64::BITS && (byte & 0x40) != 0 { - result |= (!0 as u64) << shift; - } - result as i64 - } -} diff --git a/library/panic_unwind/src/dwarf/tests.rs b/library/panic_unwind/src/dwarf/tests.rs deleted file mode 100644 index 1644f3708..000000000 --- a/library/panic_unwind/src/dwarf/tests.rs +++ /dev/null @@ -1,19 +0,0 @@ -use super::*; - -#[test] -fn dwarf_reader() { - let encoded: &[u8] = &[1, 2, 3, 4, 5, 6, 7, 0xE5, 0x8E, 0x26, 0x9B, 0xF1, 0x59, 0xFF, 0xFF]; - - let mut reader = DwarfReader::new(encoded.as_ptr()); - - unsafe { - assert!(reader.read::() == u8::to_be(1u8)); - assert!(reader.read::() == u16::to_be(0x0203)); - assert!(reader.read::() == u32::to_be(0x04050607)); - - assert!(reader.read_uleb128() == 624485); - assert!(reader.read_sleb128() == -624485); - - assert!(reader.read::() == i8::to_be(-1)); - } -} -- cgit v1.2.3