]>
Commit | Line | Data |
---|---|---|
a7813a04 XL |
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] | |
26 | #![crate_name = "panic_unwind"] | |
27 | #![crate_type = "rlib"] | |
28 | #![unstable(feature = "panic_unwind", issue = "32837")] | |
29 | #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png", | |
30 | html_favicon_url = "https://doc.rust-lang.org/favicon.ico", | |
31 | html_root_url = "https://doc.rust-lang.org/nightly/", | |
32 | issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")] | |
33 | #![cfg_attr(not(stage0), deny(warnings))] | |
34 | ||
35 | #![feature(alloc)] | |
36 | #![feature(core_intrinsics)] | |
37 | #![feature(lang_items)] | |
38 | #![feature(libc)] | |
39 | #![feature(panic_unwind)] | |
40 | #![feature(raw)] | |
41 | #![feature(staged_api)] | |
42 | #![feature(unwind_attributes)] | |
43 | #![cfg_attr(target_env = "msvc", feature(raw))] | |
44 | ||
3157f602 XL |
45 | #![panic_runtime] |
46 | #![feature(panic_runtime)] | |
a7813a04 XL |
47 | |
48 | extern crate alloc; | |
49 | extern crate libc; | |
50 | extern crate unwind; | |
51 | ||
52 | use core::intrinsics; | |
53 | use core::mem; | |
54 | use core::raw; | |
55 | ||
56 | // Rust runtime's startup objects depend on these symbols, so make them public. | |
57 | #[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))] | |
58 | pub use imp::eh_frame_registry::*; | |
59 | ||
60 | // *-pc-windows-msvc | |
61 | #[cfg(target_env = "msvc")] | |
62 | #[path = "seh.rs"] | |
63 | mod imp; | |
64 | ||
65 | // x86_64-pc-windows-gnu | |
66 | #[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))] | |
67 | #[path = "seh64_gnu.rs"] | |
68 | mod imp; | |
69 | ||
70 | // i686-pc-windows-gnu and all others | |
71 | #[cfg(any(unix, all(windows, target_arch = "x86", target_env = "gnu")))] | |
72 | #[path = "gcc.rs"] | |
73 | mod imp; | |
74 | ||
75 | mod dwarf; | |
76 | mod windows; | |
77 | ||
78 | // Entry point for catching an exception, implemented using the `try` intrinsic | |
79 | // in the compiler. | |
80 | // | |
81 | // The interaction between the `payload` function and the compiler is pretty | |
82 | // hairy and tightly coupled, for more information see the compiler's | |
83 | // implementation of this. | |
84 | #[no_mangle] | |
3157f602 XL |
85 | pub unsafe extern "C" fn __rust_maybe_catch_panic(f: fn(*mut u8), |
86 | data: *mut u8, | |
87 | data_ptr: *mut usize, | |
88 | vtable_ptr: *mut usize) | |
89 | -> u32 { | |
a7813a04 XL |
90 | let mut payload = imp::payload(); |
91 | if intrinsics::try(f, data, &mut payload as *mut _ as *mut _) == 0 { | |
92 | 0 | |
93 | } else { | |
94 | let obj = mem::transmute::<_, raw::TraitObject>(imp::cleanup(payload)); | |
95 | *data_ptr = obj.data as usize; | |
96 | *vtable_ptr = obj.vtable as usize; | |
97 | 1 | |
98 | } | |
99 | } | |
100 | ||
101 | // Entry point for raising an exception, just delegates to the platform-specific | |
102 | // implementation. | |
103 | #[no_mangle] | |
5bcae85e | 104 | #[unwind] |
3157f602 | 105 | pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 { |
a7813a04 XL |
106 | imp::panic(mem::transmute(raw::TraitObject { |
107 | data: data as *mut (), | |
108 | vtable: vtable as *mut (), | |
109 | })) | |
110 | } |