Write draft aarch64 trampoline that compiles.
This commit is contained in:
@@ -1,19 +1,68 @@
|
||||
use core::mem::offset_of;
|
||||
|
||||
use syscall::data::*;
|
||||
use syscall::error::*;
|
||||
|
||||
use crate::proc::{fork_inner, FdGuard};
|
||||
use crate::signal::inner_c;
|
||||
use crate::signal::SigStack;
|
||||
use crate::signal::{inner_c, RtSigarea, PROC_CONTROL_STRUCT};
|
||||
use crate::Tcb;
|
||||
|
||||
// Setup a stack starting from the very end of the address space, and then growing downwards.
|
||||
pub(crate) const STACK_TOP: usize = 1 << 47;
|
||||
pub(crate) const STACK_SIZE: usize = 1024 * 1024;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[repr(C)]
|
||||
pub struct SigArea {
|
||||
pub altstack_top: usize,
|
||||
pub altstack_bottom: usize,
|
||||
pub tmp: usize,
|
||||
pub tmp_x1_x2: [usize; 2],
|
||||
pub tmp_x3_x4: [usize; 2],
|
||||
pub tmp_sp: usize,
|
||||
pub onstack: u64,
|
||||
pub disable_signals_depth: u64,
|
||||
pub pctl: usize, // TODO: remove
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Default)]
|
||||
pub struct ArchIntRegs {
|
||||
pub x30: usize,
|
||||
pub x29: usize,
|
||||
pub x28: usize,
|
||||
pub x27: usize,
|
||||
pub x26: usize,
|
||||
pub x25: usize,
|
||||
pub x24: usize,
|
||||
pub x23: usize,
|
||||
pub x22: usize,
|
||||
pub x21: usize,
|
||||
pub x20: usize,
|
||||
pub x19: usize,
|
||||
pub x18: usize,
|
||||
pub x17: usize,
|
||||
pub x16: usize,
|
||||
pub x15: usize,
|
||||
pub x14: usize,
|
||||
pub x13: usize,
|
||||
pub x12: usize,
|
||||
pub x11: usize,
|
||||
pub x10: usize,
|
||||
pub x9: usize,
|
||||
pub x8: usize,
|
||||
pub x7: usize,
|
||||
pub x6: usize,
|
||||
pub x5: usize,
|
||||
pub x4: usize,
|
||||
pub x3: usize,
|
||||
pub x2: usize,
|
||||
pub x1: usize,
|
||||
|
||||
pub sp: usize,
|
||||
pub nzcv: usize, // user-accessible PSTATE bits
|
||||
|
||||
pub pc: usize,
|
||||
pub x0: usize,
|
||||
}
|
||||
|
||||
/// Deactive TLS, used before exec() on Redox to not trick target executable into thinking TLS
|
||||
@@ -91,12 +140,112 @@ asmfunction!(__relibc_internal_fork_ret: ["
|
||||
"] <= [child_hook = sym child_hook]);
|
||||
|
||||
asmfunction!(__relibc_internal_sigentry: ["
|
||||
// old pc and x0 are saved in the sigcontrol struct
|
||||
mrs x0, tpidr_el0 // ABI ptr
|
||||
ldr x0, [x0] // TCB ptr
|
||||
|
||||
// save x1-x3 and sp
|
||||
stp x1, x2, [x0, #{tcb_sa_off} + {sa_tmp_x1_x2}]
|
||||
stp x3, x4, [x0, #{tcb_sa_off} + {sa_tmp_x3_x4}]
|
||||
mov x1, sp
|
||||
str x1, [x0, #{tcb_sa_off} + {sa_tmp_sp}]
|
||||
|
||||
sub x1, x1, 128
|
||||
and x1, x1, -16
|
||||
mov sp, x1
|
||||
|
||||
ldr x3, [x0, #{tcb_sa_off} + {sa_pctl}]
|
||||
|
||||
// load x1 and x2 with each word (tearing between x1 and x2 can occur)
|
||||
// acquire ordering
|
||||
add x2, x0, #{tcb_sc_off} + {sc_word}
|
||||
ldaxp x1, x2, [x2]
|
||||
|
||||
// reduce them by ANDing the upper and lower 32 bits
|
||||
and x1, x1, x1, lsr #32 // put result in lo half
|
||||
and x2, x2, x2, lsl #32 // put result in hi half
|
||||
orr x1, x1, x2 // combine them into the set of pending unblocked
|
||||
|
||||
// count trailing zeroes, to find signal bit
|
||||
rbit x1, x1
|
||||
clz x1, x1
|
||||
mov x2, #32
|
||||
sub x1, x2, x1
|
||||
|
||||
// TODO: NOT ATOMIC!
|
||||
add x2, x3, w1, uxtb #4 // actions_base + sig_idx * sizeof Action
|
||||
ldxp x2, x3, [x2]
|
||||
|
||||
// skip sigaltstack step if SA_ONSTACK is clear
|
||||
// tbz x2, #57, 2f
|
||||
2:
|
||||
ldr x2, [x0, #{tcb_sc_off} + {sc_saved_pc}]
|
||||
ldr x3, [x0, #{tcb_sc_off} + {sc_saved_x0}]
|
||||
stp x2, x3, [sp], #-16
|
||||
|
||||
ldr x2, [x0, #{tcb_sa_off} + {sa_tmp_sp}]
|
||||
mrs x3, nzcv
|
||||
stp x2, x3, [sp], #-16
|
||||
|
||||
ldp x2, x3, [x0, #{tcb_sa_off} + {sa_tmp_x1_x2}]
|
||||
stp x2, x3, [sp], #-16
|
||||
ldp x3, x4, [x0, #{tcb_sa_off} + {sa_tmp_x3_x4}]
|
||||
stp x4, x3, [sp], #-16
|
||||
stp x6, x5, [sp], #-16
|
||||
stp x8, x7, [sp], #-16
|
||||
stp x10, x9, [sp], #-16
|
||||
stp x12, x11, [sp], #-16
|
||||
stp x14, x13, [sp], #-16
|
||||
stp x16, x15, [sp], #-16
|
||||
stp x18, x17, [sp], #-16
|
||||
stp x20, x19, [sp], #-16
|
||||
stp x22, x21, [sp], #-16
|
||||
stp x24, x23, [sp], #-16
|
||||
stp x26, x25, [sp], #-16
|
||||
stp x28, x27, [sp], #-16
|
||||
stp x30, x29, [sp], #-16
|
||||
|
||||
mov x0, sp
|
||||
bl {inner}
|
||||
|
||||
// FIXME
|
||||
b .
|
||||
"] <= [inner = sym inner_c]);
|
||||
ldp x30, x29, [sp], #16
|
||||
ldp x28, x27, [sp], #16
|
||||
ldp x26, x25, [sp], #16
|
||||
ldp x24, x23, [sp], #16
|
||||
ldp x22, x21, [sp], #16
|
||||
ldp x20, x19, [sp], #16
|
||||
ldp x18, x17, [sp], #16
|
||||
ldp x16, x15, [sp], #16
|
||||
ldp x14, x13, [sp], #16
|
||||
ldp x12, x11, [sp], #16
|
||||
ldp x10, x9, [sp], #16
|
||||
ldp x8, x7, [sp], #16
|
||||
ldp x6, x5, [sp], #16
|
||||
ldp x4, x3, [sp], #16
|
||||
ldp x2, x1, [sp], #16
|
||||
ldr x0, [sp, #8]
|
||||
msr nzcv, x0
|
||||
|
||||
// x18 is reserved by ABI as 'platform register', so clobbering it should be safe.
|
||||
mov x18, sp
|
||||
ldr x0, [sp], #16
|
||||
mov sp, x0
|
||||
mov x0, x18
|
||||
|
||||
ldp x18, x0, [x0]
|
||||
br x18
|
||||
"] <= [
|
||||
tcb_sc_off = const (offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, control)),
|
||||
tcb_sa_off = const (offset_of!(crate::Tcb, os_specific) + offset_of!(RtSigarea, arch)),
|
||||
sa_tmp_x1_x2 = const offset_of!(SigArea, tmp_x1_x2),
|
||||
sa_tmp_x3_x4 = const offset_of!(SigArea, tmp_x3_x4),
|
||||
sa_tmp_sp = const offset_of!(SigArea, tmp_sp),
|
||||
sa_pctl = const offset_of!(SigArea, pctl),
|
||||
sc_saved_pc = const offset_of!(Sigcontrol, saved_ip),
|
||||
sc_saved_x0 = const offset_of!(Sigcontrol, saved_archdep_reg),
|
||||
sc_word = const offset_of!(Sigcontrol, word),
|
||||
inner = sym inner_c,
|
||||
]);
|
||||
|
||||
asmfunction!(__relibc_internal_rlct_clone_ret: ["
|
||||
# Load registers
|
||||
@@ -109,3 +258,29 @@ asmfunction!(__relibc_internal_rlct_clone_ret: ["
|
||||
|
||||
ret
|
||||
"] <= []);
|
||||
|
||||
pub fn current_sp() -> usize {
|
||||
let sp: usize;
|
||||
unsafe {
|
||||
core::arch::asm!("mov {}, sp", out(reg) sp);
|
||||
}
|
||||
sp
|
||||
}
|
||||
|
||||
pub unsafe fn manually_enter_trampoline() {
|
||||
let ctl = &Tcb::current().unwrap().os_specific.control;
|
||||
|
||||
ctl.saved_archdep_reg.set(0);
|
||||
let ip_location = &ctl.saved_ip as *const _ as usize;
|
||||
|
||||
core::arch::asm!("
|
||||
bl 2f
|
||||
b 3f
|
||||
2:
|
||||
ldr lr, [x0]
|
||||
b __relibc_internal_sigentry
|
||||
3:
|
||||
", inout("x0") ip_location => _, out("lr") _);
|
||||
}
|
||||
|
||||
pub unsafe fn arch_pre(stack: &mut SigStack, os: &mut SigArea) {}
|
||||
|
||||
Reference in New Issue
Block a user