Skip to content

Commit

Permalink
Don't use core::intrinsics.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
whitequark authored and edef1c committed Aug 13, 2016
1 parent 8043496 commit d3303cb
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 23 deletions.
16 changes: 6 additions & 10 deletions src/arch/x86.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,14 @@
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
// * Simulating return is as easy as restoring register values from the CFI table
// and then setting stack pointer to CFA.
use core::intrinsics;
use stack::Stack;

#[derive(Debug)]
pub struct StackPointer(*mut usize);

pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
#[naked]
unsafe extern "C" fn init_trampoline_1() -> ! {
unsafe extern "C" fn init_trampoline_1() {
asm!(
r#"
# gdb has a hardcoded check that rejects backtraces where frame addresses
Expand All @@ -60,12 +59,11 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
.Lend:
.size __morestack, .Lend-__morestack
"#
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile");
intrinsics::unreachable()
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile")
}

#[naked]
unsafe extern "C" fn init_trampoline_2() -> ! {
unsafe extern "C" fn init_trampoline_2() {
asm!(
r#"
# Set up the second part of our DWARF CFI.
Expand All @@ -78,8 +76,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
# Call the provided function.
call *8(%esp)
"#
: : : "memory" : "volatile");
intrinsics::unreachable()
: : : "memory" : "volatile")
}

unsafe fn push(sp: &mut StackPointer, val: usize) {
Expand All @@ -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);

#[naked]
unsafe extern "C" fn swap_trampoline() -> ! {
unsafe extern "C" fn swap_trampoline() {
asm!(
r#"
# Save frame pointer explicitly; the unwinder uses it to find CFA of
Expand All @@ -125,8 +122,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
popl %ebx
jmpl *%ebx
"#
: : : "memory" : "volatile");
intrinsics::unreachable();
: : : "memory" : "volatile")
}

let ret: usize;
Expand Down
16 changes: 6 additions & 10 deletions src/arch/x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,14 @@
// after. A .cfi_def_* pseudoinstruction changes the CFA value similarly.
// * Simulating return is as easy as restoring register values from the CFI table
// and then setting stack pointer to CFA.
use core::intrinsics;
use stack::Stack;

#[derive(Debug)]
pub struct StackPointer(*mut usize);

pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackPointer {
#[naked]
unsafe extern "C" fn init_trampoline_1() -> ! {
unsafe extern "C" fn init_trampoline_1() {
asm!(
r#"
# gdb has a hardcoded check that rejects backtraces where frame addresses
Expand All @@ -64,12 +63,11 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
.Lend:
.size __morestack, .Lend-__morestack
"#
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile");
intrinsics::unreachable()
: : "s" (init_trampoline_2 as usize) : "memory" : "volatile")
}

#[naked]
unsafe extern "C" fn init_trampoline_2() -> ! {
unsafe extern "C" fn init_trampoline_2() {
asm!(
r#"
# Set up the second part of our DWARF CFI.
Expand All @@ -79,8 +77,7 @@ pub unsafe fn init(stack: &Stack, f: unsafe extern "C" fn(usize) -> !) -> StackP
# Call the provided function.
call *8(%rsp)
"#
: : : "memory" : "volatile");
intrinsics::unreachable()
: : : "memory" : "volatile")
}

unsafe fn push(sp: &mut StackPointer, val: usize) {
Expand All @@ -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);

#[naked]
unsafe extern "C" fn swap_trampoline() -> ! {
unsafe extern "C" fn swap_trampoline() {
asm!(
r#"
# Save frame pointer explicitly; the unwinder uses it to find CFA of
Expand All @@ -127,8 +124,7 @@ pub unsafe fn swap(arg: usize, old_sp: &mut StackPointer, new_sp: &StackPointer,
popq %rbx
jmpq *%rbx
"#
: : : "memory" : "volatile");
intrinsics::unreachable();
: : : "memory" : "volatile")
}

let ret: usize;
Expand Down
4 changes: 1 addition & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
// This file is part of libfringe, a low-level green threading library.
// Copyright (c) Nathan Zadoks <nathan@nathan7.eu>
// 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(target_arch = "x86", feature(naked_functions, core_intrinsics))]
#![cfg_attr(target_arch = "x86_64", feature(naked_functions, core_intrinsics))]
#![no_std]

//! libfringe is a library implementing safe, lightweight context switches,
Expand Down

0 comments on commit d3303cb

Please sign in to comment.