mirror of
https://github.com/Noratrieb/uwuwind.git
synced 2026-01-14 08:35:09 +01:00
more
This commit is contained in:
parent
d1e561c665
commit
598ddadc6b
4 changed files with 40 additions and 16 deletions
|
|
@ -30,9 +30,9 @@ extern "C" {
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct DwarfInfo {
|
pub struct DwarfInfo {
|
||||||
/// The text segment
|
/// The text segment
|
||||||
map: *const [u8],
|
pub(super) map: *const [u8],
|
||||||
/// PT_GNU_EH_FRAME
|
/// PT_GNU_EH_FRAME
|
||||||
dwarf: *const u8,
|
pub(super) dwarf: *const u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dwarf_info(addr: *const ffi::c_void) -> Option<DwarfInfo> {
|
pub fn dwarf_info(addr: *const ffi::c_void) -> Option<DwarfInfo> {
|
||||||
|
|
|
||||||
|
|
@ -8,4 +8,6 @@ mod parse;
|
||||||
|
|
||||||
pub use divination::{dwarf_info, DwarfInfo};
|
pub use divination::{dwarf_info, DwarfInfo};
|
||||||
|
|
||||||
pub fn uwutables(_dwarf_info: DwarfInfo) {}
|
pub fn uwutables(dwarf_info: DwarfInfo) {
|
||||||
|
trace!("getting uwutables from {:p}", dwarf_info.dwarf);
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,10 @@
|
||||||
//! and the rule to find the value for the previous frame.
|
//! and the rule to find the value for the previous frame.
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
struct Expr;
|
#[derive(Debug)]
|
||||||
|
pub struct Expr;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum RegisterRule {
|
enum RegisterRule {
|
||||||
/// A register that has this rule has no recoverable value in the previous frame.
|
/// A register that has this rule has no recoverable value in the previous frame.
|
||||||
/// (By convention, it is not preserved by a callee.)
|
/// (By convention, it is not preserved by a callee.)
|
||||||
|
|
@ -52,13 +54,15 @@ enum RegisterRule {
|
||||||
|
|
||||||
type Id = u32;
|
type Id = u32;
|
||||||
|
|
||||||
struct ULeb128(u128);
|
#[derive(Debug)]
|
||||||
|
pub struct ULeb128(u128);
|
||||||
impl ULeb128 {
|
impl ULeb128 {
|
||||||
fn parse() -> Self {
|
fn parse() -> Self {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
struct ILeb128(i128);
|
#[derive(Debug)]
|
||||||
|
pub struct ILeb128(i128);
|
||||||
impl ILeb128 {
|
impl ILeb128 {
|
||||||
fn parse() -> Self {
|
fn parse() -> Self {
|
||||||
todo!()
|
todo!()
|
||||||
|
|
@ -139,7 +143,8 @@ struct Fde<'a> {
|
||||||
instructions: &'a [u8],
|
instructions: &'a [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Instruction {
|
#[derive(Debug)]
|
||||||
|
pub enum Instruction {
|
||||||
//-------- 6.4.2.1 Row Creation Instructions
|
//-------- 6.4.2.1 Row Creation Instructions
|
||||||
//
|
//
|
||||||
/// The DW_CFA_set_loc instruction takes a single operand that represents a
|
/// The DW_CFA_set_loc instruction takes a single operand that represents a
|
||||||
|
|
@ -318,16 +323,32 @@ enum Instruction {
|
||||||
Nop,
|
Nop,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct InstrIter<'a> {
|
pub(super) struct InstrIter {
|
||||||
data: &'a [u8],
|
data: *const u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InstrIter {
|
||||||
|
/// Create a new `InstrIter` that will parse DWARF call frame information from `data`.
|
||||||
|
/// # Safety
|
||||||
|
/// `data` must be a pointer to valid DWARF call frame information with a null terminator.
|
||||||
|
pub(super) unsafe fn new(data: *const u8) -> Self {
|
||||||
|
Self { data }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> InstrIter<'a> {
|
|
||||||
fn advance(&mut self) -> Option<u8> {
|
fn advance(&mut self) -> Option<u8> {
|
||||||
let (&first, rest) = self.data.split_first()?;
|
// SAFETY: First, we assume that `data` currently points at a valid location.
|
||||||
self.data = rest;
|
// After we read from it, we increment it. This has implications. We must assume
|
||||||
|
// that the dwarf parsing code in this module never calls `advance` more than it has to.
|
||||||
|
// This means that really `advance` should be unsafe, but marking it as unsafe would only make
|
||||||
|
// the code in here harder to read and not provide practical safety improvements.
|
||||||
|
// We do eagerly move the data pointer outside the bounds of the allocation, but only one
|
||||||
|
// past the end, which is fine.
|
||||||
|
unsafe {
|
||||||
|
let first = self.data.read();
|
||||||
|
self.data = self.data.add(1);
|
||||||
Some(first)
|
Some(first)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn uleb128(&mut self) -> ULeb128 {
|
fn uleb128(&mut self) -> ULeb128 {
|
||||||
ULeb128::parse()
|
ULeb128::parse()
|
||||||
|
|
@ -364,9 +385,10 @@ const DW_CFA_val_expression: u8 = 0x16;
|
||||||
const DW_CFA_lo_user: u8 = 0x1c;
|
const DW_CFA_lo_user: u8 = 0x1c;
|
||||||
const DW_CFA_hi_user: u8 = 0x3f;
|
const DW_CFA_hi_user: u8 = 0x3f;
|
||||||
|
|
||||||
impl<'a> Iterator for InstrIter<'a> {
|
impl Iterator for InstrIter {
|
||||||
type Item = Instruction;
|
type Item = Instruction;
|
||||||
|
|
||||||
|
#[allow(unreachable_code)]
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
let b = self.advance()?;
|
let b = self.advance()?;
|
||||||
let high_2 = b & !(u8::MAX >> 2);
|
let high_2 = b & !(u8::MAX >> 2);
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ pub unsafe extern "C" fn _UnwindRaiseException(
|
||||||
exception_object: *mut uw::_Unwind_Exception,
|
exception_object: *mut uw::_Unwind_Exception,
|
||||||
) -> uw::_Unwind_Reason_Code {
|
) -> uw::_Unwind_Reason_Code {
|
||||||
trace!("someone raised an exception with addr {exception_object:p}");
|
trace!("someone raised an exception with addr {exception_object:p}");
|
||||||
crate::dwarf::dwarf_info(arch::get_rip() as _);
|
let di = crate::dwarf::dwarf_info(arch::get_rip() as _).unwrap();
|
||||||
|
crate::dwarf::uwutables(di);
|
||||||
// walk::fp::walk();
|
// walk::fp::walk();
|
||||||
|
|
||||||
stdext::abort();
|
stdext::abort();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue