Fix i686 trampoline.

This commit is contained in:
4lDO2
2024-06-27 16:58:24 +02:00
parent 5b8d53ddd3
commit 39f45b0f67
2 changed files with 58 additions and 20 deletions
+51 -16
View File
@@ -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;
}
}
+7 -4
View File
@@ -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)]