1232449Sjmallett/*- 2232449Sjmallett * Copyright (c) 2012 Juli Mallett <jmallett@FreeBSD.org> 3232449Sjmallett * All rights reserved. 4232449Sjmallett * 5232449Sjmallett * Redistribution and use in source and binary forms, with or without 6232449Sjmallett * modification, are permitted provided that the following conditions 7232449Sjmallett * are met: 8232449Sjmallett * 1. Redistributions of source code must retain the above copyright 9232449Sjmallett * notice, this list of conditions and the following disclaimer. 10232449Sjmallett * 2. Redistributions in binary form must reproduce the above copyright 11232449Sjmallett * notice, this list of conditions and the following disclaimer in the 12232449Sjmallett * documentation and/or other materials provided with the distribution. 13232449Sjmallett * 14232449Sjmallett * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15232449Sjmallett * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16232449Sjmallett * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17232449Sjmallett * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18232449Sjmallett * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19232449Sjmallett * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20232449Sjmallett * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21232449Sjmallett * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22232449Sjmallett * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23232449Sjmallett * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24232449Sjmallett * SUCH DAMAGE. 25232449Sjmallett * 26232449Sjmallett * $FreeBSD$ 27232449Sjmallett */ 28232449Sjmallett 29232449Sjmallett/* 30232449Sjmallett * Based on nwhitehorn's COMPAT_FREEBSD32 support code for PowerPC64. 31232449Sjmallett */ 32232449Sjmallett 33232449Sjmallett#include "opt_compat.h" 34232449Sjmallett 35232449Sjmallett#define __ELF_WORD_SIZE 32 36232449Sjmallett 37232449Sjmallett#include <sys/types.h> 38232449Sjmallett#include <sys/param.h> 39232449Sjmallett#include <sys/kernel.h> 40232449Sjmallett#include <sys/systm.h> 41232449Sjmallett#include <sys/sysent.h> 42232449Sjmallett#include <sys/exec.h> 43232449Sjmallett#include <sys/imgact.h> 44232449Sjmallett#include <sys/malloc.h> 45232449Sjmallett#include <sys/proc.h> 46232449Sjmallett#include <sys/namei.h> 47232449Sjmallett#include <sys/fcntl.h> 48232449Sjmallett#include <sys/sysent.h> 49232449Sjmallett#include <sys/imgact_elf.h> 50232449Sjmallett#include <sys/syscall.h> 51232449Sjmallett#include <sys/syscallsubr.h> 52232449Sjmallett#include <sys/sysproto.h> 53232449Sjmallett#include <sys/signalvar.h> 54232449Sjmallett#include <sys/vnode.h> 55232449Sjmallett#include <sys/linker.h> 56232449Sjmallett 57232449Sjmallett#include <vm/vm.h> 58232449Sjmallett#include <vm/vm_param.h> 59232449Sjmallett 60232449Sjmallett#include <machine/md_var.h> 61232449Sjmallett#include <machine/reg.h> 62232449Sjmallett#include <machine/sigframe.h> 63232449Sjmallett#include <machine/sysarch.h> 64232449Sjmallett 65232449Sjmallett#include <compat/freebsd32/freebsd32_signal.h> 66232449Sjmallett#include <compat/freebsd32/freebsd32_util.h> 67232449Sjmallett#include <compat/freebsd32/freebsd32_proto.h> 68232449Sjmallett 69232449Sjmallettstatic void freebsd32_exec_setregs(struct thread *, struct image_params *, u_long); 70232449Sjmallettstatic int get_mcontext32(struct thread *, mcontext32_t *, int); 71278347Skibstatic int set_mcontext32(struct thread *, mcontext32_t *); 72232449Sjmallettstatic void freebsd32_sendsig(sig_t, ksiginfo_t *, sigset_t *); 73232449Sjmallett 74232449Sjmallettextern const char *freebsd32_syscallnames[]; 75232449Sjmallett 76232449Sjmallettstruct sysentvec elf32_freebsd_sysvec = { 77232449Sjmallett .sv_size = SYS_MAXSYSCALL, 78232449Sjmallett .sv_table = freebsd32_sysent, 79232449Sjmallett .sv_mask = 0, 80232449Sjmallett .sv_sigsize = 0, 81232449Sjmallett .sv_sigtbl = NULL, 82232449Sjmallett .sv_errsize = 0, 83232449Sjmallett .sv_errtbl = NULL, 84232449Sjmallett .sv_transtrap = NULL, 85232449Sjmallett .sv_fixup = __elfN(freebsd_fixup), 86232449Sjmallett .sv_sendsig = freebsd32_sendsig, 87232449Sjmallett .sv_sigcode = sigcode32, 88232449Sjmallett .sv_szsigcode = &szsigcode32, 89232449Sjmallett .sv_prepsyscall = NULL, 90232449Sjmallett .sv_name = "FreeBSD ELF32", 91232449Sjmallett .sv_coredump = __elfN(coredump), 92232449Sjmallett .sv_imgact_try = NULL, 93232449Sjmallett .sv_minsigstksz = MINSIGSTKSZ, 94232449Sjmallett .sv_pagesize = PAGE_SIZE, 95232449Sjmallett .sv_minuser = VM_MIN_ADDRESS, 96232449Sjmallett .sv_maxuser = ((vm_offset_t)0x80000000), 97232449Sjmallett .sv_usrstack = FREEBSD32_USRSTACK, 98232449Sjmallett .sv_psstrings = FREEBSD32_PS_STRINGS, 99232449Sjmallett .sv_stackprot = VM_PROT_ALL, 100232449Sjmallett .sv_copyout_strings = freebsd32_copyout_strings, 101232449Sjmallett .sv_setregs = freebsd32_exec_setregs, 102232449Sjmallett .sv_fixlimit = NULL, 103232449Sjmallett .sv_maxssiz = NULL, 104232449Sjmallett .sv_flags = SV_ABI_FREEBSD | SV_ILP32, 105232449Sjmallett .sv_set_syscall_retval = cpu_set_syscall_retval, 106232449Sjmallett .sv_fetch_syscall_args = cpu_fetch_syscall_args, 107232449Sjmallett .sv_syscallnames = freebsd32_syscallnames, 108232449Sjmallett .sv_schedtail = NULL, 109293490Sdchagin .sv_thread_detach = NULL, 110294136Sdchagin .sv_trap = NULL, 111232449Sjmallett}; 112232449SjmallettINIT_SYSENTVEC(elf32_sysvec, &elf32_freebsd_sysvec); 113232449Sjmallett 114232449Sjmallettstatic Elf32_Brandinfo freebsd_brand_info = { 115232449Sjmallett .brand = ELFOSABI_FREEBSD, 116232449Sjmallett .machine = EM_MIPS, 117232449Sjmallett .compat_3_brand = "FreeBSD", 118232449Sjmallett .emul_path = NULL, 119232449Sjmallett .interp_path = "/libexec/ld-elf.so.1", 120232449Sjmallett .sysvec = &elf32_freebsd_sysvec, 121232449Sjmallett .interp_newpath = "/libexec/ld-elf32.so.1", 122232449Sjmallett .flags = 0 123232449Sjmallett}; 124232449Sjmallett 125232449SjmallettSYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, 126232449Sjmallett (sysinit_cfunc_t) elf32_insert_brand_entry, 127232449Sjmallett &freebsd_brand_info); 128232449Sjmallett 129232449Sjmallettstatic void 130232449Sjmallettfreebsd32_exec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 131232449Sjmallett{ 132232449Sjmallett exec_setregs(td, imgp, stack); 133232449Sjmallett 134232449Sjmallett /* 135232449Sjmallett * See comment in exec_setregs about running 32-bit binaries with 64-bit 136232449Sjmallett * registers. 137232449Sjmallett */ 138232449Sjmallett td->td_frame->sp -= 65536; 139232449Sjmallett 140232449Sjmallett /* 141232449Sjmallett * Clear extended address space bit for userland. 142232449Sjmallett */ 143232449Sjmallett td->td_frame->sr &= ~MIPS_SR_UX; 144232449Sjmallett} 145232449Sjmallett 146232449Sjmallettint 147232449Sjmallettset_regs32(struct thread *td, struct reg32 *regs) 148232449Sjmallett{ 149232449Sjmallett struct reg r; 150232449Sjmallett unsigned i; 151232449Sjmallett 152232449Sjmallett for (i = 0; i < NUMSAVEREGS; i++) 153232449Sjmallett r.r_regs[i] = regs->r_regs[i]; 154232449Sjmallett 155232449Sjmallett return (set_regs(td, &r)); 156232449Sjmallett} 157232449Sjmallett 158232449Sjmallettint 159232449Sjmallettfill_regs32(struct thread *td, struct reg32 *regs) 160232449Sjmallett{ 161232449Sjmallett struct reg r; 162232449Sjmallett unsigned i; 163232449Sjmallett int error; 164232449Sjmallett 165232449Sjmallett error = fill_regs(td, &r); 166232449Sjmallett if (error != 0) 167232449Sjmallett return (error); 168232449Sjmallett 169232449Sjmallett for (i = 0; i < NUMSAVEREGS; i++) 170232449Sjmallett regs->r_regs[i] = r.r_regs[i]; 171232449Sjmallett 172232449Sjmallett return (0); 173232449Sjmallett} 174232449Sjmallett 175232449Sjmallettint 176232449Sjmallettset_fpregs32(struct thread *td, struct fpreg32 *fpregs) 177232449Sjmallett{ 178232449Sjmallett struct fpreg fp; 179232449Sjmallett unsigned i; 180232449Sjmallett 181232449Sjmallett for (i = 0; i < NUMFPREGS; i++) 182232449Sjmallett fp.r_regs[i] = fpregs->r_regs[i]; 183232449Sjmallett 184232449Sjmallett return (set_fpregs(td, &fp)); 185232449Sjmallett} 186232449Sjmallett 187232449Sjmallettint 188232449Sjmallettfill_fpregs32(struct thread *td, struct fpreg32 *fpregs) 189232449Sjmallett{ 190232449Sjmallett struct fpreg fp; 191232449Sjmallett unsigned i; 192232449Sjmallett int error; 193232449Sjmallett 194232449Sjmallett error = fill_fpregs(td, &fp); 195232449Sjmallett if (error != 0) 196232449Sjmallett return (error); 197232449Sjmallett 198232449Sjmallett for (i = 0; i < NUMFPREGS; i++) 199232449Sjmallett fpregs->r_regs[i] = fp.r_regs[i]; 200232449Sjmallett 201232449Sjmallett return (0); 202232449Sjmallett} 203232449Sjmallett 204232449Sjmallettstatic int 205232449Sjmallettget_mcontext32(struct thread *td, mcontext32_t *mcp, int flags) 206232449Sjmallett{ 207232449Sjmallett mcontext_t mcp64; 208232449Sjmallett unsigned i; 209232449Sjmallett int error; 210232449Sjmallett 211232449Sjmallett error = get_mcontext(td, &mcp64, flags); 212232449Sjmallett if (error != 0) 213232449Sjmallett return (error); 214232449Sjmallett 215232449Sjmallett mcp->mc_onstack = mcp64.mc_onstack; 216232449Sjmallett mcp->mc_pc = mcp64.mc_pc; 217232449Sjmallett for (i = 0; i < 32; i++) 218232449Sjmallett mcp->mc_regs[i] = mcp64.mc_regs[i]; 219232449Sjmallett mcp->sr = mcp64.sr; 220232449Sjmallett mcp->mullo = mcp64.mullo; 221232449Sjmallett mcp->mulhi = mcp64.mulhi; 222232449Sjmallett mcp->mc_fpused = mcp64.mc_fpused; 223232449Sjmallett for (i = 0; i < 33; i++) 224232449Sjmallett mcp->mc_fpregs[i] = mcp64.mc_fpregs[i]; 225232449Sjmallett mcp->mc_fpc_eir = mcp64.mc_fpc_eir; 226232584Sjmallett mcp->mc_tls = (int32_t)(intptr_t)mcp64.mc_tls; 227232449Sjmallett 228232449Sjmallett return (0); 229232449Sjmallett} 230232449Sjmallett 231232449Sjmallettstatic int 232278347Skibset_mcontext32(struct thread *td, mcontext32_t *mcp) 233232449Sjmallett{ 234232449Sjmallett mcontext_t mcp64; 235232449Sjmallett unsigned i; 236232449Sjmallett 237232449Sjmallett mcp64.mc_onstack = mcp->mc_onstack; 238232449Sjmallett mcp64.mc_pc = mcp->mc_pc; 239232449Sjmallett for (i = 0; i < 32; i++) 240232449Sjmallett mcp64.mc_regs[i] = mcp->mc_regs[i]; 241232449Sjmallett mcp64.sr = mcp->sr; 242232449Sjmallett mcp64.mullo = mcp->mullo; 243232449Sjmallett mcp64.mulhi = mcp->mulhi; 244232449Sjmallett mcp64.mc_fpused = mcp->mc_fpused; 245232449Sjmallett for (i = 0; i < 33; i++) 246232449Sjmallett mcp64.mc_fpregs[i] = mcp->mc_fpregs[i]; 247232449Sjmallett mcp64.mc_fpc_eir = mcp->mc_fpc_eir; 248232584Sjmallett mcp64.mc_tls = (void *)(intptr_t)mcp->mc_tls; 249232449Sjmallett 250232449Sjmallett return (set_mcontext(td, &mcp64)); 251232449Sjmallett} 252232449Sjmallett 253232449Sjmallettint 254232449Sjmallettfreebsd32_sigreturn(struct thread *td, struct freebsd32_sigreturn_args *uap) 255232449Sjmallett{ 256232449Sjmallett ucontext32_t uc; 257232449Sjmallett int error; 258232449Sjmallett 259232449Sjmallett CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp); 260232449Sjmallett 261232449Sjmallett if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) { 262232449Sjmallett CTR1(KTR_SIG, "sigreturn: efault td=%p", td); 263232449Sjmallett return (EFAULT); 264232449Sjmallett } 265232449Sjmallett 266232449Sjmallett error = set_mcontext32(td, &uc.uc_mcontext); 267232449Sjmallett if (error != 0) 268232449Sjmallett return (error); 269232449Sjmallett 270232449Sjmallett kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 271232449Sjmallett 272232449Sjmallett#if 0 273232449Sjmallett CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x", 274232449Sjmallett td, uc.uc_mcontext.mc_srr0, uc.uc_mcontext.mc_gpr[1]); 275232449Sjmallett#endif 276232449Sjmallett 277232449Sjmallett return (EJUSTRETURN); 278232449Sjmallett} 279232449Sjmallett 280232449Sjmallett/* 281232449Sjmallett * The first two fields of a ucontext_t are the signal mask and the machine 282232449Sjmallett * context. The next field is uc_link; we want to avoid destroying the link 283232449Sjmallett * when copying out contexts. 284232449Sjmallett */ 285232449Sjmallett#define UC32_COPY_SIZE offsetof(ucontext32_t, uc_link) 286232449Sjmallett 287232449Sjmallettint 288232449Sjmallettfreebsd32_getcontext(struct thread *td, struct freebsd32_getcontext_args *uap) 289232449Sjmallett{ 290232449Sjmallett ucontext32_t uc; 291232449Sjmallett int ret; 292232449Sjmallett 293232449Sjmallett if (uap->ucp == NULL) 294232449Sjmallett ret = EINVAL; 295232449Sjmallett else { 296232449Sjmallett get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 297232449Sjmallett PROC_LOCK(td->td_proc); 298232449Sjmallett uc.uc_sigmask = td->td_sigmask; 299232449Sjmallett PROC_UNLOCK(td->td_proc); 300232449Sjmallett ret = copyout(&uc, uap->ucp, UC32_COPY_SIZE); 301232449Sjmallett } 302232449Sjmallett return (ret); 303232449Sjmallett} 304232449Sjmallett 305232449Sjmallettint 306232449Sjmallettfreebsd32_setcontext(struct thread *td, struct freebsd32_setcontext_args *uap) 307232449Sjmallett{ 308232449Sjmallett ucontext32_t uc; 309232449Sjmallett int ret; 310232449Sjmallett 311232449Sjmallett if (uap->ucp == NULL) 312232449Sjmallett ret = EINVAL; 313232449Sjmallett else { 314232449Sjmallett ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); 315232449Sjmallett if (ret == 0) { 316232449Sjmallett ret = set_mcontext32(td, &uc.uc_mcontext); 317232449Sjmallett if (ret == 0) { 318232449Sjmallett kern_sigprocmask(td, SIG_SETMASK, 319232449Sjmallett &uc.uc_sigmask, NULL, 0); 320232449Sjmallett } 321232449Sjmallett } 322232449Sjmallett } 323232449Sjmallett return (ret == 0 ? EJUSTRETURN : ret); 324232449Sjmallett} 325232449Sjmallett 326232449Sjmallettint 327232449Sjmallettfreebsd32_swapcontext(struct thread *td, struct freebsd32_swapcontext_args *uap) 328232449Sjmallett{ 329232449Sjmallett ucontext32_t uc; 330232449Sjmallett int ret; 331232449Sjmallett 332232449Sjmallett if (uap->oucp == NULL || uap->ucp == NULL) 333232449Sjmallett ret = EINVAL; 334232449Sjmallett else { 335232449Sjmallett get_mcontext32(td, &uc.uc_mcontext, GET_MC_CLEAR_RET); 336232449Sjmallett PROC_LOCK(td->td_proc); 337232449Sjmallett uc.uc_sigmask = td->td_sigmask; 338232449Sjmallett PROC_UNLOCK(td->td_proc); 339232449Sjmallett ret = copyout(&uc, uap->oucp, UC32_COPY_SIZE); 340232449Sjmallett if (ret == 0) { 341232449Sjmallett ret = copyin(uap->ucp, &uc, UC32_COPY_SIZE); 342232449Sjmallett if (ret == 0) { 343232449Sjmallett ret = set_mcontext32(td, &uc.uc_mcontext); 344232449Sjmallett if (ret == 0) { 345232449Sjmallett kern_sigprocmask(td, SIG_SETMASK, 346232449Sjmallett &uc.uc_sigmask, NULL, 0); 347232449Sjmallett } 348232449Sjmallett } 349232449Sjmallett } 350232449Sjmallett } 351232449Sjmallett return (ret == 0 ? EJUSTRETURN : ret); 352232449Sjmallett} 353232449Sjmallett 354232449Sjmallett#define UCONTEXT_MAGIC 0xACEDBADE 355232449Sjmallett 356232449Sjmallett/* 357232449Sjmallett * Send an interrupt to process. 358232449Sjmallett * 359232449Sjmallett * Stack is set up to allow sigcode stored 360232449Sjmallett * at top to call routine, followed by kcall 361232449Sjmallett * to sigreturn routine below. After sigreturn 362232449Sjmallett * resets the signal mask, the stack, and the 363232449Sjmallett * frame pointer, it returns to the user 364232449Sjmallett * specified pc, psl. 365232449Sjmallett */ 366232449Sjmallettstatic void 367232449Sjmallettfreebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 368232449Sjmallett{ 369232449Sjmallett struct proc *p; 370232449Sjmallett struct thread *td; 371232449Sjmallett struct fpreg32 fpregs; 372232449Sjmallett struct reg32 regs; 373232449Sjmallett struct sigacts *psp; 374232449Sjmallett struct sigframe32 sf, *sfp; 375232449Sjmallett int sig; 376232449Sjmallett int oonstack; 377232449Sjmallett unsigned i; 378232449Sjmallett 379232449Sjmallett td = curthread; 380232449Sjmallett p = td->td_proc; 381232449Sjmallett PROC_LOCK_ASSERT(p, MA_OWNED); 382232449Sjmallett sig = ksi->ksi_signo; 383232449Sjmallett psp = p->p_sigacts; 384232449Sjmallett mtx_assert(&psp->ps_mtx, MA_OWNED); 385232449Sjmallett 386232449Sjmallett fill_regs32(td, ®s); 387232449Sjmallett oonstack = sigonstack(td->td_frame->sp); 388232449Sjmallett 389232449Sjmallett /* save user context */ 390232449Sjmallett bzero(&sf, sizeof sf); 391232449Sjmallett sf.sf_uc.uc_sigmask = *mask; 392232449Sjmallett sf.sf_uc.uc_stack.ss_sp = (int32_t)(intptr_t)td->td_sigstk.ss_sp; 393232449Sjmallett sf.sf_uc.uc_stack.ss_size = td->td_sigstk.ss_size; 394232449Sjmallett sf.sf_uc.uc_stack.ss_flags = td->td_sigstk.ss_flags; 395232449Sjmallett sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 396232449Sjmallett sf.sf_uc.uc_mcontext.mc_pc = regs.r_regs[PC]; 397232449Sjmallett sf.sf_uc.uc_mcontext.mullo = regs.r_regs[MULLO]; 398232449Sjmallett sf.sf_uc.uc_mcontext.mulhi = regs.r_regs[MULHI]; 399232584Sjmallett sf.sf_uc.uc_mcontext.mc_tls = (int32_t)(intptr_t)td->td_md.md_tls; 400232449Sjmallett sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC; /* magic number */ 401232449Sjmallett for (i = 1; i < 32; i++) 402232449Sjmallett sf.sf_uc.uc_mcontext.mc_regs[i] = regs.r_regs[i]; 403232449Sjmallett sf.sf_uc.uc_mcontext.mc_fpused = td->td_md.md_flags & MDTD_FPUSED; 404232449Sjmallett if (sf.sf_uc.uc_mcontext.mc_fpused) { 405232449Sjmallett /* if FPU has current state, save it first */ 406232449Sjmallett if (td == PCPU_GET(fpcurthread)) 407232449Sjmallett MipsSaveCurFPState(td); 408232449Sjmallett fill_fpregs32(td, &fpregs); 409232449Sjmallett for (i = 0; i < 33; i++) 410232449Sjmallett sf.sf_uc.uc_mcontext.mc_fpregs[i] = fpregs.r_regs[i]; 411232449Sjmallett } 412232449Sjmallett 413232449Sjmallett /* Allocate and validate space for the signal handler context. */ 414232449Sjmallett if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 415232449Sjmallett SIGISMEMBER(psp->ps_sigonstack, sig)) { 416232449Sjmallett sfp = (struct sigframe32 *)((vm_offset_t)(td->td_sigstk.ss_sp + 417232449Sjmallett td->td_sigstk.ss_size - sizeof(struct sigframe32)) 418232449Sjmallett & ~(sizeof(__int64_t) - 1)); 419232449Sjmallett } else 420232449Sjmallett sfp = (struct sigframe32 *)((vm_offset_t)(td->td_frame->sp - 421232449Sjmallett sizeof(struct sigframe32)) & ~(sizeof(__int64_t) - 1)); 422232449Sjmallett 423232449Sjmallett /* Build the argument list for the signal handler. */ 424232449Sjmallett td->td_frame->a0 = sig; 425232449Sjmallett td->td_frame->a2 = (register_t)(intptr_t)&sfp->sf_uc; 426232449Sjmallett if (SIGISMEMBER(psp->ps_siginfo, sig)) { 427232449Sjmallett /* Signal handler installed with SA_SIGINFO. */ 428232449Sjmallett td->td_frame->a1 = (register_t)(intptr_t)&sfp->sf_si; 429232449Sjmallett /* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */ 430232449Sjmallett 431232449Sjmallett /* fill siginfo structure */ 432232449Sjmallett sf.sf_si.si_signo = sig; 433232449Sjmallett sf.sf_si.si_code = ksi->ksi_code; 434232449Sjmallett sf.sf_si.si_addr = td->td_frame->badvaddr; 435232449Sjmallett } else { 436232449Sjmallett /* Old FreeBSD-style arguments. */ 437232449Sjmallett td->td_frame->a1 = ksi->ksi_code; 438232449Sjmallett td->td_frame->a3 = td->td_frame->badvaddr; 439232449Sjmallett /* sf.sf_ahu.sf_handler = catcher; */ 440232449Sjmallett } 441232449Sjmallett 442232449Sjmallett mtx_unlock(&psp->ps_mtx); 443232449Sjmallett PROC_UNLOCK(p); 444232449Sjmallett 445232449Sjmallett /* 446232449Sjmallett * Copy the sigframe out to the user's stack. 447232449Sjmallett */ 448232449Sjmallett if (copyout(&sf, sfp, sizeof(struct sigframe32)) != 0) { 449232449Sjmallett /* 450232449Sjmallett * Something is wrong with the stack pointer. 451232449Sjmallett * ...Kill the process. 452232449Sjmallett */ 453232449Sjmallett PROC_LOCK(p); 454232449Sjmallett sigexit(td, SIGILL); 455232449Sjmallett } 456232449Sjmallett 457232449Sjmallett td->td_frame->pc = (register_t)(intptr_t)catcher; 458232449Sjmallett td->td_frame->t9 = (register_t)(intptr_t)catcher; 459232449Sjmallett td->td_frame->sp = (register_t)(intptr_t)sfp; 460232449Sjmallett /* 461232449Sjmallett * Signal trampoline code is at base of user stack. 462232449Sjmallett */ 463232449Sjmallett td->td_frame->ra = (register_t)(intptr_t)FREEBSD32_PS_STRINGS - *(p->p_sysent->sv_szsigcode); 464232449Sjmallett PROC_LOCK(p); 465232449Sjmallett mtx_lock(&psp->ps_mtx); 466232449Sjmallett} 467232449Sjmallett 468232449Sjmallettint 469232449Sjmallettfreebsd32_sysarch(struct thread *td, struct freebsd32_sysarch_args *uap) 470232449Sjmallett{ 471232449Sjmallett int error; 472232449Sjmallett int32_t tlsbase; 473232449Sjmallett 474232449Sjmallett switch (uap->op) { 475232449Sjmallett case MIPS_SET_TLS: 476232449Sjmallett td->td_md.md_tls = (void *)(intptr_t)uap->parms; 477232449Sjmallett return (0); 478232449Sjmallett case MIPS_GET_TLS: 479232449Sjmallett tlsbase = (int32_t)(intptr_t)td->td_md.md_tls; 480232449Sjmallett error = copyout(&tlsbase, uap->parms, sizeof(tlsbase)); 481232449Sjmallett return (error); 482232449Sjmallett default: 483232449Sjmallett break; 484232449Sjmallett } 485232449Sjmallett return (EINVAL); 486232449Sjmallett} 487232449Sjmallett 488232449Sjmallettvoid 489232449Sjmallettelf32_dump_thread(struct thread *td __unused, void *dst __unused, 490232449Sjmallett size_t *off __unused) 491232449Sjmallett{ 492232449Sjmallett} 493