Improve i686 trampoline and fix PIC.
This commit is contained in:
@@ -1,9 +1,10 @@
|
||||
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),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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")]
|
||||
|
||||
Reference in New Issue
Block a user