Skip to content
Snippets Groups Projects
Verified Commit 590ad70a authored by Jacob Lorentzon's avatar Jacob Lorentzon
Browse files

Fix trampoline for i686. Ctrl-C now works.

parent c93b43b4
No related branches found
No related tags found
1 merge request!480Refactor redox runtime and impl signals in userspace
use syscall::error::*;
use core::mem::offset_of;
use syscall::*;
use crate::proc::{fork_inner, FdGuard};
use crate::signal::{inner_fastcall, RtSigarea};
......@@ -97,17 +99,105 @@ asmfunction!(__relibc_internal_fork_ret: ["
ret
"] <= [child_hook = sym child_hook]);
asmfunction!(__relibc_internal_sigentry: ["
sub esp, 512
// Read pending half of first signal. This can be done nonatomically wrt the mask bits, since
// only this thread is allowed to modify the latter.
// Read first signal word
mov eax, gs:[{tcb_sc_off} + {sc_word}]
mov edx, gs:[{tcb_sc_off} + {sc_word} + 4]
not edx
and eax, edx
and eax, {SIGW0_PENDING_MASK}
bsf eax, eax
jnz 2f
// Read second signal word
mov eax, gs:[{tcb_sc_off} + {sc_word} + 8]
mov edx, gs:[{tcb_sc_off} + {sc_word} + 12]
not edx
and eax, edx
and eax, {SIGW1_PENDING_MASK}
bsf eax, eax
jz 7f
add eax, 32
2:
and esp, -{STACK_ALIGN}
bt gs:[{tcb_sa_off} + {sa_onstack}], eax
jnc 4f
mov edx, gs:[{tcb_sa_off} + {sa_altstack_top}]
cmp esp, edx
ja 3f
cmp esp, gs:[{tcb_sa_off} + {sa_altstack_bottom}]
jnbe 4f
3:
mov esp, edx
4:
// Now that we have a stack, we can finally start populating the signal stack.
push fs
.byte 0x66, 0x6a, 0x00 // pushw 0
push ss
.byte 0x66, 0x6a, 0x00 // pushw 0
push dword ptr gs:[{tcb_sc_off} + {sc_saved_esp}]
push dword ptr gs:[{tcb_sc_off} + {sc_saved_eflags}]
push cs
.byte 0x66, 0x6a, 0x00 // pushw 0
push dword ptr gs:[{tcb_sc_off} + {sc_saved_eip}]
push dword ptr gs:[{tcb_sc_off} + {sc_saved_edx}]
push ecx
push dword ptr gs:[{tcb_sc_off} + {sc_saved_eax}]
push ebx
push edi
push esi
push ebp
push eax
sub esp, 512 + 8
fxsave [esp]
mov ecx, esp
call {inner}
add esp, 512
fxrstor [esp]
add esp, 512 + 12
pop ebp
pop esi
pop edi
pop ebx
pop eax
pop ecx
pop edx
pop dword ptr gs:[{tcb_sa_off} + {sa_tmp}]
add esp, 4
popf
pop esp
jmp dword ptr gs:[{tcb_sa_off} + {sa_tmp}]
7:
ud2
"] <= [inner = sym inner_fastcall]);
"] <= [
inner = sym inner_fastcall,
sa_tmp = const offset_of!(SigArea, tmp),
sa_altstack_top = const offset_of!(SigArea, altstack_top),
sa_altstack_bottom = const offset_of!(SigArea, altstack_bottom),
sa_onstack = const offset_of!(SigArea, onstack),
sc_saved_eax = const offset_of!(Sigcontrol, saved_scratch_a),
sc_saved_edx = const offset_of!(Sigcontrol, saved_scratch_b),
sc_saved_eflags = const offset_of!(Sigcontrol, saved_flags),
sc_saved_eip = const offset_of!(Sigcontrol, saved_ip),
sc_saved_esp = const offset_of!(Sigcontrol, saved_sp),
sc_word = const offset_of!(Sigcontrol, word),
tcb_sa_off = const offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, arch),
tcb_sc_off = const offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control),
SIGW0_PENDING_MASK = const !(
SIGW0_TSTP_IS_STOP_BIT | SIGW0_TTIN_IS_STOP_BIT | SIGW0_TTOU_IS_STOP_BIT | SIGW0_NOCLDSTOP_BIT | SIGW0_UNUSED1 | SIGW0_UNUSED2
),
SIGW1_PENDING_MASK = const !0,
STACK_ALIGN = const 16,
]);
asmfunction!(__relibc_internal_rlct_clone_ret -> usize: ["
# Load registers
......
......@@ -153,27 +153,25 @@ asmfunction!(__relibc_internal_sigentry: ["
jnz 7f
add eax, 32
2:
sub rsp, {REDZONE_SIZE}
and rsp, -{STACK_ALIGN}
// By now we have selected a signal, stored in eax (6-bit). We now need to choose whether or
// not to switch to the alternate signal stack. If SA_ONSTACK is clear for this signal, then
// skip the sigaltstack logic.
bt fs:[{tcb_sa_off} + {sa_onstack}], eax
jc 3f
jnc 4f
// Otherwise, the altstack is already active. The sigaltstack being disabled, is equivalent
// to setting 'top' to usize::MAX and 'bottom' to 0.
sub rsp, {REDZONE_SIZE}
and rsp, -{STACK_ALIGN}
jmp 4f
3:
// If current RSP is above altstack region, switch to altstack
mov rdx, fs:[{tcb_sa_off} + {sa_altstack_top}]
cmp rdx, rsp
cmp rsp, rdx
cmova rsp, rdx
// If current RSP is below altstack region, also switch to altstack
mov rdx, fs:[{tcb_sa_off} + {sa_altstack_bottom}]
cmp rdx, rsp
cmp rsp, fs:[{tcb_sa_off} + {sa_altstack_bottom}]
cmovbe rsp, rdx
.p2align 4
......
......@@ -34,7 +34,12 @@ pub struct SigStack {
#[cfg(target_arch = "x86")]
fx: [u8; 512],
#[cfg(target_arch = "x86_64")]
_pad: [usize; 3], // pad to 192 = 3 * 64 = 168 + 24 bytes
#[cfg(target_arch = "x86")]
_pad: [usize; 2], // pad to 192 = 3 * 64 = 168 + 24 bytes
sig_num: usize,
regs: IntRegisters, // 160 bytes currently
}
......@@ -310,15 +315,17 @@ pub fn setup_sighandler(area: &RtSigarea) {
let mut sigactions = SIGACTIONS.lock();
}
let arch = unsafe { &mut *area.arch.get() };
#[cfg(target_arch = "x86_64")]
{
// The asm decides whether to use the altstack, based on whether the saved stack pointer
// was already on that stack. Thus, setting the altstack to the entire address space, is
// equivalent to not using any altstack at all (the default).
arch.altstack_top = usize::MAX;
arch.altstack_bottom = 0;
arch.onstack = 0;
}
#[cfg(target_arch = "x86_64")]
{
let cpuid_eax1_ecx = unsafe { core::arch::x86_64::__cpuid(1) }.ecx;
CPUID_EAX1_ECX.store(cpuid_eax1_ecx, core::sync::atomic::Ordering::Relaxed);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment