aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/sys/windows/backtrace/mod.rs
diff options
context:
space:
mode:
authorVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
committerVivian Lim <[email protected]>2021-02-06 22:11:59 -0800
commit64423f0e34cc4a7d78c15b345b3b8f58243d8286 (patch)
treecc20e2e7f0fc35abf470e20e61d3d48f0d954f3b /ctr-std/src/sys/windows/backtrace/mod.rs
parentSupport libctru 2.0 (diff)
downloadarchived-ctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.tar.xz
archived-ctru-rs-64423f0e34cc4a7d78c15b345b3b8f58243d8286.zip
Delete ctr-std to use my fork of the rust repo instead
Diffstat (limited to 'ctr-std/src/sys/windows/backtrace/mod.rs')
-rw-r--r--ctr-std/src/sys/windows/backtrace/mod.rs326
1 files changed, 0 insertions, 326 deletions
diff --git a/ctr-std/src/sys/windows/backtrace/mod.rs b/ctr-std/src/sys/windows/backtrace/mod.rs
deleted file mode 100644
index f64cae8..0000000
--- a/ctr-std/src/sys/windows/backtrace/mod.rs
+++ /dev/null
@@ -1,326 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! As always, windows has something very different than unix, we mainly want
-//! to avoid having to depend too much on libunwind for windows.
-//!
-//! If you google around, you'll find a fair bit of references to built-in
-//! functions to get backtraces on windows. It turns out that most of these are
-//! in an external library called dbghelp. I was unable to find this library
-//! via `-ldbghelp`, but it is apparently normal to do the `dlopen` equivalent
-//! of it.
-//!
-//! You'll also find that there's a function called CaptureStackBackTrace
-//! mentioned frequently (which is also easy to use), but sadly I didn't have a
-//! copy of that function in my mingw install (maybe it was broken?). Instead,
-//! this takes the route of using StackWalk64 in order to walk the stack.
-
-#![allow(deprecated)] // dynamic_lib
-
-use io;
-use libc::c_void;
-use mem;
-use ptr;
-use sys::c;
-use sys::dynamic_lib::DynamicLibrary;
-use sys_common::backtrace::Frame;
-
-macro_rules! sym {
- ($lib:expr, $e:expr, $t:ident) => (
- $lib.symbol($e).map(|f| unsafe {
- $crate::mem::transmute::<usize, $t>(f)
- })
- )
-}
-
-mod printing;
-
-#[cfg(target_env = "gnu")]
-#[path = "backtrace_gnu.rs"]
-pub mod gnu;
-
-pub use self::printing::{foreach_symbol_fileline, resolve_symname};
-use self::printing::{load_printing_fns_64, load_printing_fns_ex};
-
-pub fn unwind_backtrace(frames: &mut [Frame]) -> io::Result<(usize, BacktraceContext)> {
- let dbghelp = DynamicLibrary::open("dbghelp.dll")?;
-
- // Fetch the symbols necessary from dbghelp.dll
- let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn)?;
- let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn)?;
-
- // StackWalkEx might not be present and we'll fall back to StackWalk64
- let sw_var = match sym!(dbghelp, "StackWalkEx", StackWalkExFn) {
- Ok(StackWalkEx) => {
- StackWalkVariant::StackWalkEx(StackWalkEx, load_printing_fns_ex(&dbghelp)?)
- }
- Err(e) => match sym!(dbghelp, "StackWalk64", StackWalk64Fn) {
- Ok(StackWalk64) => {
- StackWalkVariant::StackWalk64(StackWalk64, load_printing_fns_64(&dbghelp)?)
- }
- Err(..) => return Err(e),
- },
- };
-
- // Allocate necessary structures for doing the stack walk
- let process = unsafe { c::GetCurrentProcess() };
-
- let backtrace_context = BacktraceContext {
- handle: process,
- SymCleanup,
- StackWalkVariant: sw_var,
- dbghelp,
- };
-
- // Initialize this process's symbols
- let ret = unsafe { SymInitialize(process, ptr::null_mut(), c::TRUE) };
- if ret != c::TRUE {
- return Ok((0, backtrace_context));
- }
-
- // And now that we're done with all the setup, do the stack walking!
- match backtrace_context.StackWalkVariant {
- StackWalkVariant::StackWalkEx(StackWalkEx, _) => {
- set_frames(StackWalkEx, frames).map(|i| (i, backtrace_context))
- }
-
- StackWalkVariant::StackWalk64(StackWalk64, _) => {
- set_frames(StackWalk64, frames).map(|i| (i, backtrace_context))
- }
- }
-}
-
-fn set_frames<W: StackWalker>(StackWalk: W, frames: &mut [Frame]) -> io::Result<usize> {
- let process = unsafe { c::GetCurrentProcess() };
- let thread = unsafe { c::GetCurrentProcess() };
- let mut context: c::CONTEXT = unsafe { mem::zeroed() };
- unsafe { c::RtlCaptureContext(&mut context) };
- let mut frame = W::Item::new();
- let image = frame.init(&context);
-
- let mut i = 0;
- while i < frames.len()
- && StackWalk.walk(image, process, thread, &mut frame, &mut context) == c::TRUE
- {
- let addr = frame.get_addr();
- frames[i] = Frame {
- symbol_addr: addr,
- exact_position: addr,
- inline_context: 0,
- };
-
- i += 1
- }
- Ok(i)
-}
-
-type SymInitializeFn = unsafe extern "system" fn(c::HANDLE, *mut c_void, c::BOOL) -> c::BOOL;
-type SymCleanupFn = unsafe extern "system" fn(c::HANDLE) -> c::BOOL;
-
-type StackWalkExFn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME_EX,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- c::DWORD,
-) -> c::BOOL;
-
-type StackWalk64Fn = unsafe extern "system" fn(
- c::DWORD,
- c::HANDLE,
- c::HANDLE,
- *mut c::STACKFRAME64,
- *mut c::CONTEXT,
- *mut c_void,
- *mut c_void,
- *mut c_void,
- *mut c_void,
-) -> c::BOOL;
-
-trait StackWalker {
- type Item: StackFrame;
-
- fn walk(&self, c::DWORD, c::HANDLE, c::HANDLE, &mut Self::Item, &mut c::CONTEXT) -> c::BOOL;
-}
-
-impl StackWalker for StackWalkExFn {
- type Item = c::STACKFRAME_EX;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- 0,
- )
- }
- }
-}
-
-impl StackWalker for StackWalk64Fn {
- type Item = c::STACKFRAME64;
- fn walk(
- &self,
- image: c::DWORD,
- process: c::HANDLE,
- thread: c::HANDLE,
- frame: &mut Self::Item,
- context: &mut c::CONTEXT,
- ) -> c::BOOL {
- unsafe {
- self(
- image,
- process,
- thread,
- frame,
- context,
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- ptr::null_mut(),
- )
- }
- }
-}
-
-trait StackFrame {
- fn new() -> Self;
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD;
- fn get_addr(&self) -> *const u8;
-}
-
-impl StackFrame for c::STACKFRAME_EX {
- fn new() -> c::STACKFRAME_EX {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-impl StackFrame for c::STACKFRAME64 {
- fn new() -> c::STACKFRAME64 {
- unsafe { mem::zeroed() }
- }
-
- #[cfg(target_arch = "x86")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Eip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Esp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Ebp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_I386
- }
-
- #[cfg(target_arch = "x86_64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Rip as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Rsp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Rbp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_AMD64
- }
-
- #[cfg(target_arch = "aarch64")]
- fn init(&mut self, ctx: &c::CONTEXT) -> c::DWORD {
- self.AddrPC.Offset = ctx.Pc as u64;
- self.AddrPC.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrStack.Offset = ctx.Sp as u64;
- self.AddrStack.Mode = c::ADDRESS_MODE::AddrModeFlat;
- self.AddrFrame.Offset = ctx.Fp as u64;
- self.AddrFrame.Mode = c::ADDRESS_MODE::AddrModeFlat;
- c::IMAGE_FILE_MACHINE_ARM64
- }
-
- fn get_addr(&self) -> *const u8 {
- (self.AddrPC.Offset - 1) as *const u8
- }
-}
-
-enum StackWalkVariant {
- StackWalkEx(StackWalkExFn, printing::PrintingFnsEx),
- StackWalk64(StackWalk64Fn, printing::PrintingFns64),
-}
-
-pub struct BacktraceContext {
- handle: c::HANDLE,
- SymCleanup: SymCleanupFn,
- // Only used in printing for msvc and not gnu
- // The gnu version is effectively a ZST dummy.
- #[allow(dead_code)]
- StackWalkVariant: StackWalkVariant,
- // keeping DynamycLibrary loaded until its functions no longer needed
- #[allow(dead_code)]
- dbghelp: DynamicLibrary,
-}
-
-impl Drop for BacktraceContext {
- fn drop(&mut self) {
- unsafe {
- (self.SymCleanup)(self.handle);
- }
- }
-}