blob: 9321d6917d1566db3ef070a9c35066c0ef8b1007 [file] [log] [blame]
Alex Crichton0ec321f2016-04-08 23:18:401// 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 Crichton0ec321f2016-04-08 23:18:4026#![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 Crichton0ec321f2016-04-08 23:18:4031
32#![feature(alloc)]
33#![feature(core_intrinsics)]
34#![feature(lang_items)]
35#![feature(libc)]
Alex Crichton80ff0f72017-10-23 03:01:0036#![feature(panic_unwind)]
Alex Crichton0ec321f2016-04-08 23:18:4037#![feature(raw)]
38#![feature(staged_api)]
39#![feature(unwind_attributes)]
40#![cfg_attr(target_env = "msvc", feature(raw))]
41
Alex Crichtonfa456702016-05-24 05:28:1542#![panic_runtime]
43#![feature(panic_runtime)]
Alex Crichton0ec321f2016-04-08 23:18:4044
45extern crate alloc;
46extern crate libc;
Tatsuyuki Ishi6e18fe42017-08-14 00:26:1447#[cfg(not(any(target_env = "msvc", all(windows, target_arch = "x86_64", target_env = "gnu"))))]
Alex Crichton0ec321f2016-04-08 23:18:4048extern crate unwind;
49
50use core::intrinsics;
51use core::mem;
52use 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"))]
56pub use imp::eh_frame_registry::*;
57
58// *-pc-windows-msvc
59#[cfg(target_env = "msvc")]
60#[path = "seh.rs"]
61mod imp;
62
63// x86_64-pc-windows-gnu
64#[cfg(all(windows, target_arch = "x86_64", target_env = "gnu"))]
65#[path = "seh64_gnu.rs"]
66mod imp;
67
68// i686-pc-windows-gnu and all others
Brian Anderson525a7982016-09-22 19:55:4269#[cfg(any(all(unix, not(target_os = "emscripten")),
Ed Schouten9a8f0a82018-01-04 16:55:4470 target_os = "cloudabi",
Jeremy Sollera9085092016-11-11 02:33:5971 target_os = "redox",
Brian Anderson525a7982016-09-22 19:55:4272 all(windows, target_arch = "x86", target_env = "gnu")))]
Alex Crichton0ec321f2016-04-08 23:18:4073#[path = "gcc.rs"]
74mod imp;
75
Brian Anderson525a7982016-09-22 19:55:4276// emscripten
77#[cfg(target_os = "emscripten")]
78#[path = "emcc.rs"]
79mod imp;
80
Alex Crichton80ff0f72017-10-23 03:01:0081#[cfg(all(target_arch = "wasm32", not(target_os = "emscripten")))]
82#[path = "wasm32.rs"]
83mod imp;
84
Alex Crichton0ec321f2016-04-08 23:18:4085mod dwarf;
86mod 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 Thatiparthy00bbc272016-05-29 10:36:2995pub 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 Crichton0ec321f2016-04-08 23:18:40100 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 Crichton89588152018-04-04 14:16:25114#[unwind(allowed)]
Srinivas Reddy Thatiparthy00bbc272016-05-29 10:36:29115pub unsafe extern "C" fn __rust_start_panic(data: usize, vtable: usize) -> u32 {
Alex Crichton0ec321f2016-04-08 23:18:40116 imp::panic(mem::transmute(raw::TraitObject {
117 data: data as *mut (),
118 vtable: vtable as *mut (),
119 }))
120}