1178172Simp/*- 2178172Simp * Copyright (c) 1992 Terrence R. Lambert. 3178172Simp * Copyright (c) 1982, 1987, 1990 The Regents of the University of California. 4178172Simp * All rights reserved. 5178172Simp * 6178172Simp * This code is derived from software contributed to Berkeley by 7178172Simp * William Jolitz. 8178172Simp * 9178172Simp * Redistribution and use in source and binary forms, with or without 10178172Simp * modification, are permitted provided that the following conditions 11178172Simp * are met: 12178172Simp * 1. Redistributions of source code must retain the above copyright 13178172Simp * notice, this list of conditions and the following disclaimer. 14178172Simp * 2. Redistributions in binary form must reproduce the above copyright 15178172Simp * notice, this list of conditions and the following disclaimer in the 16178172Simp * documentation and/or other materials provided with the distribution. 17178172Simp * 4. Neither the name of the University nor the names of its contributors 18178172Simp * may be used to endorse or promote products derived from this software 19178172Simp * without specific prior written permission. 20178172Simp * 21178172Simp * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23178172Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24178172Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25178172Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26178172Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27178172Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28178172Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29178172Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30178172Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31178172Simp * SUCH DAMAGE. 32178172Simp * 33178172Simp * from: @(#)machdep.c 7.4 (Berkeley) 6/3/91 34178172Simp * from: src/sys/i386/i386/machdep.c,v 1.385.2.3 2000/05/10 02:04:46 obrien 35178172Simp * JNPR: pm_machdep.c,v 1.9.2.1 2007/08/16 15:59:10 girish 36178172Simp */ 37178172Simp 38178172Simp#include <sys/cdefs.h> 39178172Simp__FBSDID("$FreeBSD$"); 40178172Simp 41178172Simp#include "opt_compat.h" 42202046Simp 43178172Simp#include <sys/types.h> 44178172Simp#include <sys/param.h> 45178172Simp#include <sys/systm.h> 46178172Simp#include <sys/sysent.h> 47178172Simp#include <sys/proc.h> 48178172Simp#include <sys/signalvar.h> 49178172Simp#include <sys/exec.h> 50178172Simp#include <sys/imgact.h> 51178172Simp#include <sys/ucontext.h> 52178172Simp#include <sys/lock.h> 53209613Sjhb#include <sys/syscallsubr.h> 54178172Simp#include <sys/sysproto.h> 55178172Simp#include <sys/ptrace.h> 56178172Simp#include <sys/syslog.h> 57178172Simp#include <vm/vm.h> 58178172Simp#include <vm/pmap.h> 59178172Simp#include <vm/vm_map.h> 60178172Simp#include <vm/vm_extern.h> 61178172Simp#include <sys/user.h> 62178172Simp#include <sys/uio.h> 63178172Simp#include <machine/reg.h> 64178172Simp#include <machine/md_var.h> 65178172Simp#include <machine/sigframe.h> 66178172Simp#include <machine/vmparam.h> 67178172Simp#include <sys/vnode.h> 68178172Simp#include <fs/pseudofs/pseudofs.h> 69178172Simp#include <fs/procfs/procfs.h> 70178172Simp 71178172Simp#define UCONTEXT_MAGIC 0xACEDBADE 72178172Simp 73178172Simp/* 74178172Simp * Send an interrupt to process. 75178172Simp * 76178172Simp * Stack is set up to allow sigcode stored 77178172Simp * at top to call routine, followed by kcall 78178172Simp * to sigreturn routine below. After sigreturn 79178172Simp * resets the signal mask, the stack, and the 80178172Simp * frame pointer, it returns to the user 81178172Simp * specified pc, psl. 82178172Simp */ 83178172Simpvoid 84178172Simpsendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) 85178172Simp{ 86178172Simp struct proc *p; 87178172Simp struct thread *td; 88178172Simp struct trapframe *regs; 89178172Simp struct sigacts *psp; 90178172Simp struct sigframe sf, *sfp; 91178172Simp int sig; 92178172Simp int oonstack; 93178172Simp 94178172Simp td = curthread; 95178172Simp p = td->td_proc; 96178172Simp PROC_LOCK_ASSERT(p, MA_OWNED); 97178172Simp sig = ksi->ksi_signo; 98178172Simp psp = p->p_sigacts; 99178172Simp mtx_assert(&psp->ps_mtx, MA_OWNED); 100178172Simp 101178172Simp regs = td->td_frame; 102178172Simp oonstack = sigonstack(regs->sp); 103178172Simp 104178172Simp /* save user context */ 105178172Simp bzero(&sf, sizeof(struct sigframe)); 106178172Simp sf.sf_uc.uc_sigmask = *mask; 107178172Simp sf.sf_uc.uc_stack = td->td_sigstk; 108178172Simp sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0; 109178172Simp sf.sf_uc.uc_mcontext.mc_pc = regs->pc; 110178172Simp sf.sf_uc.uc_mcontext.mullo = regs->mullo; 111178172Simp sf.sf_uc.uc_mcontext.mulhi = regs->mulhi; 112232585Sjmallett sf.sf_uc.uc_mcontext.mc_tls = td->td_md.md_tls; 113178172Simp sf.sf_uc.uc_mcontext.mc_regs[0] = UCONTEXT_MAGIC; /* magic number */ 114178172Simp bcopy((void *)®s->ast, (void *)&sf.sf_uc.uc_mcontext.mc_regs[1], 115178172Simp sizeof(sf.sf_uc.uc_mcontext.mc_regs) - sizeof(register_t)); 116178172Simp sf.sf_uc.uc_mcontext.mc_fpused = td->td_md.md_flags & MDTD_FPUSED; 117178172Simp if (sf.sf_uc.uc_mcontext.mc_fpused) { 118178172Simp /* if FPU has current state, save it first */ 119178172Simp if (td == PCPU_GET(fpcurthread)) 120178172Simp MipsSaveCurFPState(td); 121178172Simp bcopy((void *)&td->td_frame->f0, 122178172Simp (void *)sf.sf_uc.uc_mcontext.mc_fpregs, 123178172Simp sizeof(sf.sf_uc.uc_mcontext.mc_fpregs)); 124178172Simp } 125178172Simp 126178172Simp /* Allocate and validate space for the signal handler context. */ 127178172Simp if ((td->td_pflags & TDP_ALTSTACK) != 0 && !oonstack && 128178172Simp SIGISMEMBER(psp->ps_sigonstack, sig)) { 129294930Sjhb sfp = (struct sigframe *)(((uintptr_t)td->td_sigstk.ss_sp + 130178172Simp td->td_sigstk.ss_size - sizeof(struct sigframe)) 131178172Simp & ~(sizeof(__int64_t) - 1)); 132178172Simp } else 133178172Simp sfp = (struct sigframe *)((vm_offset_t)(regs->sp - 134178172Simp sizeof(struct sigframe)) & ~(sizeof(__int64_t) - 1)); 135178172Simp 136178172Simp /* Build the argument list for the signal handler. */ 137178172Simp regs->a0 = sig; 138209500Sjchandra regs->a2 = (register_t)(intptr_t)&sfp->sf_uc; 139178172Simp if (SIGISMEMBER(psp->ps_siginfo, sig)) { 140178172Simp /* Signal handler installed with SA_SIGINFO. */ 141209500Sjchandra regs->a1 = (register_t)(intptr_t)&sfp->sf_si; 142178172Simp /* sf.sf_ahu.sf_action = (__siginfohandler_t *)catcher; */ 143178172Simp 144178172Simp /* fill siginfo structure */ 145178172Simp sf.sf_si.si_signo = sig; 146178172Simp sf.sf_si.si_code = ksi->ksi_code; 147209500Sjchandra sf.sf_si.si_addr = (void*)(intptr_t)regs->badvaddr; 148178172Simp } else { 149178172Simp /* Old FreeBSD-style arguments. */ 150178172Simp regs->a1 = ksi->ksi_code; 151178172Simp regs->a3 = regs->badvaddr; 152178172Simp /* sf.sf_ahu.sf_handler = catcher; */ 153178172Simp } 154178172Simp 155178172Simp mtx_unlock(&psp->ps_mtx); 156178172Simp PROC_UNLOCK(p); 157178172Simp 158178172Simp /* 159178172Simp * Copy the sigframe out to the user's stack. 160178172Simp */ 161178172Simp if (copyout(&sf, sfp, sizeof(struct sigframe)) != 0) { 162178172Simp /* 163178172Simp * Something is wrong with the stack pointer. 164178172Simp * ...Kill the process. 165178172Simp */ 166178172Simp PROC_LOCK(p); 167178172Simp sigexit(td, SIGILL); 168178172Simp } 169178172Simp 170209500Sjchandra regs->pc = (register_t)(intptr_t)catcher; 171209500Sjchandra regs->t9 = (register_t)(intptr_t)catcher; 172209500Sjchandra regs->sp = (register_t)(intptr_t)sfp; 173178172Simp /* 174178172Simp * Signal trampoline code is at base of user stack. 175178172Simp */ 176209500Sjchandra regs->ra = (register_t)(intptr_t)PS_STRINGS - *(p->p_sysent->sv_szsigcode); 177178172Simp PROC_LOCK(p); 178178172Simp mtx_lock(&psp->ps_mtx); 179178172Simp} 180178172Simp 181178172Simp/* 182178172Simp * System call to cleanup state after a signal 183178172Simp * has been taken. Reset signal mask and 184178172Simp * stack state from context left by sendsig (above). 185178172Simp * Return to previous pc as specified by 186178172Simp * context left by sendsig. 187178172Simp */ 188178172Simpint 189225617Skmacysys_sigreturn(struct thread *td, struct sigreturn_args *uap) 190178172Simp{ 191178172Simp ucontext_t uc; 192178172Simp int error; 193178172Simp 194178172Simp error = copyin(uap->sigcntxp, &uc, sizeof(uc)); 195178172Simp if (error != 0) 196178172Simp return (error); 197178172Simp 198232586Sjmallett error = set_mcontext(td, &uc.uc_mcontext); 199232586Sjmallett if (error != 0) 200232586Sjmallett return (error); 201178172Simp 202232586Sjmallett kern_sigprocmask(td, SIG_SETMASK, &uc.uc_sigmask, NULL, 0); 203178172Simp 204232586Sjmallett return (EJUSTRETURN); 205178172Simp} 206178172Simp 207178172Simpint 208178172Simpptrace_set_pc(struct thread *td, unsigned long addr) 209178172Simp{ 210178172Simp td->td_frame->pc = (register_t) addr; 211178172Simp return 0; 212178172Simp} 213178172Simp 214178172Simpstatic int 215178172Simpptrace_read_int(struct thread *td, off_t addr, int *v) 216178172Simp{ 217178172Simp 218291961Smarkj if (proc_readmem(td, td->td_proc, addr, v, sizeof(*v)) != sizeof(*v)) 219291961Smarkj return (ENOMEM); 220291961Smarkj return (0); 221178172Simp} 222178172Simp 223178172Simpstatic int 224178172Simpptrace_write_int(struct thread *td, off_t addr, int v) 225178172Simp{ 226178172Simp 227291961Smarkj if (proc_writemem(td, td->td_proc, addr, &v, sizeof(v)) != sizeof(v)) 228291961Smarkj return (ENOMEM); 229291961Smarkj return (0); 230178172Simp} 231178172Simp 232178172Simpint 233178172Simpptrace_single_step(struct thread *td) 234178172Simp{ 235178172Simp unsigned va; 236178172Simp struct trapframe *locr0 = td->td_frame; 237178172Simp int i; 238210038Simp int bpinstr = MIPS_BREAK_SSTEP; 239178172Simp int curinstr; 240178172Simp struct proc *p; 241178172Simp 242178172Simp p = td->td_proc; 243178172Simp PROC_UNLOCK(p); 244178172Simp /* 245178172Simp * Fetch what's at the current location. 246178172Simp */ 247178172Simp ptrace_read_int(td, (off_t)locr0->pc, &curinstr); 248178172Simp 249178172Simp /* compute next address after current location */ 250178172Simp if(curinstr != 0) { 251178172Simp va = MipsEmulateBranch(locr0, locr0->pc, locr0->fsr, 252202046Simp (uintptr_t)&curinstr); 253178172Simp } else { 254178172Simp va = locr0->pc + 4; 255178172Simp } 256178172Simp if (td->td_md.md_ss_addr) { 257178172Simp printf("SS %s (%d): breakpoint already set at %x (va %x)\n", 258178172Simp p->p_comm, p->p_pid, td->td_md.md_ss_addr, va); /* XXX */ 259178172Simp return (EFAULT); 260178172Simp } 261178172Simp td->td_md.md_ss_addr = va; 262178172Simp /* 263178172Simp * Fetch what's at the current location. 264178172Simp */ 265178172Simp ptrace_read_int(td, (off_t)va, &td->td_md.md_ss_instr); 266178172Simp 267178172Simp /* 268178172Simp * Store breakpoint instruction at the "next" location now. 269178172Simp */ 270178172Simp i = ptrace_write_int (td, va, bpinstr); 271178172Simp 272178172Simp /* 273178172Simp * The sync'ing of I & D caches is done by procfs_domem() 274178172Simp * through procfs_rwmem(). 275178172Simp */ 276178172Simp 277178172Simp PROC_LOCK(p); 278178172Simp if (i < 0) 279178172Simp return (EFAULT); 280178172Simp#if 0 281178172Simp printf("SS %s (%d): breakpoint set at %x: %x (pc %x) br %x\n", 282178172Simp p->p_comm, p->p_pid, p->p_md.md_ss_addr, 283178172Simp p->p_md.md_ss_instr, locr0->pc, curinstr); /* XXX */ 284178172Simp#endif 285178172Simp return (0); 286178172Simp} 287178172Simp 288178172Simp 289178172Simpvoid 290178172Simpmakectx(struct trapframe *tf, struct pcb *pcb) 291178172Simp{ 292178172Simp 293178172Simp pcb->pcb_regs.ra = tf->ra; 294178172Simp pcb->pcb_regs.pc = tf->pc; 295178172Simp pcb->pcb_regs.sp = tf->sp; 296178172Simp} 297178172Simp 298178172Simpint 299178172Simpfill_regs(struct thread *td, struct reg *regs) 300178172Simp{ 301178172Simp memcpy(regs, td->td_frame, sizeof(struct reg)); 302178172Simp return (0); 303178172Simp} 304178172Simp 305178172Simpint 306178172Simpset_regs(struct thread *td, struct reg *regs) 307178172Simp{ 308178172Simp struct trapframe *f; 309178172Simp register_t sr; 310178172Simp 311178172Simp f = (struct trapframe *) td->td_frame; 312178172Simp /* 313178172Simp * Don't allow the user to change SR 314178172Simp */ 315178172Simp sr = f->sr; 316178172Simp memcpy(td->td_frame, regs, sizeof(struct reg)); 317178172Simp f->sr = sr; 318178172Simp return (0); 319178172Simp} 320178172Simp 321178172Simpint 322178172Simpget_mcontext(struct thread *td, mcontext_t *mcp, int flags) 323178172Simp{ 324178172Simp struct trapframe *tp; 325178172Simp 326178172Simp tp = td->td_frame; 327178172Simp PROC_LOCK(curthread->td_proc); 328178172Simp mcp->mc_onstack = sigonstack(tp->sp); 329178172Simp PROC_UNLOCK(curthread->td_proc); 330178172Simp bcopy((void *)&td->td_frame->zero, (void *)&mcp->mc_regs, 331178172Simp sizeof(mcp->mc_regs)); 332178172Simp 333178172Simp mcp->mc_fpused = td->td_md.md_flags & MDTD_FPUSED; 334178172Simp if (mcp->mc_fpused) { 335178172Simp bcopy((void *)&td->td_frame->f0, (void *)&mcp->mc_fpregs, 336178172Simp sizeof(mcp->mc_fpregs)); 337178172Simp } 338202046Simp if (flags & GET_MC_CLEAR_RET) { 339202046Simp mcp->mc_regs[V0] = 0; 340202046Simp mcp->mc_regs[V1] = 0; 341202046Simp mcp->mc_regs[A3] = 0; 342202046Simp } 343202046Simp 344178172Simp mcp->mc_pc = td->td_frame->pc; 345178172Simp mcp->mullo = td->td_frame->mullo; 346178172Simp mcp->mulhi = td->td_frame->mulhi; 347202046Simp mcp->mc_tls = td->td_md.md_tls; 348178172Simp return (0); 349178172Simp} 350178172Simp 351178172Simpint 352278001Skibset_mcontext(struct thread *td, mcontext_t *mcp) 353178172Simp{ 354178172Simp struct trapframe *tp; 355178172Simp 356178172Simp tp = td->td_frame; 357178172Simp bcopy((void *)&mcp->mc_regs, (void *)&td->td_frame->zero, 358178172Simp sizeof(mcp->mc_regs)); 359178172Simp 360178172Simp td->td_md.md_flags = mcp->mc_fpused & MDTD_FPUSED; 361178172Simp if (mcp->mc_fpused) { 362178172Simp bcopy((void *)&mcp->mc_fpregs, (void *)&td->td_frame->f0, 363178172Simp sizeof(mcp->mc_fpregs)); 364178172Simp } 365178172Simp td->td_frame->pc = mcp->mc_pc; 366178172Simp td->td_frame->mullo = mcp->mullo; 367178172Simp td->td_frame->mulhi = mcp->mulhi; 368202046Simp td->td_md.md_tls = mcp->mc_tls; 369264625Srwatson /* Dont let user to set any bits in status and cause registers. */ 370178172Simp 371178172Simp return (0); 372178172Simp} 373178172Simp 374178172Simpint 375178172Simpfill_fpregs(struct thread *td, struct fpreg *fpregs) 376178172Simp{ 377178172Simp if (td == PCPU_GET(fpcurthread)) 378178172Simp MipsSaveCurFPState(td); 379178172Simp memcpy(fpregs, &td->td_frame->f0, sizeof(struct fpreg)); 380178172Simp return 0; 381178172Simp} 382178172Simp 383178172Simpint 384178172Simpset_fpregs(struct thread *td, struct fpreg *fpregs) 385178172Simp{ 386178172Simp if (PCPU_GET(fpcurthread) == td) 387178172Simp PCPU_SET(fpcurthread, (struct thread *)0); 388178172Simp memcpy(&td->td_frame->f0, fpregs, sizeof(struct fpreg)); 389178172Simp return 0; 390178172Simp} 391178172Simp 392178172Simp 393178172Simp/* 394178172Simp * Clear registers on exec 395178172Simp * $sp is set to the stack pointer passed in. $pc is set to the entry 396178172Simp * point given by the exec_package passed in, as is $t9 (used for PIC 397178172Simp * code by the MIPS elf abi). 398178172Simp */ 399178172Simpvoid 400205642Snwhitehornexec_setregs(struct thread *td, struct image_params *imgp, u_long stack) 401178172Simp{ 402178172Simp 403178172Simp bzero((caddr_t)td->td_frame, sizeof(struct trapframe)); 404178172Simp 405178172Simp /* 406210595Sjmallett * The stack pointer has to be aligned to accommodate the largest 407210595Sjmallett * datatype at minimum. This probably means it should be 16-byte 408210595Sjmallett * aligned, but for now we're 8-byte aligning it. 409178172Simp */ 410178172Simp td->td_frame->sp = ((register_t) stack) & ~(sizeof(__int64_t) - 1); 411210595Sjmallett 412210595Sjmallett /* 413210595Sjmallett * If we're running o32 or n32 programs but have 64-bit registers, 414210595Sjmallett * GCC may use stack-relative addressing near the top of user 415210595Sjmallett * address space that, due to sign extension, will yield an 416210595Sjmallett * invalid address. For instance, if sp is 0x7fffff00 then GCC 417210595Sjmallett * might do something like this to load a word from 0x7ffffff0: 418210595Sjmallett * 419210595Sjmallett * addu sp, sp, 32768 420210595Sjmallett * lw t0, -32528(sp) 421210595Sjmallett * 422210595Sjmallett * On systems with 64-bit registers, sp is sign-extended to 423210595Sjmallett * 0xffffffff80007f00 and the load is instead done from 424210595Sjmallett * 0xffffffff7ffffff0. 425210595Sjmallett * 426210595Sjmallett * To prevent this, we subtract 64K from the stack pointer here. 427210595Sjmallett * 428210595Sjmallett * For consistency, we should just always do this unless we're 429210595Sjmallett * running n64 programs. For now, since we don't support 430210595Sjmallett * COMPAT_FREEBSD32 on n64 kernels, we just do it unless we're 431210595Sjmallett * running n64 kernels. 432210595Sjmallett */ 433210595Sjmallett#if !defined(__mips_n64) 434210595Sjmallett td->td_frame->sp -= 65536; 435210595Sjmallett#endif 436210595Sjmallett 437205642Snwhitehorn td->td_frame->pc = imgp->entry_addr & ~3; 438205642Snwhitehorn td->td_frame->t9 = imgp->entry_addr & ~3; /* abicall req */ 439210038Simp td->td_frame->sr = MIPS_SR_KSU_USER | MIPS_SR_EXL | MIPS_SR_INT_IE | 440210038Simp (mips_rd_status() & MIPS_SR_INT_MASK); 441210644Sjchandra#if defined(__mips_n32) 442210038Simp td->td_frame->sr |= MIPS_SR_PX; 443210644Sjchandra#elif defined(__mips_n64) 444211218Sjchandra td->td_frame->sr |= MIPS_SR_PX | MIPS_SR_UX | MIPS_SR_KX; 445178172Simp#endif 446178172Simp /* 447178172Simp * FREEBSD_DEVELOPERS_FIXME: 448178172Simp * Setup any other CPU-Specific registers (Not MIPS Standard) 449178172Simp * and/or bits in other standard MIPS registers (if CPU-Specific) 450178172Simp * that are needed. 451178172Simp */ 452178172Simp 453178172Simp /* 454178172Simp * Set up arguments for the rtld-capable crt0: 455178172Simp * a0 stack pointer 456178172Simp * a1 rtld cleanup (filled in by dynamic loader) 457178172Simp * a2 rtld object (filled in by dynamic loader) 458178172Simp * a3 ps_strings 459178172Simp */ 460178172Simp td->td_frame->a0 = (register_t) stack; 461178172Simp td->td_frame->a1 = 0; 462178172Simp td->td_frame->a2 = 0; 463205642Snwhitehorn td->td_frame->a3 = (register_t)imgp->ps_strings; 464178172Simp 465178172Simp td->td_md.md_flags &= ~MDTD_FPUSED; 466178172Simp if (PCPU_GET(fpcurthread) == td) 467178172Simp PCPU_SET(fpcurthread, (struct thread *)0); 468178172Simp td->td_md.md_ss_addr = 0; 469178172Simp} 470178172Simp 471178172Simpint 472178172Simpptrace_clear_single_step(struct thread *td) 473178172Simp{ 474178172Simp int i; 475178172Simp struct proc *p; 476178172Simp 477178172Simp p = td->td_proc; 478178172Simp PROC_LOCK_ASSERT(p, MA_OWNED); 479178172Simp if (!td->td_md.md_ss_addr) 480178172Simp return EINVAL; 481178172Simp 482178172Simp /* 483178172Simp * Restore original instruction and clear BP 484178172Simp */ 485178172Simp i = ptrace_write_int (td, td->td_md.md_ss_addr, td->td_md.md_ss_instr); 486178172Simp 487178172Simp /* The sync'ing of I & D caches is done by procfs_domem(). */ 488178172Simp 489178172Simp if (i < 0) { 490178172Simp log(LOG_ERR, "SS %s %d: can't restore instruction at %x: %x\n", 491178172Simp p->p_comm, p->p_pid, td->td_md.md_ss_addr, 492178172Simp td->td_md.md_ss_instr); 493178172Simp } 494178172Simp td->td_md.md_ss_addr = 0; 495178172Simp return 0; 496178172Simp} 497