forked from M-Labs/libfringe
Don't use core::intrinsics.
The core::intrinsics::unreachable() we used at the end of every naked function is essentially pointless, as #[naked] implies that intrinsic at the end of the function. rustc currently does not implement that behavior (rust-lang/rust#32487), but it is a bug. On top of that, anything except a single asm!() in naked functions is likely to be disallowed in the future (rust-lang/rust#32490). A nice side effect is that we avoid the core_intrinsics feature, which will be never stabilized, though neither asm nor naked_functions are likely to be stabilized soon.
This commit is contained in:
parent
ddbf9a5afe
commit
f34ddc6805
|
@ -28,7 +28,6 @@
|
||||||
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
|
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
|
||||||
// * Simulating return is as easy as restoring register values from the CFI table
|
// * Simulating return is as easy as restoring register values from the CFI table
|
||||||
// and then setting stack pointer to CFA.
|
// and then setting stack pointer to CFA.
|
||||||
use core::intrinsics;
|
|
||||||
use stack::Stack;
|
use stack::Stack;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -36,7 +35,7 @@ pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn init_trampoline_1() -> ! {
|
unsafe extern "C" fn init_trampoline_1() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# gdb has a hardcoded check that rejects backtraces where frame addresses
|
# gdb has a hardcoded check that rejects backtraces where frame addresses
|
||||||
|
@ -60,12 +59,11 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
.Lend:
|
.Lend:
|
||||||
.size __morestack, .Lend-__morestack
|
.size __morestack, .Lend-__morestack
|
||||||
"#
|
"#
|
||||||
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile");
|
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile")
|
||||||
intrinsics::unreachable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn init_trampoline_2() -> ! {
|
unsafe extern "C" fn init_trampoline_2() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# Set up the second part of our DWARF CFI.
|
# Set up the second part of our DWARF CFI.
|
||||||
|
@ -78,8 +76,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
# Call the provided function.
|
# Call the provided function.
|
||||||
call *8(%esp)
|
call *8(%esp)
|
||||||
"#
|
"#
|
||||||
: : : "memory" : "volatile");
|
: : : "memory" : "volatile")
|
||||||
intrinsics::unreachable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn push(sp: &mut StackPointer, val: usize) {
|
unsafe fn push(sp: &mut StackPointer, val: usize) {
|
||||||
|
@ -102,7 +99,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
|
||||||
let new_cfa = (new_stack.top() as *mut usize).offset(-1);
|
let new_cfa = (new_stack.top() as *mut usize).offset(-1);
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn swap_trampoline() -> ! {
|
unsafe extern "C" fn swap_trampoline() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# Save frame pointer explicitly; the unwinder uses it to find CFA of
|
# Save frame pointer explicitly; the unwinder uses it to find CFA of
|
||||||
|
@ -125,8 +122,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
|
||||||
popl %ebx
|
popl %ebx
|
||||||
jmpl *%ebx
|
jmpl *%ebx
|
||||||
"#
|
"#
|
||||||
: : : "memory" : "volatile");
|
: : : "memory" : "volatile")
|
||||||
intrinsics::unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret: usize;
|
let ret: usize;
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
|
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
|
||||||
// * Simulating return is as easy as restoring register values from the CFI table
|
// * Simulating return is as easy as restoring register values from the CFI table
|
||||||
// and then setting stack pointer to CFA.
|
// and then setting stack pointer to CFA.
|
||||||
use core::intrinsics;
|
|
||||||
use stack::Stack;
|
use stack::Stack;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -40,7 +39,7 @@ pub struct StackPointer(*mut usize);
|
||||||
|
|
||||||
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn init_trampoline_1() -> ! {
|
unsafe extern "C" fn init_trampoline_1() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# gdb has a hardcoded check that rejects backtraces where frame addresses
|
# gdb has a hardcoded check that rejects backtraces where frame addresses
|
||||||
|
@ -64,12 +63,11 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
.Lend:
|
.Lend:
|
||||||
.size __morestack, .Lend-__morestack
|
.size __morestack, .Lend-__morestack
|
||||||
"#
|
"#
|
||||||
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile");
|
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile")
|
||||||
intrinsics::unreachable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn init_trampoline_2() -> ! {
|
unsafe extern "C" fn init_trampoline_2() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# Set up the second part of our DWARF CFI.
|
# Set up the second part of our DWARF CFI.
|
||||||
|
@ -79,8 +77,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
|
||||||
# Call the provided function.
|
# Call the provided function.
|
||||||
call *8(%rsp)
|
call *8(%rsp)
|
||||||
"#
|
"#
|
||||||
: : : "memory" : "volatile");
|
: : : "memory" : "volatile")
|
||||||
intrinsics::unreachable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn push(sp: &mut StackPointer, val: usize) {
|
unsafe fn push(sp: &mut StackPointer, val: usize) {
|
||||||
|
@ -104,7 +101,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
|
||||||
let new_cfa = (new_stack.top() as *mut usize).offset(-1);
|
let new_cfa = (new_stack.top() as *mut usize).offset(-1);
|
||||||
|
|
||||||
#[naked]
|
#[naked]
|
||||||
unsafe extern "C" fn swap_trampoline() -> ! {
|
unsafe extern "C" fn swap_trampoline() {
|
||||||
asm!(
|
asm!(
|
||||||
r#"
|
r#"
|
||||||
# Save frame pointer explicitly; the unwinder uses it to find CFA of
|
# Save frame pointer explicitly; the unwinder uses it to find CFA of
|
||||||
|
@ -127,8 +124,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
|
||||||
popq %rbx
|
popq %rbx
|
||||||
jmpq *%rbx
|
jmpq *%rbx
|
||||||
"#
|
"#
|
||||||
: : : "memory" : "volatile");
|
: : : "memory" : "volatile")
|
||||||
intrinsics::unreachable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let ret: usize;
|
let ret: usize;
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
// This file is part of libfringe, a low-level green threading library.
|
// This file is part of libfringe, a low-level green threading library.
|
||||||
// Copyright (c) edef <edef@edef.eu>
|
// Copyright (c) edef <edef@edef.eu>
|
||||||
// See the LICENSE file included in this distribution.
|
// See the LICENSE file included in this distribution.
|
||||||
#![feature(asm)]
|
#![feature(asm, naked_functions)]
|
||||||
#![cfg_attr(test, feature(test, thread_local, const_fn))]
|
#![cfg_attr(test, feature(test, thread_local, const_fn))]
|
||||||
#![cfg_attr(target_arch = "x86", feature(naked_functions, core_intrinsics))]
|
|
||||||
#![cfg_attr(target_arch = "x86_64", feature(naked_functions, core_intrinsics))]
|
|
||||||
#![no_std]
|
#![no_std]
|
||||||
|
|
||||||
//! libfringe is a library implementing safe, lightweight context switches,
|
//! libfringe is a library implementing safe, lightweight context switches,
|
||||||
|
|
Loading…
Reference in New Issue