From f5f259453db80650c2533f1008457b4907c5fbea Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Apr 2019 14:16:36 +0200 Subject: [PATCH 1/6] Bump gimli to 0.18.0 --- unwind/Cargo.toml | 2 +- unwind/src/lib.rs | 27 +++++++++++---------------- unwind/src/unwind_helper.c | 1 - 3 files changed, 12 insertions(+), 18 deletions(-) diff --git a/unwind/Cargo.toml b/unwind/Cargo.toml index e8981b3..529a9d5 100644 --- a/unwind/Cargo.toml +++ b/unwind/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" authors = ["main() "] [dependencies] -gimli = "0.17" +gimli = "0.18" libc = "0.2" fallible-iterator = "0.1" log = "0.4" diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index 9ff16db..af787f1 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -46,7 +46,7 @@ struct ObjectRecord { pub struct DwarfUnwinder { cfi: Vec, - ctx: Option, StaticReader>>, + ctx: UninitializedUnwindContext, } impl Default for DwarfUnwinder { @@ -77,7 +77,7 @@ impl Default for DwarfUnwinder { DwarfUnwinder { cfi, - ctx: Some(UninitializedUnwindContext::new()), + ctx: UninitializedUnwindContext::new(), } } } @@ -96,28 +96,26 @@ struct UnwindInfo { personality: Option, lsda: Option, initial_address: u64, - ctx: UninitializedUnwindContext, StaticReader>, } impl ObjectRecord { - fn unwind_info_for_address(&self, - ctx: UninitializedUnwindContext, StaticReader>, - address: u64) -> gimli::Result> { + fn unwind_info_for_address( + &self, + ctx: &mut UninitializedUnwindContext, + address: u64, + ) -> gimli::Result> { let &ObjectRecord { ref eh_frame_hdr, - eh_frame: ref sel, + ref eh_frame, ref bases, .. } = self; let fde = eh_frame_hdr.table().unwrap() - .lookup_and_parse(address, bases, sel.clone(), |offset| sel.cie_from_offset(bases, offset))?; - + .fde_for_address(eh_frame, bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset))?; let mut result_row = None; - let mut ctx = ctx.initialize(fde.cie()).unwrap(); - { - let mut table = UnwindTable::new(&mut ctx, &fde); + let mut table = UnwindTable::new(eh_frame, bases, ctx, &fde)?; while let Some(row) = table.next_row()? { if row.contains(address) { result_row = Some(row.clone()); @@ -129,7 +127,6 @@ impl ObjectRecord { match result_row { Some(row) => Ok(UnwindInfo { row, - ctx: ctx.reset(), personality: fde.personality(), lsda: fde.lsda(), initial_address: fde.initial_address(), @@ -198,9 +195,7 @@ impl<'a> FallibleIterator for StackFrames<'a> { let rec = self.unwinder.cfi.iter().filter(|x| x.er.text.contains(caller)).next().ok_or(gimli::Error::NoUnwindInfoForAddress)?; - let ctx = self.unwinder.ctx.take().unwrap_or_else(UninitializedUnwindContext::new); - let UnwindInfo { row, personality, lsda, initial_address, ctx } = rec.unwind_info_for_address(ctx, caller)?; - self.unwinder.ctx = Some(ctx); + let UnwindInfo { row, personality, lsda, initial_address } = rec.unwind_info_for_address(&mut self.unwinder.ctx, caller)?; trace!("ok: {:?} (0x{:x} - 0x{:x})", row.cfa(), row.start_address(), row.end_address()); let cfa = match *row.cfa() { diff --git a/unwind/src/unwind_helper.c b/unwind/src/unwind_helper.c index 25c1ba4..3ffaf66 100644 --- a/unwind/src/unwind_helper.c +++ b/unwind/src/unwind_helper.c @@ -1,4 +1,3 @@ - asm ( ".global unwind_trampoline \n" "unwind_trampoline: \n" From 58e872979d2ff9dee5b4b20bd79e7af04147bcca Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Apr 2019 14:28:55 +0200 Subject: [PATCH 2/6] Add .travis.yml --- .travis.yml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9353e11 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,14 @@ +language: rust +cache: cargo + +os: + - linux +# - osx + +rust: stable + +script: + - cd unwind && cargo build && (cargo run --example demo || true) && cargo run --example trace + +env: +- RUST_BACKTRACE=pretty From 8182b21fe618a8ef5c9f982b02826f6a029b6dee Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 25 Apr 2019 16:32:38 +0200 Subject: [PATCH 3/6] Make some things public --- unwind/src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index af787f1..bb41496 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -9,7 +9,7 @@ extern crate fallible_iterator; use gimli::{UnwindSection, UnwindTable, UnwindTableRow, EhFrame, BaseAddresses, UninitializedUnwindContext, Pointer, Reader, EndianSlice, NativeEndian, CfaRule, RegisterRule, EhFrameHdr, ParsedEhFrameHdr, X86_64}; use fallible_iterator::FallibleIterator; -mod registers; +pub mod registers; mod find_cfi; mod range; pub mod libunwind_shim; @@ -26,9 +26,9 @@ pub struct StackFrames<'a> { #[derive(Debug)] pub struct StackFrame { - personality: Option, - lsda: Option, - initial_address: u64, + pub personality: Option, + pub lsda: Option, + pub initial_address: u64, } pub trait Unwinder: Default { From 27bacc57f059f93f6ca3ed54c9124ee4f6d93af5 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Apr 2019 14:37:21 +0200 Subject: [PATCH 4/6] Add getter methods --- unwind/src/lib.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index bb41496..26f2baa 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -26,9 +26,23 @@ pub struct StackFrames<'a> { #[derive(Debug)] pub struct StackFrame { - pub personality: Option, - pub lsda: Option, - pub initial_address: u64, + personality: Option, + lsda: Option, + initial_address: u64, +} + +impl StackFrame { + pub fn personality(&self) -> Option { + self.personality + } + + pub fn lsda(&self) -> Option { + self.lsda + } + + pub fn initial_address(&self) -> u64 { + self.initial_address + } } pub trait Unwinder: Default { From fc0eeb5c389317cdda8ce9261506c8732e672483 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Apr 2019 14:05:47 +0200 Subject: [PATCH 5/6] [WIP] Macos support --- unwind/Cargo.toml | 6 ++ unwind/src/find_cfi/baremetal.rs | 2 +- unwind/src/find_cfi/ld.rs | 2 +- unwind/src/find_cfi/macos.rs | 67 ++++++++++++++++++ unwind/src/find_cfi/mod.rs | 22 ++++-- unwind/src/lib.rs | 118 ++++++++++++++++++++++++------- unwind/src/unwind_helper.c | 10 +-- 7 files changed, 189 insertions(+), 38 deletions(-) create mode 100644 unwind/src/find_cfi/macos.rs diff --git a/unwind/Cargo.toml b/unwind/Cargo.toml index 529a9d5..36c33c7 100644 --- a/unwind/Cargo.toml +++ b/unwind/Cargo.toml @@ -9,6 +9,12 @@ libc = "0.2" fallible-iterator = "0.1" log = "0.4" +[target."cfg(target_os = \"macos\")".dependencies] +findshlibs = "0.4.0" +object = "0.11.0" +memmap = "0.7.0" +backtrace = "0.3.15" + [build-dependencies] gcc = "0.3.52" diff --git a/unwind/src/find_cfi/baremetal.rs b/unwind/src/find_cfi/baremetal.rs index 2e62a6b..3f72d96 100644 --- a/unwind/src/find_cfi/baremetal.rs +++ b/unwind/src/find_cfi/baremetal.rs @@ -24,7 +24,7 @@ pub fn find_cfi_sections() -> Vec { }; let eh_frame_end = &__ehframe_end as *const _ as u64; - cfi.push(EhRef { + cfi.push(EhRef::WithHeader { text, eh_frame_hdr, eh_frame_end, diff --git a/unwind/src/find_cfi/ld.rs b/unwind/src/find_cfi/ld.rs index 33240fd..709b796 100644 --- a/unwind/src/find_cfi/ld.rs +++ b/unwind/src/find_cfi/ld.rs @@ -65,7 +65,7 @@ extern "C" fn callback(info: *const DlPhdrInfo, size: usize, data: *mut c_void) .fold(0, |vaddr, x| cmp::max(vaddr, x.vaddr + x.memsz)); // This is an upper bound, not the exact address. let eh_frame_end = (*info).addr + max_vaddr; - (*data).push(EhRef { + (*data).push(EhRef::WithHeader { text: AddrRange { start: start_addr, end: start_addr + text.memsz }, eh_frame_hdr: AddrRange { start: eh_frame_hdr_start, end: eh_frame_hdr_start + eh_frame_hdr.memsz }, eh_frame_end, diff --git a/unwind/src/find_cfi/macos.rs b/unwind/src/find_cfi/macos.rs new file mode 100644 index 0000000..3a975bf --- /dev/null +++ b/unwind/src/find_cfi/macos.rs @@ -0,0 +1,67 @@ +extern crate findshlibs; +extern crate object; +extern crate memmap; + +use libc::{c_void, c_int, c_char}; +use std::ffi::CStr; +use std::{slice, mem, cmp}; +use range::AddrRange; +use super::EhRef; + +use self::findshlibs::{SharedLibrary, Segment}; +use self::object::{Object, ObjectSection}; + +extern "C" { + #[link_name = "\x01segment$start$__TEXT"] + static START_TEXT: usize; + #[link_name = "\x01segment$end$__TEXT"] + static STOP_TEXT: usize; + + #[link_name = "\x01section$start$__DATA$__eh_frame"] + static START_EHFRAME: usize; + #[link_name = "\x01section$end$__DATA$__eh_frame"] + static STOP_EHFRAME: usize; +} + +pub fn find_cfi_sections() -> Vec { + let mut cfi: Vec = Vec::new(); + + findshlibs::TargetSharedLibrary::each(|shlib| { + let text_seg = shlib.segments().find(|seg| seg.name() == CStr::from_bytes_with_nul(b"__TEXT\0").unwrap()).expect("No code in library???"); + + let text = AddrRange { + start: text_seg.actual_virtual_memory_address(shlib).0 as u64, + end: text_seg.actual_virtual_memory_address(shlib).0 as u64 + text_seg.len() as u64, + }; + + println!("{}", shlib.name().to_str().unwrap()); + + let file_bytes = unsafe { memmap::Mmap::map(&std::fs::File::open(shlib.name().to_str().unwrap()).unwrap()).unwrap() }; + + let object = match object::MachOFile::parse(&*file_bytes) { + Ok(object) => object, + Err(err) => { + if &file_bytes[0..4] == &[0xca, 0xfe, 0xba, 0xbe] { + println!("can't parse fat mach-O file"); + return; + } + + println!("{:?}", err); + return; + } + }; + + // FIXME fix memory leak + let eh_frame: &'static [u8] = Box::leak(object.section_data_by_name(".eh_frame").unwrap().into_owned().into_boxed_slice()); + + cfi.push(EhRef::WithoutHeader { + text, + eh_frame: AddrRange { start: eh_frame.as_ptr() as u64, end: eh_frame.as_ptr() as u64 + eh_frame.len() as u64 }, + }); + }); + + println!("{:#?}", cfi); + + trace!("CFI sections: {:?}", cfi); + cfi +} diff --git a/unwind/src/find_cfi/mod.rs b/unwind/src/find_cfi/mod.rs index 27b142a..ea8380c 100644 --- a/unwind/src/find_cfi/mod.rs +++ b/unwind/src/find_cfi/mod.rs @@ -1,16 +1,26 @@ use range::AddrRange; -#[derive(Debug)] -pub struct EhRef { - pub text: AddrRange, - pub eh_frame_hdr: AddrRange, - pub eh_frame_end: u64, +#[derive(Debug, Clone)] +pub enum EhRef { + WithHeader { + text: AddrRange, + eh_frame_hdr: AddrRange, + eh_frame_end: u64, + }, + WithoutHeader { + text: AddrRange, + eh_frame: AddrRange, + }, } -#[cfg(unix)] +#[cfg(all(unix, not(target_os = "macos")))] #[path = "ld.rs"] mod imp; +#[cfg(target_os = "macos")] +#[path = "macos.rs"] +mod imp; + #[cfg(not(unix))] #[path = "baremetal.rs"] mod imp; diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index 26f2baa..c7692ca 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -5,6 +5,7 @@ extern crate gimli; extern crate libc; extern crate fallible_iterator; #[macro_use] extern crate log; +extern crate backtrace; use gimli::{UnwindSection, UnwindTable, UnwindTableRow, EhFrame, BaseAddresses, UninitializedUnwindContext, Pointer, Reader, EndianSlice, NativeEndian, CfaRule, RegisterRule, EhFrameHdr, ParsedEhFrameHdr, X86_64}; use fallible_iterator::FallibleIterator; @@ -53,7 +54,7 @@ type StaticReader = EndianSlice<'static, NativeEndian>; struct ObjectRecord { er: EhRef, - eh_frame_hdr: ParsedEhFrameHdr, + eh_frame_hdr: Option>, eh_frame: EhFrame, bases: BaseAddresses, } @@ -66,26 +67,50 @@ pub struct DwarfUnwinder { impl Default for DwarfUnwinder { fn default() -> DwarfUnwinder { let cfi = find_cfi::find_cfi_sections().into_iter().map(|er| { - unsafe { - // TODO: set_got() - let bases = BaseAddresses::default() - .set_eh_frame_hdr(er.eh_frame_hdr.start) - .set_text(er.text.start); + match er { + EhRef::WithHeader { + text, + eh_frame_hdr, + eh_frame_end, + } => unsafe { + // TODO: set_got() + let bases = BaseAddresses::default() + .set_eh_frame_hdr(eh_frame_hdr.start) + .set_text(text.start); - let eh_frame_hdr: &'static [u8] = std::slice::from_raw_parts(er.eh_frame_hdr.start as *const u8, er.eh_frame_hdr.len() as usize); + let eh_frame_hdr: &'static [u8] = std::slice::from_raw_parts(eh_frame_hdr.start as *const u8, eh_frame_hdr.len() as usize); - let eh_frame_hdr = EhFrameHdr::new(eh_frame_hdr, NativeEndian).parse(&bases, 8).unwrap(); + let eh_frame_hdr = EhFrameHdr::new(eh_frame_hdr, NativeEndian).parse(&bases, 8).unwrap(); - let eh_frame_addr = deref_ptr(eh_frame_hdr.eh_frame_ptr()); - let eh_frame_sz = er.eh_frame_end.saturating_sub(eh_frame_addr); + let eh_frame_addr = deref_ptr(eh_frame_hdr.eh_frame_ptr()); + let eh_frame_sz = eh_frame_end.saturating_sub(eh_frame_addr); - let eh_frame: &'static [u8] = std::slice::from_raw_parts(eh_frame_addr as *const u8, eh_frame_sz as usize); - trace!("eh_frame at {:p} sz {:x}", eh_frame_addr as *const u8, eh_frame_sz); - let eh_frame = EhFrame::new(eh_frame, NativeEndian); + let eh_frame: &'static [u8] = std::slice::from_raw_parts(eh_frame_addr as *const u8, eh_frame_sz as usize); + trace!("eh_frame at {:p} sz {:x}", eh_frame_addr as *const u8, eh_frame_sz); + let eh_frame = EhFrame::new(eh_frame, NativeEndian); - let bases = bases.set_eh_frame(eh_frame_addr); + let bases = bases.set_eh_frame(eh_frame_addr); - ObjectRecord { er, eh_frame_hdr, eh_frame, bases } + ObjectRecord { er, eh_frame_hdr: Some(eh_frame_hdr), eh_frame, bases } + } + EhRef::WithoutHeader { + text, + eh_frame, + } => unsafe { + // TODO: set_got() + let bases = BaseAddresses::default() + .set_text(text.start); + + let eh_frame_addr = eh_frame.start as *const u8; + let eh_frame_sz = eh_frame.end as usize - eh_frame.start as usize; + let eh_frame: &'static [u8] = std::slice::from_raw_parts(eh_frame_addr, eh_frame_sz); + trace!("eh_frame at {:p} sz {:x}", eh_frame_addr as *const u8, eh_frame_sz); + let eh_frame = EhFrame::new(eh_frame, NativeEndian); + + let bases = bases.set_eh_frame(eh_frame_addr as u64); + + ObjectRecord { er, eh_frame_hdr: None, eh_frame, bases } + } } }).collect(); @@ -125,17 +150,50 @@ impl ObjectRecord { .. } = self; - let fde = eh_frame_hdr.table().unwrap() - .fde_for_address(eh_frame, bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset))?; + let fde; let mut result_row = None; - { - let mut table = UnwindTable::new(eh_frame, bases, ctx, &fde)?; - while let Some(row) = table.next_row()? { - if row.contains(address) { - result_row = Some(row.clone()); - break; + if let Some(eh_frame_hdr) = eh_frame_hdr { + fde = eh_frame_hdr.table().unwrap() + .fde_for_address(eh_frame, bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset))?; + + { + let mut table = UnwindTable::new(eh_frame, bases, ctx, &fde)?; + while let Some(row) = table.next_row()? { + if row.contains(address) { + result_row = Some(row.clone()); + break; + } + } + } + } else { + use gimli::UnwindSection; + + let mut entries = eh_frame.entries(bases); + backtrace::resolve(address as *mut _, |s| { + println!("address {:016x}: {:?}", address, s.name()); + let (text, eh_frame) = match self.er { EhRef::WithoutHeader { text, eh_frame, .. } => (text, eh_frame), _ => panic!() }; + println!("bases {:?}", bases); + println!("text {:016x} .. {:016x}", text.start, text.end); + println!("eh_frame {:016x} .. {:016x}", eh_frame.start, eh_frame.end); + }); + while let Some(entry) = entries.next()? { + match entry { + gimli::CieOrFde::Cie(_) => {} + gimli::CieOrFde::Fde(partial) => { + let fde = partial.parse(|eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset)).unwrap(); + println!("fde {:016x} .. {:016x}", fde.initial_address(), fde.initial_address() + fde.len()); + //println!("{:?}", fde); + } } } + + fde = eh_frame.fde_for_address(bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset)).unwrap(); + result_row = Some(eh_frame.unwind_info_for_address( + bases, + ctx, + address, + |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset), + )?); } match result_row { @@ -145,7 +203,7 @@ impl ObjectRecord { lsda: fde.lsda(), initial_address: fde.initial_address(), }), - None => Err(gimli::Error::NoUnwindInfoForAddress) + None => panic!(), } } } @@ -207,7 +265,17 @@ impl<'a> FallibleIterator for StackFrames<'a> { caller -= 1; // THIS IS NECESSARY debug!("caller is 0x{:x}", caller); - let rec = self.unwinder.cfi.iter().filter(|x| x.er.text.contains(caller)).next().ok_or(gimli::Error::NoUnwindInfoForAddress)?; + println!("{:?}, {:?}", caller, self.unwinder.cfi.iter().map(|x| x.er.clone()).collect::>()); + + let rec = self.unwinder.cfi + .iter() + .filter(|x| match x.er { + EhRef::WithoutHeader { text, .. } | EhRef::WithHeader { text, .. } => text.contains(caller), + }) + .next() + .ok_or(gimli::Error::NoUnwindInfoForAddress)?; + + println!("found"); let UnwindInfo { row, personality, lsda, initial_address } = rec.unwind_info_for_address(&mut self.unwinder.ctx, caller)?; diff --git a/unwind/src/unwind_helper.c b/unwind/src/unwind_helper.c index 3ffaf66..c095c3b 100644 --- a/unwind/src/unwind_helper.c +++ b/unwind/src/unwind_helper.c @@ -1,6 +1,6 @@ asm ( - ".global unwind_trampoline \n" - "unwind_trampoline: \n" + ".global _unwind_trampoline \n" + "_unwind_trampoline: \n" ".cfi_startproc \n" "movq %rsp, %rsi \n" ".cfi_def_cfa rsi, 8 \n" @@ -14,7 +14,7 @@ asm ( "movq %rsp, %rdx \n" "subq $0x08, %rsp \n" ".cfi_def_cfa rsp, 0x40 \n" - "call unwind_recorder \n" + "call _unwind_recorder \n" "addq $0x38, %rsp \n" ".cfi_def_cfa rsp, 8 \n" "ret \n" @@ -22,8 +22,8 @@ asm ( ); asm ( - ".global unwind_lander \n" - "unwind_lander: \n" + ".global _unwind_lander \n" + "_unwind_lander: \n" "movq %rdi, %rsp \n" "popq %rax \n" "popq %rbx \n" From d15b86331a90203a1d37ac32d8060c153b4987af Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 27 Apr 2019 15:04:44 +0200 Subject: [PATCH 6/6] [WIP] --- unwind/Cargo.toml | 2 +- unwind/src/find_cfi/macos.rs | 5 ++- unwind/src/lib.rs | 68 +++++++++++++++--------------------- unwind/src/unwind_helper.c | 10 +++--- 4 files changed, 37 insertions(+), 48 deletions(-) diff --git a/unwind/Cargo.toml b/unwind/Cargo.toml index 36c33c7..cc17a77 100644 --- a/unwind/Cargo.toml +++ b/unwind/Cargo.toml @@ -8,12 +8,12 @@ gimli = "0.18" libc = "0.2" fallible-iterator = "0.1" log = "0.4" +backtrace = "0.3.15" [target."cfg(target_os = \"macos\")".dependencies] findshlibs = "0.4.0" object = "0.11.0" memmap = "0.7.0" -backtrace = "0.3.15" [build-dependencies] gcc = "0.3.52" diff --git a/unwind/src/find_cfi/macos.rs b/unwind/src/find_cfi/macos.rs index 3a975bf..abc76a0 100644 --- a/unwind/src/find_cfi/macos.rs +++ b/unwind/src/find_cfi/macos.rs @@ -34,18 +34,17 @@ pub fn find_cfi_sections() -> Vec { end: text_seg.actual_virtual_memory_address(shlib).0 as u64 + text_seg.len() as u64, }; - println!("{}", shlib.name().to_str().unwrap()); - let file_bytes = unsafe { memmap::Mmap::map(&std::fs::File::open(shlib.name().to_str().unwrap()).unwrap()).unwrap() }; let object = match object::MachOFile::parse(&*file_bytes) { Ok(object) => object, Err(err) => { if &file_bytes[0..4] == &[0xca, 0xfe, 0xba, 0xbe] { - println!("can't parse fat mach-O file"); + //println!("can't parse fat mach-O file"); return; } + println!("{}", shlib.name().to_str().unwrap()); println!("{:?}", err); return; } diff --git a/unwind/src/lib.rs b/unwind/src/lib.rs index c7692ca..89552d4 100644 --- a/unwind/src/lib.rs +++ b/unwind/src/lib.rs @@ -152,50 +152,40 @@ impl ObjectRecord { let fde; let mut result_row = None; - if let Some(eh_frame_hdr) = eh_frame_hdr { - fde = eh_frame_hdr.table().unwrap() - .fde_for_address(eh_frame, bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset))?; - - { - let mut table = UnwindTable::new(eh_frame, bases, ctx, &fde)?; - while let Some(row) = table.next_row()? { - if row.contains(address) { - result_row = Some(row.clone()); - break; - } + use gimli::UnwindSection; + + let mut entries = eh_frame.entries(bases); + backtrace::resolve(address as *mut _, |s| { + println!("address {:016x}: {:?}", address, s.name()); + let (text, eh_frame) = match self.er { EhRef::WithoutHeader { text, eh_frame, .. } => (text, eh_frame), _ => panic!() }; + println!("bases {:?}", bases); + println!("text {:016x} .. {:016x}", text.start, text.end); + println!("eh_frame {:016x} .. {:016x}", eh_frame.start, eh_frame.end); + }); + let mut i = 0; + while let Some(entry) = entries.next()? { + match entry { + gimli::CieOrFde::Cie(_) => {} + gimli::CieOrFde::Fde(partial) => { + let fde = partial.parse(EhFrame::cie_from_offset).unwrap(); + println!("fde {:016x} .. {:016x}", fde.initial_address(), fde.initial_address() + fde.len()); + //println!("{:?}", fde); } } - } else { - use gimli::UnwindSection; - - let mut entries = eh_frame.entries(bases); - backtrace::resolve(address as *mut _, |s| { - println!("address {:016x}: {:?}", address, s.name()); - let (text, eh_frame) = match self.er { EhRef::WithoutHeader { text, eh_frame, .. } => (text, eh_frame), _ => panic!() }; - println!("bases {:?}", bases); - println!("text {:016x} .. {:016x}", text.start, text.end); - println!("eh_frame {:016x} .. {:016x}", eh_frame.start, eh_frame.end); - }); - while let Some(entry) = entries.next()? { - match entry { - gimli::CieOrFde::Cie(_) => {} - gimli::CieOrFde::Fde(partial) => { - let fde = partial.parse(|eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset)).unwrap(); - println!("fde {:016x} .. {:016x}", fde.initial_address(), fde.initial_address() + fde.len()); - //println!("{:?}", fde); - } - } + i += 1; + if i > 10 { + break; } - - fde = eh_frame.fde_for_address(bases, address, |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset)).unwrap(); - result_row = Some(eh_frame.unwind_info_for_address( - bases, - ctx, - address, - |eh_frame, bases, offset| eh_frame.cie_from_offset(bases, offset), - )?); } + fde = eh_frame.fde_for_address(bases, address, EhFrame::cie_from_offset).unwrap(); + result_row = Some(eh_frame.unwind_info_for_address( + bases, + ctx, + address, + EhFrame::cie_from_offset, + )?); + match result_row { Some(row) => Ok(UnwindInfo { row, diff --git a/unwind/src/unwind_helper.c b/unwind/src/unwind_helper.c index c095c3b..3ffaf66 100644 --- a/unwind/src/unwind_helper.c +++ b/unwind/src/unwind_helper.c @@ -1,6 +1,6 @@ asm ( - ".global _unwind_trampoline \n" - "_unwind_trampoline: \n" + ".global unwind_trampoline \n" + "unwind_trampoline: \n" ".cfi_startproc \n" "movq %rsp, %rsi \n" ".cfi_def_cfa rsi, 8 \n" @@ -14,7 +14,7 @@ asm ( "movq %rsp, %rdx \n" "subq $0x08, %rsp \n" ".cfi_def_cfa rsp, 0x40 \n" - "call _unwind_recorder \n" + "call unwind_recorder \n" "addq $0x38, %rsp \n" ".cfi_def_cfa rsp, 8 \n" "ret \n" @@ -22,8 +22,8 @@ asm ( ); asm ( - ".global _unwind_lander \n" - "_unwind_lander: \n" + ".global unwind_lander \n" + "unwind_lander: \n" "movq %rdi, %rsp \n" "popq %rax \n" "popq %rbx \n"