Skip to content

Commit ed0b26b

Browse files
committed
Switch eh_unwind_resume to be a static function ptr
This makes calls go directly to _Unwind_Resume. _Unwind_Resume expects that it is called directly (i.e., the caller needs to be the landing pad).
1 parent a7836b6 commit ed0b26b

File tree

16 files changed

+136
-79
lines changed

16 files changed

+136
-79
lines changed

src/doc/unstable-book/src/language-features/lang-items.md

+15-7
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ fn main(_argc: isize, _argv: *const *const u8) -> isize {
5252
5353
#[lang = "eh_personality"] extern fn rust_eh_personality() {}
5454
#[lang = "panic_impl"] extern fn rust_begin_panic(info: &PanicInfo) -> ! { unsafe { intrinsics::abort() } }
55-
#[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
55+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
56+
intrinsics::abort()
57+
}
58+
#[lang = "eh_unwind_resume"]
59+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
5660
#[no_mangle] pub extern fn rust_eh_register_frames () {}
5761
#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
5862
```
@@ -131,10 +135,12 @@ pub extern fn rust_eh_personality() {
131135
}
132136
133137
// This function may be needed based on the compilation target.
134-
#[lang = "eh_unwind_resume"]
135-
#[no_mangle]
136-
pub extern fn rust_eh_unwind_resume() {
138+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
139+
intrinsics::abort()
137140
}
141+
#[lang = "eh_unwind_resume"]
142+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
143+
138144
139145
#[lang = "panic_impl"]
140146
#[no_mangle]
@@ -174,10 +180,12 @@ pub extern fn rust_eh_personality() {
174180
}
175181
176182
// This function may be needed based on the compilation target.
177-
#[lang = "eh_unwind_resume"]
178-
#[no_mangle]
179-
pub extern fn rust_eh_unwind_resume() {
183+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
184+
intrinsics::abort()
180185
}
186+
#[lang = "eh_unwind_resume"]
187+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
188+
181189
182190
#[lang = "panic_impl"]
183191
#[no_mangle]

src/libpanic_unwind/gcc.rs

+13-4
Original file line numberDiff line numberDiff line change
@@ -324,16 +324,25 @@ unsafe fn find_eh_action(
324324
eh::find_eh_action(lsda, &eh_context, foreign_exception)
325325
}
326326

327-
// See docs in the `unwind` module.
327+
#[cfg(all(
328+
target_os = "windows",
329+
any(target_arch = "x86", target_arch = "x86_64"),
330+
target_env = "gnu"
331+
))]
332+
#[cfg_attr(not(bootstrap), lang = "eh_unwind_resume")]
333+
#[used]
334+
pub static RESUME: unsafe extern "C" fn(*mut uw::_Unwind_Exception) -> ! =
335+
uw::_Unwind_Resume as unsafe extern "C" fn(_) -> !;
336+
328337
#[cfg(all(
329338
target_os = "windows",
330339
any(target_arch = "x86", target_arch = "x86_64"),
331340
target_env = "gnu"
332341
))]
333342
#[lang = "eh_unwind_resume"]
334-
#[unwind(allowed)]
335-
unsafe extern "C" fn rust_eh_unwind_resume(panic_ctx: *mut u8) -> ! {
336-
uw::_Unwind_Resume(panic_ctx as *mut uw::_Unwind_Exception);
343+
#[cfg(bootstrap)]
344+
pub unsafe extern "C" fn rust_eh_unwind_resume(p: *mut u8) -> ! {
345+
uw::_Unwind_Resume(p as *mut uw::_Unwind_Exception)
337346
}
338347

339348
// Frame unwind info registration

src/libpanic_unwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#![feature(raw)]
3131
#![panic_runtime]
3232
#![feature(panic_runtime)]
33+
#![allow(dead_code)]
3334

3435
use alloc::boxed::Box;
3536
use core::any::Any;

src/librustc_codegen_llvm/context.rs

+6-13
Original file line numberDiff line numberDiff line change
@@ -417,17 +417,9 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
417417
let tcx = self.tcx;
418418
assert!(self.sess().target.target.options.custom_unwind_resume);
419419
if let Some(def_id) = tcx.lang_items().eh_unwind_resume() {
420-
let llfn = self.get_fn_addr(
421-
ty::Instance::resolve(
422-
tcx,
423-
ty::ParamEnv::reveal_all(),
424-
def_id,
425-
tcx.intern_substs(&[]),
426-
)
427-
.unwrap(),
428-
);
429-
unwresume.set(Some(llfn));
430-
return llfn;
420+
let static_ptr = self.get_static(def_id);
421+
unwresume.set(Some(static_ptr));
422+
return static_ptr;
431423
}
432424

433425
let sig = ty::Binder::bind(tcx.mk_fn_sig(
@@ -441,8 +433,9 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
441433
let fn_abi = FnAbi::of_fn_ptr(self, sig, &[]);
442434
let llfn = self.declare_fn("rust_eh_unwind_resume", &fn_abi);
443435
attributes::apply_target_cpu_attr(self, llfn);
444-
unwresume.set(Some(llfn));
445-
llfn
436+
let static_ptr = self.static_addr_of(llfn, tcx.data_layout.pointer_align.abi, None);
437+
unwresume.set(Some(static_ptr));
438+
static_ptr
446439
}
447440

448441
fn sess(&self) -> &Session {

src/librustc_codegen_ssa/mir/block.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
184184
lp = bx.insert_value(lp, lp1, 1);
185185
bx.resume(lp);
186186
} else {
187-
bx.call(bx.eh_unwind_resume(), &[lp0], helper.funclet(self));
187+
let llfn = bx.load(bx.eh_unwind_resume(), bx.tcx().data_layout.pointer_align.abi);
188+
bx.call(llfn, &[lp0], helper.funclet(self));
188189
bx.unreachable();
189190
}
190191
}

src/librustc_hir/lang_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ language_item_table! {
240240
StartFnLangItem, "start", start_fn, Target::Fn;
241241

242242
EhPersonalityLangItem, "eh_personality", eh_personality, Target::Fn;
243-
EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Fn;
243+
EhUnwindResumeLangItem, "eh_unwind_resume", eh_unwind_resume, Target::Static;
244244
EhCatchTypeinfoLangItem, "eh_catch_typeinfo", eh_catch_typeinfo, Target::Static;
245245

246246
OwnedBoxLangItem, "owned_box", owned_box, Target::Struct;

src/libunwind/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(nll)]
55
#![feature(staged_api)]
66
#![feature(unwind_attributes)]
7+
#![feature(lang_items)]
78
#![feature(static_nobundle)]
89
#![cfg_attr(not(target_env = "msvc"), feature(libc))]
910

Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
// no-prefer-dynamic
22

33
#![crate_type = "rlib"]
4-
54
#![no_std]
6-
#![feature(lang_items)]
5+
#![feature(lang_items, core_intrinsics)]
76

87
use core::panic::PanicInfo;
98

109
#[lang = "panic_impl"]
11-
fn panic_impl(info: &PanicInfo) -> ! { loop {} }
10+
fn panic_impl(info: &PanicInfo) -> ! {
11+
loop {}
12+
}
1213
#[lang = "eh_personality"]
1314
fn eh_personality() {}
15+
16+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
17+
core::intrinsics::abort();
18+
}
1419
#[lang = "eh_unwind_resume"]
15-
fn eh_unwind_resume() {}
20+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;

src/test/ui/consts/const-eval/const_panic_libcore_main.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#![crate_type = "bin"]
2-
#![feature(lang_items)]
2+
#![feature(lang_items, core_intrinsics)]
33
#![feature(const_panic)]
44
#![no_main]
55
#![no_std]
@@ -17,8 +17,12 @@ const X: () = unimplemented!();
1717

1818
#[lang = "eh_personality"]
1919
fn eh() {}
20+
21+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
22+
core::intrinsics::abort();
23+
}
2024
#[lang = "eh_unwind_resume"]
21-
fn eh_unwind_resume() {}
25+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
2226

2327
#[panic_handler]
2428
fn panic(_info: &PanicInfo) -> ! {

src/test/ui/macros/macro-comma-behavior.core.stderr

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
11
error: 1 positional argument in format string, but no arguments were given
2-
--> $DIR/macro-comma-behavior.rs:21:23
2+
--> $DIR/macro-comma-behavior.rs:36:23
33
|
44
LL | assert_eq!(1, 1, "{}",);
55
| ^^
66

77
error: 1 positional argument in format string, but no arguments were given
8-
--> $DIR/macro-comma-behavior.rs:24:23
8+
--> $DIR/macro-comma-behavior.rs:39:23
99
|
1010
LL | assert_ne!(1, 2, "{}",);
1111
| ^^
1212

1313
error: 1 positional argument in format string, but no arguments were given
14-
--> $DIR/macro-comma-behavior.rs:30:29
14+
--> $DIR/macro-comma-behavior.rs:45:29
1515
|
1616
LL | debug_assert_eq!(1, 1, "{}",);
1717
| ^^
1818

1919
error: 1 positional argument in format string, but no arguments were given
20-
--> $DIR/macro-comma-behavior.rs:33:29
20+
--> $DIR/macro-comma-behavior.rs:48:29
2121
|
2222
LL | debug_assert_ne!(1, 2, "{}",);
2323
| ^^
2424

2525
error: 1 positional argument in format string, but no arguments were given
26-
--> $DIR/macro-comma-behavior.rs:54:19
26+
--> $DIR/macro-comma-behavior.rs:72:19
2727
|
2828
LL | format_args!("{}",);
2929
| ^^
3030

3131
error: 1 positional argument in format string, but no arguments were given
32-
--> $DIR/macro-comma-behavior.rs:72:21
32+
--> $DIR/macro-comma-behavior.rs:92:21
3333
|
3434
LL | unimplemented!("{}",);
3535
| ^^
3636

3737
error: 1 positional argument in format string, but no arguments were given
38-
--> $DIR/macro-comma-behavior.rs:81:24
38+
--> $DIR/macro-comma-behavior.rs:101:24
3939
|
4040
LL | write!(f, "{}",)?;
4141
| ^^

src/test/ui/macros/macro-comma-behavior.rs

+31-11
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,29 @@
33
// compile-flags: -C debug_assertions=yes
44
// revisions: std core
55

6-
#![feature(lang_items)]
6+
#![feature(lang_items, core_intrinsics)]
77
#![cfg_attr(core, no_std)]
88

9-
#[cfg(std)] use std::fmt;
10-
#[cfg(core)] use core::fmt;
11-
#[cfg(core)] #[lang = "eh_personality"] fn eh_personality() {}
12-
#[cfg(core)] #[lang = "eh_unwind_resume"] fn eh_unwind_resume() {}
13-
#[cfg(core)] #[lang = "panic_impl"] fn panic_impl(panic: &core::panic::PanicInfo) -> ! { loop {} }
9+
#[cfg(core)]
10+
use core::fmt;
11+
#[cfg(std)]
12+
use std::fmt;
13+
#[cfg(core)]
14+
#[lang = "eh_personality"]
15+
fn eh_personality() {}
16+
#[cfg(core)]
17+
#[lang = "panic_impl"]
18+
fn panic_impl(panic: &core::panic::PanicInfo) -> ! {
19+
loop {}
20+
}
21+
22+
#[cfg(core)]
23+
unsafe extern "C" fn eh_unwind_resume(_: *mut u8) -> ! {
24+
core::intrinsics::abort();
25+
}
26+
#[cfg(core)]
27+
#[lang = "eh_unwind_resume"]
28+
static _RESUME: unsafe extern "C" fn(*mut u8) -> ! = eh_unwind_resume;
1429

1530
// (see documentation of the similarly-named test in run-pass)
1631
fn to_format_or_not_to_format() {
@@ -34,19 +49,22 @@ fn to_format_or_not_to_format() {
3449
//[core]~^ ERROR no arguments
3550
//[std]~^^ ERROR no arguments
3651

37-
#[cfg(std)] {
52+
#[cfg(std)]
53+
{
3854
eprint!("{}",);
3955
//[std]~^ ERROR no arguments
4056
}
4157

42-
#[cfg(std)] {
58+
#[cfg(std)]
59+
{
4360
// FIXME: compile-fail says "expected error not found" even though
4461
// rustc does emit an error
4562
// eprintln!("{}",);
4663
// <DISABLED> [std]~^ ERROR no arguments
4764
}
4865

49-
#[cfg(std)] {
66+
#[cfg(std)]
67+
{
5068
format!("{}",);
5169
//[std]~^ ERROR no arguments
5270
}
@@ -57,12 +75,14 @@ fn to_format_or_not_to_format() {
5775

5876
// if falsum() { panic!("{}",); } // see run-pass
5977

60-
#[cfg(std)] {
78+
#[cfg(std)]
79+
{
6180
print!("{}",);
6281
//[std]~^ ERROR no arguments
6382
}
6483

65-
#[cfg(std)] {
84+
#[cfg(std)]
85+
{
6686
// FIXME: compile-fail says "expected error not found" even though
6787
// rustc does emit an error
6888
// println!("{}",);

src/test/ui/macros/macro-comma-behavior.std.stderr

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,59 @@
11
error: 1 positional argument in format string, but no arguments were given
2-
--> $DIR/macro-comma-behavior.rs:21:23
2+
--> $DIR/macro-comma-behavior.rs:36:23
33
|
44
LL | assert_eq!(1, 1, "{}",);
55
| ^^
66

77
error: 1 positional argument in format string, but no arguments were given
8-
--> $DIR/macro-comma-behavior.rs:24:23
8+
--> $DIR/macro-comma-behavior.rs:39:23
99
|
1010
LL | assert_ne!(1, 2, "{}",);
1111
| ^^
1212

1313
error: 1 positional argument in format string, but no arguments were given
14-
--> $DIR/macro-comma-behavior.rs:30:29
14+
--> $DIR/macro-comma-behavior.rs:45:29
1515
|
1616
LL | debug_assert_eq!(1, 1, "{}",);
1717
| ^^
1818

1919
error: 1 positional argument in format string, but no arguments were given
20-
--> $DIR/macro-comma-behavior.rs:33:29
20+
--> $DIR/macro-comma-behavior.rs:48:29
2121
|
2222
LL | debug_assert_ne!(1, 2, "{}",);
2323
| ^^
2424

2525
error: 1 positional argument in format string, but no arguments were given
26-
--> $DIR/macro-comma-behavior.rs:38:18
26+
--> $DIR/macro-comma-behavior.rs:54:18
2727
|
2828
LL | eprint!("{}",);
2929
| ^^
3030

3131
error: 1 positional argument in format string, but no arguments were given
32-
--> $DIR/macro-comma-behavior.rs:50:18
32+
--> $DIR/macro-comma-behavior.rs:68:18
3333
|
3434
LL | format!("{}",);
3535
| ^^
3636

3737
error: 1 positional argument in format string, but no arguments were given
38-
--> $DIR/macro-comma-behavior.rs:54:19
38+
--> $DIR/macro-comma-behavior.rs:72:19
3939
|
4040
LL | format_args!("{}",);
4141
| ^^
4242

4343
error: 1 positional argument in format string, but no arguments were given
44-
--> $DIR/macro-comma-behavior.rs:61:17
44+
--> $DIR/macro-comma-behavior.rs:80:17
4545
|
4646
LL | print!("{}",);
4747
| ^^
4848

4949
error: 1 positional argument in format string, but no arguments were given
50-
--> $DIR/macro-comma-behavior.rs:72:21
50+
--> $DIR/macro-comma-behavior.rs:92:21
5151
|
5252
LL | unimplemented!("{}",);
5353
| ^^
5454

5555
error: 1 positional argument in format string, but no arguments were given
56-
--> $DIR/macro-comma-behavior.rs:81:24
56+
--> $DIR/macro-comma-behavior.rs:101:24
5757
|
5858
LL | write!(f, "{}",)?;
5959
| ^^

0 commit comments

Comments
 (0)