From 6be0751865f4fa27bb25468592f4d634357a103c Mon Sep 17 00:00:00 2001 From: Olivier Houchard Date: Sat, 10 Feb 2018 22:41:48 +0100 Subject: [PATCH] WIP: FREEBSD_COMPAT32 support on aarch64 --- sys/arm/include/reg.h | 7 + sys/arm64/arm64/elf32_machdep.c | 232 +++++++++++++++- sys/arm64/arm64/freebsd32_machdep.c | 360 ++++++++++++++++++++++++- sys/arm64/arm64/locore.S | 19 ++ sys/arm64/arm64/machdep.c | 27 +- sys/arm64/arm64/trap.c | 7 +- sys/arm64/arm64/undefined.c | 33 +++ sys/arm64/arm64/vm_machdep.c | 27 +- sys/arm64/conf/GENERIC | 4 +- sys/arm64/include/armreg.h | 5 + sys/arm64/include/armv6_signal.h | 62 +++++ sys/arm64/include/cpu.h | 3 +- sys/arm64/include/elf.h | 4 + sys/arm64/include/param.h | 3 + sys/arm64/include/pcb.h | 1 + sys/arm64/include/reg.h | 6 +- sys/arm64/include/vfp.h | 5 + sys/compat/freebsd32/freebsd32_misc.c | 4 + sys/compat/freebsd32/freebsd32_proto.h | 16 +- sys/compat/freebsd32/freebsd32_syscalls.c | 2 +- sys/compat/freebsd32/freebsd32_sysent.c | 2 +- sys/compat/freebsd32/freebsd32_systrace_args.c | 6 +- sys/compat/freebsd32/syscalls.master | 3 +- sys/conf/files.arm64 | 2 + sys/kern/kern_exec.c | 6 + sys/kern/kern_proc.c | 5 +- sys/kern/kern_sharedpage.c | 14 +- sys/kern/kern_tc.c | 5 +- sys/sys/vdso.h | 2 +- 29 files changed, 820 insertions(+), 52 deletions(-) create mode 100644 sys/arm64/include/armv6_signal.h diff --git a/sys/arm/include/reg.h b/sys/arm/include/reg.h index ab70ae128d3..93ed78b208e 100644 --- a/sys/arm/include/reg.h +++ b/sys/arm/include/reg.h @@ -37,6 +37,13 @@ int fill_fpregs(struct thread *, struct fpreg *); int set_fpregs(struct thread *, struct fpreg *); int fill_dbregs(struct thread *, struct dbreg *); int set_dbregs(struct thread *, struct dbreg *); + +int fill_regs32(struct thread *, struct reg32 *); +int set_regs32(struct thread *, struct reg32 *); +int fill_fpregs32(struct thread *, struct fpreg32 *); +int set_fpregs32(struct thread *, struct fpreg32 *); +int fill_dbregs32(struct thread *, struct dbreg32 *); +int set_dbregs32(struct thread *, struct dbreg32 *); #endif #endif /* !MACHINE_REG_H */ diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c index 4e1b416c3e0..7ae7382a6e9 100644 --- a/sys/arm64/arm64/elf32_machdep.c +++ b/sys/arm64/arm64/elf32_machdep.c @@ -1,5 +1,13 @@ /*- - * Copyright (c) 2017 Nuxi, https://nuxi.nl/ + * Copyright (c) 2014, 2015 The FreeBSD Foundation. + * Copyright (c) 2014, 2017 Andrew Turner. + * All rights reserved. + * + * This software was developed by Andrew Turner under + * sponsorship from the FreeBSD Foundation. + * + * Portions of this software were developed by Konstantin Belousov + * under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,13 +34,225 @@ #include __FBSDID("$FreeBSD$"); -#include -#define __ELF_WORD_SIZE 32 +#define __ELF_WORD_SIZE 32 + +#include +#include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include -void -elf32_dump_thread(struct thread *td __unused, void *dst __unused, - size_t *off __unused) +#include +#include + +#include + +#define FREEBSD32_MINUSER 0x00001000 +#define FREEBSD32_MAXUSER ((1ul << 32) - PAGE_SIZE) +#define FREEBSD32_SHAREDPAGE (FREEBSD32_MAXUSER - PAGE_SIZE) +#define FREEBSD32_USRSTACK FREEBSD32_SHAREDPAGE + +extern const char *freebsd32_syscallnames[]; + +extern char armv6_sigcode[]; +extern int sz_armv6_sigcode; + +static int armv6_fetch_syscall_args(struct thread *td); +static void armv6_setregs(struct thread *td, struct image_params *imgp, + u_long stack); +static void armv6_set_syscall_retval(struct thread *, int); + +static boolean_t elf32_arm_abi_supported(struct image_params *); + +static struct sysentvec armv6_freebsd_sysvec = { + .sv_size = SYS_MAXSYSCALL, + .sv_table = freebsd32_sysent, + .sv_mask = 0, + .sv_errsize = 0, + .sv_errtbl = NULL, + .sv_transtrap = NULL, + .sv_fixup = elf32_freebsd_fixup, + .sv_sendsig = armv6_sendsig, + .sv_sigcode = armv6_sigcode, + .sv_szsigcode = &sz_armv6_sigcode, + .sv_name = "FreeBSD ELF32", + .sv_coredump = elf32_coredump, + .sv_imgact_try = NULL, + .sv_minsigstksz = MINSIGSTKSZ, + .sv_pagesize = PAGE_SIZE, + .sv_minuser = FREEBSD32_MINUSER, + .sv_maxuser = FREEBSD32_MAXUSER, + .sv_usrstack = FREEBSD32_USRSTACK, + .sv_psstrings = FREEBSD32_PS_STRINGS, + .sv_stackprot = VM_PROT_READ | VM_PROT_WRITE, + .sv_copyout_strings = freebsd32_copyout_strings, + .sv_setregs = armv6_setregs, + .sv_fixlimit = NULL, // XXX + .sv_maxssiz = NULL, + .sv_flags = SV_ABI_FREEBSD | SV_ILP32 | SV_SHP | SV_TIMEKEEP, + .sv_set_syscall_retval = armv6_set_syscall_retval, + .sv_fetch_syscall_args = armv6_fetch_syscall_args, + .sv_syscallnames = freebsd32_syscallnames, + .sv_shared_page_base = FREEBSD32_SHAREDPAGE, + .sv_shared_page_len = PAGE_SIZE, + .sv_schedtail = NULL, + .sv_thread_detach = NULL, + .sv_trap = NULL, +}; +INIT_SYSENTVEC(armv6_sysvec, &armv6_freebsd_sysvec); + +static Elf32_Brandinfo armv6_brand_info = { + .brand = ELFOSABI_FREEBSD, + .machine = EM_ARM, + .compat_3_brand = "FreeBSD", + .emul_path = NULL, + .interp_path = "/libexec/ld-elf.so.1", + .sysvec = &armv6_freebsd_sysvec, + .interp_newpath = NULL, + .brand_note = &elf32_freebsd_brandnote, + .flags = BI_CAN_EXEC_DYN | BI_BRAND_NOTE, + .header_supported= elf32_arm_abi_supported, +}; + +SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, + (sysinit_cfunc_t)elf32_insert_brand_entry, &armv6_brand_info); + +static boolean_t +elf32_arm_abi_supported(struct image_params *imgp) +{ + const Elf32_Ehdr *hdr; + + /* Check if we support AArch32 */ + if (ID_AA64PFR0_EL0(READ_SPECIALREG(id_aa64pfr0_el1)) != + ID_AA64PFR0_EL0_64_32) + return (FALSE); + +#define EF_ARM_EABI_VERSION(x) (((x) & EF_ARM_EABIMASK) >> 24) +#define EF_ARM_EABI_FREEBSD_MIN 4 + hdr = (const Elf32_Ehdr *)imgp->image_header; + if (EF_ARM_EABI_VERSION(hdr->e_flags) < EF_ARM_EABI_FREEBSD_MIN) { + if (bootverbose) + uprintf("Attempting to execute non EABI binary " + "(rev %d) image %s", + EF_ARM_EABI_VERSION(hdr->e_flags), + imgp->args->fname); + return (FALSE); + } + + return (TRUE); +} + +static int +armv6_fetch_syscall_args(struct thread *td) { + struct proc *p; + register_t *ap; + struct syscall_args *sa; + int error, i, nap; + unsigned int args[4]; + nap = 4; + p = td->td_proc; + ap = td->td_frame->tf_x; + sa = &td->td_sa; + + /* r7 is the syscall id */ + sa->code = td->td_frame->tf_x[7]; + + if (sa->code == SYS_syscall) { + sa->code = *ap++; + nap--; + } else if (sa->code == SYS___syscall) { + sa->code = ap[1]; + nap -= 2; + ap += 2; + } + + if (sa->code >= p->p_sysent->sv_size) + sa->callp = &p->p_sysent->sv_table[0]; + else + sa->callp = &p->p_sysent->sv_table[sa->code]; + + sa->narg = sa->callp->sy_narg; + for (i = 0; i < nap; i++) + sa->args[i] = ap[i]; + if (sa->narg > nap) { + if ((sa->narg - nap) > nitems(args)) + panic("Too many system call arguiments"); + error = copyin((void *)td->td_frame->tf_x[13], args, + (sa->narg - nap) * sizeof(int)); + for (i = 0; i < (sa->narg - nap); i++) + sa->args[i + nap] = args[i]; + } + + td->td_retval[0] = 0; + td->td_retval[1] = 0; + + return (0); +} + +static void +armv6_set_syscall_retval(struct thread *td, int error) +{ + struct trapframe *frame; + + frame = td->td_frame; + switch (error) { + case 0: + frame->tf_x[0] = td->td_retval[0]; + frame->tf_x[1] = td->td_retval[1]; + frame->tf_spsr &= ~PSR_C; + break; + case ERESTART: + /* + * Reconstruct the pc to point at the swi. + */ + if ((frame->tf_spsr & PSR_T) != 0) + frame->tf_elr -= 2; //THUMB_INSN_SIZE; + else + frame->tf_elr -= 4; //INSN_SIZE; + break; + case EJUSTRETURN: + /* nothing to do */ + break; + default: + frame->tf_x[0] = error; + frame->tf_spsr |= PSR_C; + break; + } +} + +static void +armv6_setregs(struct thread *td, struct image_params *imgp, + u_long stack) +{ + struct trapframe *tf = td->td_frame; + + memset(tf, 0, sizeof(struct trapframe)); + + /* + * We need to set x0 for init as it doesn't call + * cpu_set_syscall_retval to copy the value. We also + * need to set td_retval for the cases where we do. + */ + tf->tf_x[0] = stack; + /* SP_usr is mapped to x13 */ + tf->tf_x[13] = stack; + /* LR_usr is mapped to x14 */ + tf->tf_x[14] = imgp->entry_addr; + tf->tf_elr = imgp->entry_addr; + tf->tf_spsr = PSR_M_32; +} + +void +elf32_dump_thread(struct thread *td, void *dst, size_t *off) +{ + /* XXX: VFP */ } diff --git a/sys/arm64/arm64/freebsd32_machdep.c b/sys/arm64/arm64/freebsd32_machdep.c index e76ee9552e3..13d1089ae5a 100644 --- a/sys/arm64/arm64/freebsd32_machdep.c +++ b/sys/arm64/arm64/freebsd32_machdep.c @@ -27,44 +27,390 @@ __FBSDID("$FreeBSD$"); #include +#include +#include +#include +#include +#include +#include +#include +#ifdef VFP +#include +#endif #include +#include + +/* + * The first two fields of a ucontext_t are the signal mask and the machine + * context. The next field is uc_link; we want to avoid destroying the link + * when copying out contexts. + */ +#define UC32_COPY_SIZE offsetof(struct armv6_ucontext, uc_link) + +#ifdef VFP +static void armv6_get_fpcontext(struct thread *td, struct armv6_mcontext_vfp *); +#endif /* * Stubs for machine dependent 32-bits system calls. */ int +freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) +{ + int error; + +#define ARM_SYNC_ICACHE 0 +#define ARM_DRAIN_WRITEBUF 1 +#define ARM_SET_TP 2 +#define ARM_GET_TP 3 +#define ARM_GET_VFPSTATE 4 + + switch(uap->op) { + case ARM_SET_TP: + printf("setting tp writing %p\n", uap->parms); + WRITE_SPECIALREG(TPIDR_EL0, uap->parms); + WRITE_SPECIALREG(TPIDRRO_EL0, uap->parms); + return 0; + case ARM_SYNC_ICACHE: + { + struct { + uint32_t addr; + uint32_t size; + } args; + + if ((error = copyin(uap->parms, &args, sizeof(args))) != 0) + return (error); + if ((uint64_t)args.addr + (uint64_t)args.size > 0xffffffff) + return (EINVAL); + cpu_icache_sync_range(args.addr, args.size); + return 0; + } + case ARM_GET_VFPSTATE: + { + struct armv6_mcontext_vfp mcontext_vfp; + + struct { + uint32_t mc_vfp_size; + uint32_t mc_vfp; + } args; + if ((error = copyin(uap->parms, &args, sizeof(args))) != 0) + return (error); + if (args.mc_vfp_size != sizeof(mcontext_vfp)) + return (EINVAL); +#ifdef VFP + armv6_get_fpcontext(td, &mcontext_vfp); +#else + bzero(&mcontext_vfp, sizeof(mcontext_vfp)); +#endif + error = copyout(&mcontext_vfp, + (void *)(uintptr_t)args.mc_vfp, + sizeof(mcontext_vfp)); + return error; + } + } + + return (EINVAL); +} + + +#include + +#ifdef VFP +static void +armv6_get_fpcontext(struct thread *td, struct armv6_mcontext_vfp *mcp) +{ + struct pcb *curpcb; + + critical_enter(); + curpcb = curthread->td_pcb; + + if ((curpcb->pcb_fpflags & PCB_FP_STARTED) != 0) { + /* + * If we have just been running VFP instructions we will + * need to save the state to memcpy it below. + */ + vfp_save_state(td, curpcb); + + KASSERT(curpcb->pcb_fpusaved == &curpcb->pcb_fpustate, + ("Called get_fpcontext while the kernel is using the VFP")); + KASSERT((curpcb->pcb_fpflags & ~PCB_FP_USERMASK) == 0, + ("Non-userspace FPU flags set in get_fpcontext")); + memcpy(mcp->mcv_reg, curpcb->pcb_fpustate.vfp_regs, + sizeof(mcp->mcv_reg)); + mcp->mcv_fpscr = VFP_FPSCR_FROM_SRCR(curpcb->pcb_fpustate.vfp_fpcr, + curpcb->pcb_fpustate.vfp_fpsr); + } + critical_exit(); +} + +static void +armv6_set_fpcontext(struct thread *td, struct armv6_mcontext_vfp *mcp) +{ + struct pcb *pcb; + + critical_enter(); + pcb = td->td_pcb; + if (td == curthread) + vfp_discard(td); + memcpy(pcb->pcb_fpustate.vfp_regs, mcp->mcv_reg, + sizeof(pcb->pcb_fpustate.vfp_regs)); + pcb->pcb_fpustate.vfp_fpsr = VFP_FPSR_FROM_FPSCR(mcp->mcv_fpscr); + pcb->pcb_fpustate.vfp_fpcr = VFP_FPSR_FROM_FPSCR(mcp->mcv_fpscr); + critical_exit(); +} +#endif +static void +armv6_get_mcontext(struct thread *td, struct armv6_mcontext *mcp, int flags) +{ + struct pcb *pcb; + struct trapframe *tf; + int i; + + pcb = td->td_pcb; + tf = td->td_frame; + + if ((flags & GET_MC_CLEAR_RET) != 0) { + mcp->mc_gregset[0] = 0; + mcp->mc_gregset[16] = tf->tf_spsr & ~PSR_C; + } else { + mcp->mc_gregset[0] = tf->tf_x[0]; + mcp->mc_gregset[16] = tf->tf_spsr; + } + for (i = 1; i < 15; i++) + mcp->mc_gregset[i] = tf->tf_x[i]; + mcp->mc_gregset[15] = tf->tf_elr; + + mcp->mc_vfp_size = 0; + mcp->mc_vfp_ptr = 0; + + memset(mcp->mc_spare, 0, sizeof(mcp->mc_spare)); +} + +static int +armv6_set_mcontext(struct thread *td, struct armv6_mcontext *mcp) +{ + struct trapframe *tf; + struct armv6_mcontext_vfp mc_vfp; + int i; + + tf = td->td_frame; + + for (i = 0; i < 15; i++) + tf->tf_x[i] = mcp->mc_gregset[i]; + tf->tf_elr = mcp->mc_gregset[15]; + tf->tf_spsr = mcp->mc_gregset[16]; +#ifdef VFP + if (mcp->mc_vfp_size == sizeof(mc_vfp) && mcp->mc_vfp_ptr != 0) { + if (copyin((void *)(uintptr_t)mcp->mc_vfp_ptr, &mc_vfp, + sizeof(mc_vfp)) != 0) + return (EFAULT); + armv6_set_fpcontext(td, &mc_vfp); + } +#endif + + return (0); +} + +#define UC_COPY_SIZE offsetof(struct armv6_ucontext, uc_link) + +int freebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) { + struct armv6_ucontext uc; + int ret; - return (ENOSYS); + if (uap->ucp == NULL) + ret = EINVAL; + else { + memset(&uc, 0, sizeof(uc)); + armv6_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); + PROC_LOCK(td->td_proc); + uc.uc_sigmask = td->td_sigmask; + PROC_UNLOCK(td->td_proc); + ret = copyout(&uc, uap->ucp, UC_COPY_SIZE); + } + return (ret); } int freebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) { + struct armv6_ucontext uc; + int ret; - return (ENOSYS); + if (uap->ucp == NULL) + ret = EINVAL; + else { + ret = copyin(uap->ucp, &uc, UC_COPY_SIZE); + if (ret == 0) { + ret = armv6_set_mcontext(td, &uc.uc_mcontext); + if (ret == 0) + kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, + NULL, 0); + } + } + return (ret); } int freebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) { + struct armv6_ucontext uc; + int error; + + if (uap == NULL) + return (EFAULT); + if (copyin(uap->sigcntxp, &uc, sizeof(uc))) + return (EFAULT); + error = armv6_set_mcontext(td, &uc.uc_mcontext); + if (error != 0) + return (0); + + /* Restore signal mask. */ + kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); + printf("returning lol\n"); + + return (EJUSTRETURN); - return (ENOSYS); } int freebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) { + struct armv6_ucontext uc; + int ret; - return (ENOSYS); + if (uap->oucp == NULL || uap->ucp == NULL) + ret = EINVAL; + else { + armv6_get_mcontext(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); + PROC_LOCK(td->td_proc); + uc.uc_sigmask = td->td_sigmask; + PROC_UNLOCK(td->td_proc); + ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE); + if (ret == 0) { + ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); + if (ret == 0) { + ret = armv6_set_mcontext(td, &uc.uc_mcontext); + kern_sigprocmask(td, SIG_SETMASK, + &uc.uc_sigmask, NULL, 0); + } + } + } + return (ret); } -int -freebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) +void +armv6_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { + struct thread *td; + struct proc *p; + struct trapframe *tf; + struct armv6_sigframe *fp, frame; + struct sigacts *psp; + struct siginfo32 siginfo; + struct sysentvec *sysent; + int onstack; + int sig; + int code; + + printf("sendsig %s\n", curthread->td_proc->p_comm); + siginfo_to_siginfo32(&ksi->ksi_info, &siginfo); + td = curthread; + p = td->td_proc; + PROC_LOCK_ASSERT(p, MA_OWNED); + sig = ksi->ksi_signo; + code = ksi->ksi_code; + psp = p->p_sigacts; + mtx_assert(&psp->ps_mtx, MA_OWNED); + tf = td->td_frame; + onstack = sigonstack(tf->tf_x[13]); + + CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm, + catcher, sig); + + printf("onstack %d altstack %d\n", onstack, td->td_pflags & TDP_ALTSTACK); + /* Allocate and validate space for the signal handler context. */ + if ((td->td_pflags & TDP_ALTSTACK) != 0 && !(onstack) && + SIGISMEMBER(psp->ps_sigonstack, sig)) { + fp = (struct armv6_sigframe *)((uintptr_t)td->td_sigstk.ss_sp + + td->td_sigstk.ss_size); +#if defined(COMPAT_43) + td->td_sigstk.ss_flags |= SS_ONSTACK; +#endif + } else + fp = (struct armv6_sigframe *)td->td_frame->tf_x[13]; + + /* make room on the stack */ + fp--; + + /* make the stack aligned */ + fp = (struct armv6_sigframe *)((unsigned long)(fp) &~ (8 - 1)); + /* Populate the siginfo frame. */ + armv6_get_mcontext(td, &frame.sf_uc.uc_mcontext, 0); +#ifdef VFP + armv6_get_fpcontext(td, &frame.sf_vfp); + frame.sf_uc.uc_mcontext.mc_vfp_size = sizeof(fp->sf_vfp); + frame.sf_uc.uc_mcontext.mc_vfp_ptr = (uint32_t)(uintptr_t)&fp->sf_vfp; +#else + frame.sf_uc.uc_mcontext.mc_vfp_size = 0; + frame.sf_uc.uc_mcontext.mc_vfp_ptr = (uint32_t)NULL; +#endif + frame.sf_si = siginfo; + frame.sf_uc.uc_sigmask = *mask; + frame.sf_uc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK ) + ? ((onstack) ? SS_ONSTACK : 0) : SS_DISABLE; + frame.sf_uc.uc_stack.ss_sp = (uintptr_t)td->td_sigstk.ss_sp; + frame.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; + + mtx_unlock(&psp->ps_mtx); + PROC_UNLOCK(td->td_proc); + + /* Copy the sigframe out to the user's stack. */ + if (copyout(&frame, fp, sizeof(*fp)) != 0) { + /* Process has trashed its stack. Kill it. */ + CTR2(KTR_SIG, "sendsig: sigexit td=%p fp=%p", td, fp); + PROC_LOCK(p); + sigexit(td, SIGILL); + } + + /* + * Build context to run handler in. We invoke the handler + * directly, only returning via the trampoline. Note the + * trampoline version numbers are coordinated with machine- + * dependent code in libc. + */ + + tf->tf_x[0] = sig; + tf->tf_x[1] = (register_t)&fp->sf_si; + tf->tf_x[2] = (register_t)&fp->sf_uc; + + /* the trampoline uses r5 as the uc address */ + tf->tf_x[5] = (register_t)&fp->sf_uc; + tf->tf_elr = (register_t)catcher; + tf->tf_x[13] = (register_t)fp; + sysent = p->p_sysent; + if (sysent->sv_sigcode_base != 0) + tf->tf_x[14] = (register_t)sysent->sv_sigcode_base; + else + tf->tf_x[14] = (register_t)(sysent->sv_psstrings - + *(sysent->sv_szsigcode)); + printf("addr is %lx\n", tf->tf_x[14]); + for (int i = 0; i < *(sysent->sv_szsigcode); i += 4) { + printf("got %x\n", *(int *)(tf->tf_x[14] + i)); + } + /* Set the mode to enter in the signal handler */ + if ((register_t)catcher & 1) + tf->tf_spsr |= PSR_T; + else + tf->tf_spsr &= ~PSR_T; + + CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td, tf->tf_x[14], + tf->tf_x[13]); + + PROC_LOCK(p); + mtx_lock(&psp->ps_mtx); - return (ENOSYS); } diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S index 107d189618e..8d327d28e41 100644 --- a/sys/arm64/arm64/locore.S +++ b/sys/arm64/arm64/locore.S @@ -699,3 +699,22 @@ esigcode: .global szsigcode szsigcode: .quad esigcode - sigcode + +/* TODO: This needs to be built for 32-bit ARM */ +ENTRY(armv6_sigcode) + .word 0xe1a0000d // mov r0, sp + .word 0xe2800040 // add r0, r0, #SIGF_UC + .word 0xe59f700c // ldr r7, [pc, #12] + .word 0xef000000 // swi #0 + .word 0xe59f7008 // ldr r7, [pc, #8] + .word 0xef000000 // swi #0 + .word 0xeafffffa // b . - 16 +END(armv6_sigcode) + .word SYS_sigreturn + .word SYS_exit + .align 3 +armv6_esigcode: + .data + .global sz_armv6_sigcode +sz_armv6_sigcode: + .quad armv6_esigcode - armv6_sigcode diff --git a/sys/arm64/arm64/machdep.c b/sys/arm64/arm64/machdep.c index e82b9e4ab0b..70fa35090b1 100644 --- a/sys/arm64/arm64/machdep.c +++ b/sys/arm64/arm64/machdep.c @@ -276,17 +276,36 @@ set_dbregs(struct thread *td, struct dbreg *regs) int fill_regs32(struct thread *td, struct reg32 *regs) { + int i; + struct trapframe *tf; - printf("ARM64TODO: fill_regs32"); - return (EDOOFUS); + tf = td->td_frame; + for (i = 0; i < 13; i++) + regs->r[i] = tf->tf_x[i]; + regs->r_sp = tf->tf_sp; + regs->r_lr = tf->tf_lr; + regs->r_pc = tf->tf_elr; + regs->r_cpsr = tf->tf_spsr; + + return (0); } int set_regs32(struct thread *td, struct reg32 *regs) { + int i; + struct trapframe *tf; - printf("ARM64TODO: set_regs32"); - return (EDOOFUS); + tf = td->td_frame; + for (i = 0; i < 13; i++) + tf->tf_x[i] = regs->r[i]; + tf->tf_sp = regs->r_sp; + tf->tf_lr = regs->r_lr; + tf->tf_elr = regs->r_pc; + tf->tf_spsr = regs->r_cpsr; + + + return (0); } int diff --git a/sys/arm64/arm64/trap.c b/sys/arm64/arm64/trap.c index 9de15479800..9bf13f4faf6 100644 --- a/sys/arm64/arm64/trap.c +++ b/sys/arm64/arm64/trap.c @@ -144,6 +144,7 @@ svc_handler(struct thread *td, struct trapframe *frame) error = syscallenter(td); syscallret(td, error); } else { + printf("CE SIGILL LA LOL\n"); call_trapsignal(td, SIGILL, ILL_ILLOPN, (void *)frame->tf_elr); userret(td, frame); } @@ -236,6 +237,7 @@ data_abort(struct thread *td, struct trapframe *frame, uint64_t esr, error = vm_fault(map, va, ftype, VM_FAULT_NORMAL); if (error != KERN_SUCCESS) { if (lower) { + printf("FAULTING ON ADDR %p PC %p\n", (void *)va, (void *)frame->tf_elr); sig = SIGSEGV; if (error == KERN_PROTECTION_FAILURE) ucode = SEGV_ACCERR; @@ -438,8 +440,10 @@ do_el0_sync(struct thread *td, struct trapframe *frame) data_abort(td, frame, esr, far, 1); break; case EXCP_UNKNOWN: - if (!undef_insn(0, frame)) + if (!undef_insn(0, frame)) { + printf("SIGILL ROFLOUNET\n"); call_trapsignal(td, SIGILL, ILL_ILLTRP, (void *)far); + } userret(td, frame); break; case EXCP_SP_ALIGN: @@ -456,6 +460,7 @@ do_el0_sync(struct thread *td, struct trapframe *frame) break; case EXCP_MSR: call_trapsignal(td, SIGILL, ILL_PRVOPC, (void *)frame->tf_elr); + printf("bite de bite!!\n"); userret(td, frame); break; case EXCP_SOFTSTP_EL0: diff --git a/sys/arm64/arm64/undefined.c b/sys/arm64/arm64/undefined.c index 753558a085d..5c750d98c22 100644 --- a/sys/arm64/arm64/undefined.c +++ b/sys/arm64/arm64/undefined.c @@ -36,9 +36,12 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include +#include MALLOC_DEFINE(M_UNDEF, "undefhandler", "Undefined instruction handler data"); @@ -83,6 +86,32 @@ id_aa64mmfr2_handler(vm_offset_t va, uint32_t insn, struct trapframe *frame, return (0); } +#ifdef COMPAT_FREEBSD32 +/* arm32 GDB breakpoints */ +#define GDB_BREAKPOINT 0xe6000011 +#define GDB5_BREAKPOINT 0xe7ffdefe +static int +gdb_trapper(vm_offset_t va, uint32_t insn, struct trapframe *frame, + uint32_t esr) +{ + struct thread *td = curthread; + + if (insn == GDB_BREAKPOINT || insn == GDB5_BREAKPOINT) { + if (va < VM_MAXUSER_ADDRESS) { + ksiginfo_t ksi; + + ksiginfo_init_trap(&ksi); + ksi.ksi_signo = SIGTRAP; + ksi.ksi_code = TRAP_BRKPT; + ksi.ksi_addr = (void *)va; + trapsignal(td, &ksi); + return 1; + } + } + return 0; +} +#endif + void undef_init(void) { @@ -91,6 +120,9 @@ undef_init(void) LIST_INIT(&undef_handlers[1]); install_undef_handler(false, id_aa64mmfr2_handler); +#ifdef COMPAT_FREEBSD32 + install_undef_handler(true, gdb_trapper); +#endif } void * @@ -132,6 +164,7 @@ undef_insn(u_int el, struct trapframe *frame) insn = *(uint32_t *)frame->tf_elr; } + printf("undefined instruction at %lx\n", frame->tf_elr); LIST_FOREACH(uh, &undef_handlers[el], uh_link) { ret = uh->uh_handler(frame->tf_elr, insn, frame, frame->tf_esr); if (ret) diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index 8ec20381018..3663c884f5e 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -78,6 +78,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) * this may not have happened. */ td1->td_pcb->pcb_tpidr_el0 = READ_SPECIALREG(tpidr_el0); + td1->td_pcb->pcb_tpidrro_el0 = READ_SPECIALREG(tpidrro_el0); #ifdef VFP if ((td1->td_pcb->pcb_fpflags & PCB_FP_STARTED) != 0) vfp_save_state(td1, td1->td_pcb); @@ -97,7 +98,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) bcopy(td1->td_frame, tf, sizeof(*tf)); tf->tf_x[0] = 0; tf->tf_x[1] = 0; - tf->tf_spsr = 0; + tf->tf_spsr = td1->td_frame->tf_spsr & PSR_M_32; td2->td_frame = tf; @@ -195,7 +196,11 @@ cpu_set_upcall(struct thread *td, void (*entry)(void *), void *arg, { struct trapframe *tf = td->td_frame; - tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); + /* 32bits processes use r13 for sp */ + if (td->td_frame->tf_spsr & PSR_M_32) + tf->tf_x[13] = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); + else + tf->tf_sp = STACKALIGN((uintptr_t)stack->ss_sp + stack->ss_size); tf->tf_elr = (register_t)entry; tf->tf_x[0] = (register_t)arg; } @@ -208,10 +213,22 @@ cpu_set_user_tls(struct thread *td, void *tls_base) if ((uintptr_t)tls_base >= VM_MAXUSER_ADDRESS) return (EINVAL); + printf("SET USER TLS %s\n", td->td_proc->p_comm); pcb = td->td_pcb; - pcb->pcb_tpidr_el0 = (register_t)tls_base; - if (td == curthread) - WRITE_SPECIALREG(tpidr_el0, tls_base); + if (td->td_frame->tf_spsr & PSR_M_32) { + printf("SETTING TLS FOR 32BITS PROCESS %p\n", tls_base); + /* 32bits arm stores the user TLS into tpidrro */ + pcb->pcb_tpidrro_el0 = (register_t)tls_base; + pcb->pcb_tpidr_el0 = (register_t)tls_base; + if (td == curthread) { + WRITE_SPECIALREG(tpidrro_el0, tls_base); + WRITE_SPECIALREG(tpidr_el0, tls_base); + } + } else { + pcb->pcb_tpidr_el0 = (register_t)tls_base; + if (td == curthread) + WRITE_SPECIALREG(tpidr_el0, tls_base); + } return (0); } diff --git a/sys/arm64/conf/GENERIC b/sys/arm64/conf/GENERIC index f753f8d1f9c..82017a18166 100644 --- a/sys/arm64/conf/GENERIC +++ b/sys/arm64/conf/GENERIC @@ -48,12 +48,12 @@ options NFSLOCKD # Network Lock Manager options NFS_ROOT # NFS usable as /, requires NFSCL options MSDOSFS # MSDOS Filesystem options CD9660 # ISO 9660 Filesystem -options PROCFS # Process filesystem (requires PSEUDOFS) +#options PROCFS # Process filesystem (requires PSEUDOFS) options PSEUDOFS # Pseudo-filesystem framework options GEOM_PART_GPT # GUID Partition Tables. options GEOM_RAID # Soft RAID functionality. options GEOM_LABEL # Provides labelization -options COMPAT_FREEBSD32 # Incomplete, but used by cloudabi32.ko. +options COMPAT_FREEBSD32 # Compatible with FreeBSD/arm options COMPAT_FREEBSD11 # Compatible with FreeBSD11 options SCSI_DELAY=5000 # Delay (in ms) before probing SCSI options KTRACE # ktrace(1) support diff --git a/sys/arm64/include/armreg.h b/sys/arm64/include/armreg.h index 97b13931258..cf03e2c28bd 100644 --- a/sys/arm64/include/armreg.h +++ b/sys/arm64/include/armreg.h @@ -560,8 +560,13 @@ #define PSR_M_EL1h 0x00000005 #define PSR_M_EL2t 0x00000008 #define PSR_M_EL2h 0x00000009 +#define PSR_M_STATE_MASK 0x0000000f +#define PSR_M_64 0x00000000 +#define PSR_M_32 0x00000010 #define PSR_M_MASK 0x0000000f +#define PSR_T 0x00000020 + #define PSR_AARCH32 0x00000010 #define PSR_F 0x00000040 #define PSR_I 0x00000080 diff --git a/sys/arm64/include/armv6_signal.h b/sys/arm64/include/armv6_signal.h new file mode 100644 index 00000000000..c66641fea77 --- /dev/null +++ b/sys/arm64/include/armv6_signal.h @@ -0,0 +1,62 @@ +/*- + * Copyright (c) 2018 Olivier Houchard + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_ARMV6_SIGNAL_H_ +#define _MACHINE_ARMV6_SIGNAL_H_ + +#include + +struct armv6_mcontext { + uint32_t mc_gregset[17]; + uint32_t mc_vfp_size; + uint32_t mc_vfp_ptr; + uint32_t mc_spare[33]; +}; + +struct armv6_ucontext { + sigset_t uc_sigmask; + struct armv6_mcontext uc_mcontext; + u_int32_t uc_link; + struct sigaltstack32 uc_stack; + u_int32_t uc_flags; + u_int32_t __spare__[4]; +}; + +struct armv6_mcontext_vfp { + __uint64_t mcv_reg[32]; + __uint32_t mcv_fpscr; +}; + +struct armv6_sigframe { + struct siginfo32 sf_si; + struct armv6_ucontext sf_uc; + struct armv6_mcontext_vfp sf_vfp; +}; + +extern void armv6_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); +#endif /* _MACHINE_ARMV6_SIGNAL_H_ */ diff --git a/sys/arm64/include/cpu.h b/sys/arm64/include/cpu.h index f5d7909b789..82a874fef05 100644 --- a/sys/arm64/include/cpu.h +++ b/sys/arm64/include/cpu.h @@ -46,7 +46,8 @@ #include #define TRAPF_PC(tfp) ((tfp)->tf_lr) -#define TRAPF_USERMODE(tfp) (((tfp)->tf_spsr & PSR_M_MASK) == PSR_M_EL0t) +#define TRAPF_USERMODE(tfp) \ + (((tfp)->tf_spsr & PSR_M_STATE_MASK) == PSR_M_EL0t) #define cpu_getstack(td) ((td)->td_frame->tf_sp) #define cpu_setstack(td, sp) ((td)->td_frame->tf_sp = (sp)) diff --git a/sys/arm64/include/elf.h b/sys/arm64/include/elf.h index 04487c43abf..c81e05c3657 100644 --- a/sys/arm64/include/elf.h +++ b/sys/arm64/include/elf.h @@ -112,6 +112,10 @@ __ElfType(Auxinfo); #define ELF_TARG_VER 1 #endif +#if __ELF_WORD_SIZE == 32 +#define ET_DYN_LOAD_ADDR 0x12000 +#else #define ET_DYN_LOAD_ADDR 0x100000 +#endif #endif /* !_MACHINE_ELF_H_ */ diff --git a/sys/arm64/include/param.h b/sys/arm64/include/param.h index 63c603bed3e..3b53c95ce91 100644 --- a/sys/arm64/include/param.h +++ b/sys/arm64/include/param.h @@ -53,6 +53,9 @@ #ifndef MACHINE_ARCH32 #define MACHINE_ARCH32 "armv7" #endif +#ifndef MACHINE_ARCH32 +#define MACHINE_ARCH32 "armv6" +#endif #if defined(SMP) || defined(KLD_MODULE) #ifndef MAXCPU diff --git a/sys/arm64/include/pcb.h b/sys/arm64/include/pcb.h index bd8b1b4235a..5c8068076a4 100644 --- a/sys/arm64/include/pcb.h +++ b/sys/arm64/include/pcb.h @@ -50,6 +50,7 @@ struct pcb { u_int pcb_flags; #define PCB_SINGLE_STEP_SHIFT 0 #define PCB_SINGLE_STEP (1 << PCB_SINGLE_STEP_SHIFT) +#define PCB_32BIT (1 << 1) struct vfpstate *pcb_fpusaved; int pcb_fpflags; diff --git a/sys/arm64/include/reg.h b/sys/arm64/include/reg.h index 8925a6cbb25..39c8db11cdc 100644 --- a/sys/arm64/include/reg.h +++ b/sys/arm64/include/reg.h @@ -42,7 +42,11 @@ struct reg { }; struct reg32 { - int dummy; + unsigned int r[13]; + unsigned int r_sp; + unsigned int r_lr; + unsigned int r_pc; + unsigned int r_cpsr; }; struct fpreg { diff --git a/sys/arm64/include/vfp.h b/sys/arm64/include/vfp.h index b3b0c575828..752ff150845 100644 --- a/sys/arm64/include/vfp.h +++ b/sys/arm64/include/vfp.h @@ -65,6 +65,11 @@ int fpu_kern_leave(struct thread *, struct fpu_kern_ctx *); int fpu_kern_thread(u_int); int is_fpu_kern_thread(u_int); +/* Convert to and from Aarch32 FPSCR to Aarch64 FPCR/FPSR */ +#define VFP_FPSCR_FROM_SRCR(vpsr, vpcr) ((vpsr) | ((vpcr) & 0x7c00000)) +#define VFP_FPSR_FROM_FPSCR(vpscr) ((vpscr) &~ 0x7c00000) +#define VFP_FPCR_FROM_FPSCR(vpsrc) ((vpsrc) & 0x7c00000) + #endif #endif diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c index 070a9bcd8a7..04325486f80 100644 --- a/sys/compat/freebsd32/freebsd32_misc.c +++ b/sys/compat/freebsd32/freebsd32_misc.c @@ -577,6 +577,7 @@ freebsd32_select(struct thread *td, struct freebsd32_select_args *uap) int error; if (uap->tv != NULL) { + printf("COPYING TV FROM %p\n", uap->tv); error = copyin(uap->tv, &tv32, sizeof(tv32)); if (error) return (error); @@ -3165,6 +3166,9 @@ freebsd32_copyout_strings(struct image_params *imgp) destp = rounddown2(destp, sizeof(uint32_t)); copyout(imgp->proc->p_sysent->sv_sigcode, (void *)destp, szsigcode); + printf("copying to %lx\n", destp); + for (int i = 0; i < szsigcode; i += 4) + printf("%x\n", *(int *)(destp + i)); } /* diff --git a/sys/compat/freebsd32/freebsd32_proto.h b/sys/compat/freebsd32/freebsd32_proto.h index b7c0cdddc32..ebfab26e5f4 100644 --- a/sys/compat/freebsd32/freebsd32_proto.h +++ b/sys/compat/freebsd32/freebsd32_proto.h @@ -34,7 +34,7 @@ struct thread; #define PADR_(t) 0 #endif -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct freebsd32_wait4_args { @@ -710,7 +710,7 @@ struct freebsd32_cpuset_setdomain_args { char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)]; char policy_l_[PADL_(int)]; int policy; char policy_r_[PADR_(int)]; }; -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif int freebsd32_wait4(struct thread *, struct freebsd32_wait4_args *); @@ -845,7 +845,7 @@ int freebsd32_cpuset_setdomain(struct thread *, struct freebsd32_cpuset_setdomai #ifdef COMPAT_43 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct ofreebsd32_lseek_args { @@ -937,7 +937,7 @@ int ofreebsd32_getdirentries(struct thread *, struct ofreebsd32_getdirentries_ar #ifdef COMPAT_FREEBSD4 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct freebsd4_freebsd32_getfsstat_args { @@ -1000,7 +1000,7 @@ int freebsd4_freebsd32_sigreturn(struct thread *, struct freebsd4_freebsd32_sigr #ifdef COMPAT_FREEBSD6 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct freebsd6_freebsd32_pread_args { @@ -1087,7 +1087,7 @@ int freebsd6_freebsd32_lio_listio(struct thread *, struct freebsd6_freebsd32_lio #ifdef COMPAT_FREEBSD7 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct freebsd7_freebsd32_semctl_args { @@ -1127,7 +1127,7 @@ int freebsd7_freebsd32_shmctl(struct thread *, struct freebsd7_freebsd32_shmctl_ #ifdef COMPAT_FREEBSD10 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif #ifdef PAD64_REQUIRED @@ -1149,7 +1149,7 @@ int freebsd10_freebsd32_pipe(struct thread *, struct freebsd10_freebsd32_pipe_ar #ifdef COMPAT_FREEBSD11 -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif struct freebsd11_freebsd32_mknod_args { diff --git a/sys/compat/freebsd32/freebsd32_syscalls.c b/sys/compat/freebsd32/freebsd32_syscalls.c index c186771f070..f366cea27bd 100644 --- a/sys/compat/freebsd32/freebsd32_syscalls.c +++ b/sys/compat/freebsd32/freebsd32_syscalls.c @@ -6,7 +6,7 @@ */ const char *freebsd32_syscallnames[] = { -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif "syscall", /* 0 = syscall */ diff --git a/sys/compat/freebsd32/freebsd32_sysent.c b/sys/compat/freebsd32/freebsd32_sysent.c index 1a6ff314dfa..53ae99d3937 100644 --- a/sys/compat/freebsd32/freebsd32_sysent.c +++ b/sys/compat/freebsd32/freebsd32_sysent.c @@ -53,7 +53,7 @@ /* The casts are bogus but will do for now. */ struct sysent freebsd32_sysent[] = { -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 0 = syscall */ diff --git a/sys/compat/freebsd32/freebsd32_systrace_args.c b/sys/compat/freebsd32/freebsd32_systrace_args.c index c3ee144f07e..7b6dc27257c 100644 --- a/sys/compat/freebsd32/freebsd32_systrace_args.c +++ b/sys/compat/freebsd32/freebsd32_systrace_args.c @@ -11,7 +11,7 @@ systrace_args(int sysnum, void *params, uint64_t *uarg, int *n_args) { int64_t *iarg = (int64_t *) uarg; switch (sysnum) { -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif /* nosys */ @@ -3268,7 +3268,7 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) { const char *p = NULL; switch (sysnum) { -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif /* nosys */ @@ -8769,7 +8769,7 @@ systrace_return_setargdesc(int sysnum, int ndx, char *desc, size_t descsz) { const char *p = NULL; switch (sysnum) { -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || defined(__aarch64__)) #define PAD64_REQUIRED #endif /* nosys */ diff --git a/sys/compat/freebsd32/syscalls.master b/sys/compat/freebsd32/syscalls.master index 9b5aafe4124..6be6e3f0b5e 100644 --- a/sys/compat/freebsd32/syscalls.master +++ b/sys/compat/freebsd32/syscalls.master @@ -54,7 +54,8 @@ #include #include -#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__)) +#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__) || \ + defined(__aarch64__)) #define PAD64_REQUIRED #endif diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 010fbc7460c..f743850a524 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -114,6 +114,8 @@ arm64/arm64/dump_machdep.c standard arm64/arm64/efirt_machdep.c optional efirt arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/elf_machdep.c standard +# XXX: Make optional +arm64/arm64/elf32_machdep.c optional compat_freebsd32 arm64/arm64/exception.S standard arm64/arm64/freebsd32_machdep.c optional compat_freebsd32 arm64/arm64/gicv3_its.c optional intrng fdt diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c index 23c398fc43b..a851742566b 100644 --- a/sys/kern/kern_exec.c +++ b/sys/kern/kern_exec.c @@ -1123,6 +1123,7 @@ exec_new_vmspace(struct image_params *imgp, struct sysentvec *sv) VM_PROT_READ | VM_PROT_EXECUTE, MAP_INHERIT_SHARE | MAP_ACC_NO_CHARGE); if (error != KERN_SUCCESS) { + printf("ERROR %d\n", error); vm_object_deallocate(obj); return (vm_mmap_to_errno(error)); } @@ -1505,6 +1506,11 @@ exec_copyout_strings(struct image_params *imgp) destp -= szsigcode; destp = rounddown2(destp, sizeof(void *)); copyout(p->p_sysent->sv_sigcode, (void *)destp, szsigcode); + if (1) { + printf("copying to %lx\n", destp); + for (int i = 0; i < szsigcode; i += 4) + printf("%x\n", *(int *)(destp + i)); + } } /* diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c index 0280a2c706b..a7731ba4a1a 100644 --- a/sys/kern/kern_proc.c +++ b/sys/kern/kern_proc.c @@ -1914,9 +1914,10 @@ proc_getauxv(struct thread *td, struct proc *p, struct sbuf *sb) error = get_proc_vector(td, p, &auxv, &vsize, PROC_AUX); if (error == 0) { #ifdef COMPAT_FREEBSD32 - if (SV_PROC_FLAG(p, SV_ILP32) != 0) + if (SV_PROC_FLAG(p, SV_ILP32) != 0) { + printf("BITE LOLLL\n"); size = vsize * sizeof(Elf32_Auxinfo); - else + } else #endif size = vsize * sizeof(Elf_Auxinfo); if (sbuf_bcat(sb, auxv, size) != 0) diff --git a/sys/kern/kern_sharedpage.c b/sys/kern/kern_sharedpage.c index 2b1fe70ad33..e7150dc8b88 100644 --- a/sys/kern/kern_sharedpage.c +++ b/sys/kern/kern_sharedpage.c @@ -164,7 +164,7 @@ timehands_update(struct vdso_sv_tk *svtk) tk->tk_enabled = enabled; } -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) static void timehands_update32(struct vdso_sv_tk *svtk) { @@ -199,7 +199,7 @@ timehands_update32(struct vdso_sv_tk *svtk) * context. */ static struct vdso_sv_tk *host_svtk; -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) static struct vdso_sv_tk *compat32_svtk; #endif @@ -209,7 +209,7 @@ timekeep_push_vdso(void) if (host_svtk != NULL) timehands_update(host_svtk); -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) if (compat32_svtk != NULL) timehands_update32(compat32_svtk); #endif @@ -234,7 +234,7 @@ alloc_sv_tk(void) return (svtk); } -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) struct vdso_sv_tk * alloc_sv_tk_compat32(void) { @@ -261,15 +261,17 @@ exec_sysvec_init(void *param) struct sysentvec *sv; sv = (struct sysentvec *)param; + printf("DOING SV %p\n", sv); if ((sv->sv_flags & SV_SHP) == 0) return; sv->sv_shared_page_obj = shared_page_obj; sv->sv_sigcode_base = sv->sv_shared_page_base + shared_page_fill(*(sv->sv_szsigcode), 16, sv->sv_sigcode); + printf("shared page base is %p\n", (void *)sv->sv_sigcode_base); if ((sv->sv_flags & SV_ABI_MASK) != SV_ABI_FREEBSD) return; if ((sv->sv_flags & SV_TIMEKEEP) != 0) { -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) if ((sv->sv_flags & SV_ILP32) != 0) { KASSERT(compat32_svtk == NULL, ("Compat32 already registered")); @@ -282,7 +284,7 @@ exec_sysvec_init(void *param) host_svtk = alloc_sv_tk(); sv->sv_timekeep_base = sv->sv_shared_page_base + host_svtk->sv_timekeep_off; -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) } #endif } diff --git a/sys/kern/kern_tc.c b/sys/kern/kern_tc.c index e55290df785..d016cda20fb 100644 --- a/sys/kern/kern_tc.c +++ b/sys/kern/kern_tc.c @@ -145,7 +145,8 @@ sysctl_kern_boottime(SYSCTL_HANDLER_ARGS) getboottime(&boottime); -#ifndef __mips__ +/* i386 is the only arch which uses a 32bits time_t */ +#ifdef __amd64__ #ifdef SCTL_MASK32 int tv[2]; @@ -2175,7 +2176,7 @@ tc_fill_vdso_timehands(struct vdso_timehands *vdso_th) return (enabled); } -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) uint32_t tc_fill_vdso_timehands32(struct vdso_timehands32 *vdso_th32) { diff --git a/sys/sys/vdso.h b/sys/sys/vdso.h index b645e5356c8..8646b77b780 100644 --- a/sys/sys/vdso.h +++ b/sys/sys/vdso.h @@ -101,7 +101,7 @@ struct vdso_sv_tk *alloc_sv_tk(void); #define VDSO_TH_NUM 4 -#ifdef COMPAT_FREEBSD32 +#if defined(COMPAT_FREEBSD32) struct bintime32 { uint32_t sec; uint32_t frac[2]; -- 2.13.3