Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
| 2 | // file at the top-level directory of this distribution and at |
| 3 | // http://rust-lang.org/COPYRIGHT. |
| 4 | // |
| 5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or |
| 6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license |
| 7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your |
| 8 | // option. This file may not be copied, modified, or distributed |
| 9 | // except according to those terms. |
| 10 | |
| 11 | //! Implementation of panics via stack unwinding |
| 12 | //! |
| 13 | //! This crate is an implementation of panics in Rust using "most native" stack |
| 14 | //! unwinding mechanism of the platform this is being compiled for. This |
| 15 | //! essentially gets categorized into three buckets currently: |
| 16 | //! |
| 17 | //! 1. MSVC targets use SEH in the `seh.rs` file. |
| 18 | //! 2. The 64-bit MinGW target half-uses SEH and half-use gcc-like information |
| 19 | //! in the `seh64_gnu.rs` module. |
| 20 | //! 3. All other targets use libunwind/libgcc in the `gcc/mod.rs` module. |
| 21 | //! |
| 22 | //! More documentation about each implementation can be found in the respective |
| 23 | //! module. |
| 24 | |
| 25 | #![no_std] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 26 | #![unstable(feature = "panic_unwind", issue = "32837")] |
| 27 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", |
| 28 | html_favicon_url = "https://doc.rust-lang.org/favicon.ico", |
| 29 | html_root_url = "https://doc.rust-lang.org/nightly/", |
| 30 | issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 31 | |
| 32 | #![feature(alloc)] |
| 33 | #![feature(core_intrinsics)] |
| 34 | #![feature(lang_items)] |
| 35 | #![feature(libc)] |
Alex Crichton | 80ff0f7 | 2017-10-23 03:01:00 | [diff] [blame] | 36 | #![feature(panic_unwind)] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 37 | #![feature(raw)] |
| 38 | #![feature(staged_api)] |
| 39 | #![feature(unwind_attributes)] |
| 40 | #![cfg_attr(target_env = "msvc", feature(raw))] |
| 41 | |
Alex Crichton | fa45670 | 2016-05-24 05:28:15 | [diff] [blame] | 42 | #![panic_runtime] |
| 43 | #![feature(panic_runtime)] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 44 | |
| 45 | extern crate alloc; |
| 46 | extern crate libc; |
Tatsuyuki Ishi | 6e18fe4 | 2017-08-14 00:26:14 | [diff] [blame] | 47 | #[cfg(not(any(target_env = "msvc", all(windows, target_arch = "x86_64", target_env = "gnu"))))] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 48 | extern crate unwind; |
| 49 | |
| 50 | use core::intrinsics; |
| 51 | use core::mem; |
| 52 | use core::raw; |
| 53 | |
| 54 | // Rust runtime's startup objects depend on these symbols, so make them public. |
| 55 | #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] |
| 56 | pub use imp::eh_frame_registry::*; |
| 57 | |
| 58 | // *-pc-windows-msvc |
| 59 | #[cfg(target_env = "msvc")] |
| 60 | #[path = "seh.rs"] |
| 61 | mod imp; |
| 62 | |
| 63 | // x86_64-pc-windows-gnu |
| 64 | #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] |
| 65 | #[path = "seh64_gnu.rs"] |
| 66 | mod imp; |
| 67 | |
| 68 | // i686-pc-windows-gnu and all others |
Brian Anderson | 525a798 | 2016-09-22 19:55:42 | [diff] [blame] | 69 | #[cfg(any(all(unix, not(target_os = "emscripten")), |
Ed Schouten | 9a8f0a8 | 2018-01-04 16:55:44 | [diff] [blame] | 70 | target_os = "cloudabi", |
Jeremy Soller | a908509 | 2016-11-11 02:33:59 | [diff] [blame] | 71 | target_os = "redox", |
Brian Anderson | 525a798 | 2016-09-22 19:55:42 | [diff] [blame] | 72 | all(windows, target_arch = "x86", target_env = "gnu")))] |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 73 | #[path = "gcc.rs"] |
| 74 | mod imp; |
| 75 | |
Brian Anderson | 525a798 | 2016-09-22 19:55:42 | [diff] [blame] | 76 | // emscripten |
| 77 | #[cfg(target_os = "emscripten")] |
| 78 | #[path = "emcc.rs"] |
| 79 | mod imp; |
| 80 | |
Alex Crichton | 80ff0f7 | 2017-10-23 03:01:00 | [diff] [blame] | 81 | #[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))] |
| 82 | #[path = "wasm32.rs"] |
| 83 | mod imp; |
| 84 | |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 85 | mod dwarf; |
| 86 | mod windows; |
| 87 | |
| 88 | // Entry point for catching an exception, implemented using the `try` intrinsic |
| 89 | // in the compiler. |
| 90 | // |
| 91 | // The interaction between the `payload` function and the compiler is pretty |
| 92 | // hairy and tightly coupled, for more information see the compiler's |
| 93 | // implementation of this. |
| 94 | #[no_mangle] |
Srinivas Reddy Thatiparthy | 00bbc27 | 2016-05-29 10:36:29 | [diff] [blame] | 95 | pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8), |
| 96 | data: *mut u8, |
| 97 | data_ptr: *mut usize, |
| 98 | vtable_ptr: *mut usize) |
| 99 | -> u32 { |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 100 | let mut payload = imp::payload(); |
| 101 | if intrinsics::try(f, data, &mut payload as *mut _ as *mut _) == 0 { |
| 102 | 0 |
| 103 | } else { |
| 104 | let obj = mem::transmute::<_, raw::TraitObject>(imp::cleanup(payload)); |
| 105 | *data_ptr = obj.data as usize; |
| 106 | *vtable_ptr = obj.vtable as usize; |
| 107 | 1 |
| 108 | } |
| 109 | } |
| 110 | |
| 111 | // Entry point for raising an exception, just delegates to the platform-specific |
| 112 | // implementation. |
| 113 | #[no_mangle] |
Alex Crichton | 8958815 | 2018-04-04 14:16:25 | [diff] [blame] | 114 | #[unwind(allowed)] |
Srinivas Reddy Thatiparthy | 00bbc27 | 2016-05-29 10:36:29 | [diff] [blame] | 115 | pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 { |
Alex Crichton | 0ec321f | 2016-04-08 23:18:40 | [diff] [blame] | 116 | imp::panic(mem::transmute(raw::TraitObject { |
| 117 | data: data as *mut (), |
| 118 | vtable: vtable as *mut (), |
| 119 | })) |
| 120 | } |