diff --git a/redox-rt/src/arch/i686.rs b/redox-rt/src/arch/i686.rs
index 27f1e55bce87fd910e6c306fd703aa60ffba311a..07d8ae05b74cea093bea1e17010c9a0c87d3acf4 100644
--- a/redox-rt/src/arch/i686.rs
+++ b/redox-rt/src/arch/i686.rs
@@ -3,7 +3,7 @@ use core::mem::offset_of;
 use syscall::*;
 
 use crate::proc::{fork_inner, FdGuard};
-use crate::signal::{inner_fastcall, RtSigarea};
+use crate::signal::{inner_fastcall, RtSigarea, SigStack};
 
 // Setup a stack starting from the very end of the address space, and then growing downwards.
 pub(crate) const STACK_TOP: usize = 1 << 31;
@@ -14,10 +14,30 @@ pub(crate) const STACK_SIZE: usize = 1024 * 1024;
 pub struct SigArea {
     pub altstack_top: usize,
     pub altstack_bottom: usize,
-    pub tmp: usize,
+    pub tmp_eip: usize,
+    pub tmp_esp: usize,
+    pub tmp_eax: usize,
+    pub tmp_edx: usize,
     pub onstack: u64,
     pub disable_signals_depth: u64,
 }
+#[derive(Debug, Default)]
+#[repr(C)]
+pub struct ArchIntRegs {
+    pub _pad: [usize; 2], // make size divisible by 16
+
+    pub ebp: usize,
+    pub esi: usize,
+    pub edi: usize,
+    pub ebx: usize,
+    pub eax: usize,
+    pub ecx: usize,
+    pub edx: usize,
+
+    pub eflags: usize,
+    pub eip: usize,
+    pub esp: usize,
+}
 
 /// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS
 /// is already initialized as if it was a thread.
@@ -100,6 +120,7 @@ asmfunction!(__relibc_internal_fork_ret: ["
     ret
 "] <= [child_hook = sym child_hook]);
 asmfunction!(__relibc_internal_sigentry: ["
+    // Save some registers
     mov gs:[{tcb_sa_off} + {sa_tmp_esp}], esp
     mov gs:[{tcb_sa_off} + {sa_tmp_eax}], eax
     mov gs:[{tcb_sa_off} + {sa_tmp_edx}], edx
@@ -136,33 +157,29 @@ asmfunction!(__relibc_internal_sigentry: ["
     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_sa_off} + {sc_tmp_esp}]
-    push dword ptr gs:[{tcb_sc_off} + {sc_saved_eflags}]
-    push cs
-    .byte 0x66, 0x6a, 0x00 // pushw 0
+    push dword ptr gs:[{tcb_sa_off} + {sa_tmp_esp}]
     push dword ptr gs:[{tcb_sc_off} + {sc_saved_eip}]
+    push dword ptr gs:[{tcb_sc_off} + {sc_saved_eflags}]
 
-    push dword ptr gs:[{tcb_sa_off} + {sc_tmp_edx}]
+    push dword ptr gs:[{tcb_sa_off} + {sa_tmp_edx}]
     push ecx
-    push dword ptr gs:[{tcb_sa_off} + {sc_tmp_eax}]
+    push dword ptr gs:[{tcb_sa_off} + {sa_tmp_eax}]
     push ebx
     push edi
     push esi
     push ebp
 
+    sub esp, 8
+
     push eax
-    sub esp, 512 + 8
+    sub esp, 12 + 512
     fxsave [esp]
 
     mov ecx, esp
     call {inner}
 
     fxrstor [esp]
-    add esp, 512 + 12
+    add esp, 512 + 12 + 4 + 8
 
     pop ebp
     pop esi
@@ -172,10 +189,15 @@ asmfunction!(__relibc_internal_sigentry: ["
     pop ecx
     pop edx
 
-    pop dword ptr gs:[{tcb_sa_off} + {sa_tmp_eip}]
-    add esp, 4
     popfd
+    pop dword ptr gs:[{tcb_sa_off} + {sa_tmp_eip}]
+
+    .globl __relibc_internal_sigentry_crit_first
+__relibc_internal_sigentry_crit_first:
     pop esp
+
+    .globl __relibc_internal_sigentry_crit_second
+__relibc_internal_sigentry_crit_second:
     jmp dword ptr gs:[{tcb_sa_off} + {sa_tmp_eip}]
 7:
     ud2
@@ -218,3 +240,16 @@ asmfunction!(__relibc_internal_rlct_clone_ret -> usize: ["
 
     ret
 "] <= []);
+extern "C" {
+    fn __relibc_internal_sigentry_crit_first();
+    fn __relibc_internal_sigentry_crit_second();
+}
+pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
+    if stack.regs.eip == __relibc_internal_sigentry_crit_first as usize {
+        let stack_ptr = stack.regs.esp as *const usize;
+        stack.regs.esp = stack_ptr.read();
+        stack.regs.eip = stack_ptr.sub(1).read();
+    } else if stack.regs.eip == __relibc_internal_sigentry_crit_second as usize {
+        stack.regs.eip = area.tmp_eip;
+    }
+}
diff --git a/redox-rt/src/signal.rs b/redox-rt/src/signal.rs
index d328896d62fb73df93a7bcfbac9e62f6fe284ff2..8b7bf0ff495a0f219f2ba8d905c4469ce03ce0b9 100644
--- a/redox-rt/src/signal.rs
+++ b/redox-rt/src/signal.rs
@@ -29,19 +29,22 @@ pub fn sighandler_function() -> usize {
 #[repr(C)]
 pub struct SigStack {
     #[cfg(target_arch = "x86_64")]
-    fx: [u8; 4096],
+    fx: [u8; 4096], // 64 byte aligned
 
     #[cfg(target_arch = "x86")]
-    fx: [u8; 512],
+    fx: [u8; 512], // 16 byte aligned
 
     #[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
+    _pad: [usize; 3], // pad to 64 = 4 * 16 = 52 + 12 bytes
 
     sig_num: usize,
-    pub regs: ArchIntRegs, // 160 bytes currently
+
+    // x86_64: 160 bytes
+    // i686: 48 bytes
+    pub regs: ArchIntRegs,
 }
 
 #[inline(always)]