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

Improve i686 trampoline and fix PIC.

parent 5460ffc4
No related branches found
No related tags found
No related merge requests found
use core::mem::offset_of;
use core::sync::atomic::Ordering;
use syscall::*;
use crate::proc::{fork_inner, FdGuard};
use crate::signal::{inner_fastcall, RtSigarea, SigStack};
use crate::signal::{inner_fastcall, PROC_CONTROL_STRUCT, 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;
......@@ -18,7 +19,6 @@ pub struct SigArea {
pub tmp_esp: usize,
pub tmp_eax: usize,
pub tmp_edx: usize,
pub onstack: u64,
pub disable_signals_depth: u64,
}
#[derive(Debug, Default)]
......@@ -144,7 +144,10 @@ asmfunction!(__relibc_internal_sigentry: ["
add eax, 32
2:
and esp, -{STACK_ALIGN}
bt gs:[{tcb_sa_off} + {sa_onstack}], eax
mov edx, eax
add edx, edx
bt dword ptr [{pctl} + {pctl_off_actions} + edx * 8 + 4], 28
jnc 4f
mov edx, gs:[{tcb_sa_off} + {sa_altstack_top}]
......@@ -209,15 +212,14 @@ __relibc_internal_sigentry_crit_second:
sa_tmp_edx = const offset_of!(SigArea, tmp_edx),
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_eflags = const offset_of!(Sigcontrol, saved_archdep_reg),
sc_saved_eip = const offset_of!(Sigcontrol, saved_ip),
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
),
pctl_off_actions = const offset_of!(SigProcControl, actions),
pctl = sym PROC_CONTROL_STRUCT,
SIGW0_PENDING_MASK = const !0,
SIGW1_PENDING_MASK = const !0,
STACK_ALIGN = const 16,
]);
......@@ -253,3 +255,20 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
stack.regs.eip = area.tmp_eip;
}
}
pub unsafe fn manually_enter_trampoline() {
let c = &crate::Tcb::current().unwrap().os_specific.control;
c.control_flags.store(c.control_flags.load(Ordering::Relaxed) | syscall::flag::INHIBIT_DELIVERY.bits(), Ordering::Release);
c.saved_archdep_reg.set(0); // TODO: Just reset DF on x86?
core::arch::asm!("
call 2f
jmp 3f
2:
pop dword ptr gs:[{tcb_sc_off} + {sc_saved_eip}]
jmp __relibc_internal_sigentry
3:
",
tcb_sc_off = const offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control),
sc_saved_eip = const offset_of!(Sigcontrol, saved_ip),
);
}
use core::mem::offset_of;
use core::sync::atomic::AtomicU8;
use core::sync::atomic::{AtomicU8, Ordering};
use syscall::data::{Sigcontrol, SigProcControl};
use syscall::error::*;
......@@ -360,10 +360,9 @@ pub unsafe fn arch_pre(stack: &mut SigStack, area: &mut SigArea) {
static SUPPORTS_XSAVE: AtomicU8 = AtomicU8::new(1); // FIXME
pub unsafe fn manually_enter_trampoline() {
let _g = tmp_disable_signals();
let a = &Tcb::current().unwrap().os_specific.control;
a.saved_archdep_reg.set(0); // TODO: Just reset DF on x86?
let c = &Tcb::current().unwrap().os_specific.control;
c.control_flags.store(c.control_flags.load(Ordering::Relaxed) | syscall::flag::INHIBIT_DELIVERY.bits(), Ordering::Release);
c.saved_archdep_reg.set(0); // TODO: Just reset DF on x86?
core::arch::asm!("
lea rax, [rip + 2f]
......
......@@ -111,10 +111,13 @@ unsafe fn inner(stack: &mut SigStack) {
// Call handler, either sa_handler or sa_siginfo depending on flag.
if sigaction.flags.contains(SigactionFlags::SIGINFO) && let Some(sigaction) = handler.sigaction {
//let _ = syscall::write(1, alloc::format!("SIGACTION {:p}\n", sigaction).as_bytes());
sigaction(stack.sig_num as c_int, core::ptr::null_mut(), core::ptr::null_mut());
} else if let Some(handler) = handler.handler {
//let _ = syscall::write(1, alloc::format!("HANDLER {:p}\n", handler).as_bytes());
handler(stack.sig_num as c_int);
}
//let _ = syscall::write(1, alloc::format!("RETURNED HANDLER\n").as_bytes());
// Disable signals while we modify the sigmask again
control_flags.store(control_flags.load(Ordering::Relaxed) | SigcontrolFlags::INHIBIT_DELIVERY.bits(), Ordering::Release);
......@@ -129,6 +132,8 @@ unsafe fn inner(stack: &mut SigStack) {
// TODO: If resetting the sigmask caused signals to be unblocked, then should they be delivered
// here? And would it be possible to tail-call-optimize that?
//let _ = syscall::write(1, alloc::format!("will return to {:x?}\n", stack.regs.eip).as_bytes());
// And re-enable them again
control_flags.store(control_flags.load(Ordering::Relaxed) & !SigcontrolFlags::INHIBIT_DELIVERY.bits(), Ordering::Release);
core::sync::atomic::compiler_fence(Ordering::Acquire);
......@@ -388,7 +393,10 @@ pub fn setup_sighandler(area: &RtSigarea) {
// equivalent to not using any altstack at all (the default).
arch.altstack_top = usize::MAX;
arch.altstack_bottom = 0;
arch.pctl = core::ptr::addr_of!(PROC_CONTROL_STRUCT) as usize;
#[cfg(not(target_arch = "x86"))]
{
arch.pctl = core::ptr::addr_of!(PROC_CONTROL_STRUCT) as usize;
}
}
#[cfg(target_arch = "x86_64")]
......
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