1188628Simp/* 2204977Simp * Copyright 1998 Sean Eric Fagan 3188628Simp * 4188628Simp * Redistribution and use in source and binary forms, with or without 5188628Simp * modification, are permitted provided that the following conditions 6188628Simp * are met: 7188628Simp * 1. Redistributions of source code must retain the above copyright 8188628Simp * notice, this list of conditions and the following disclaimer. 9188628Simp * 2. Redistributions in binary form must reproduce the above copyright 10188628Simp * notice, this list of conditions and the following disclaimer in the 11188628Simp * documentation and/or other materials provided with the distribution. 12188628Simp * 3. All advertising materials mentioning features or use of this software 13188628Simp * must display the following acknowledgement: 14188628Simp * This product includes software developed by Sean Eric Fagan 15188628Simp * 4. Neither the name of the author may be used to endorse or promote 16188628Simp * products derived from this software without specific prior written 17188628Simp * permission. 18188628Simp * 19188628Simp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20188628Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21188628Simp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22188628Simp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23188628Simp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24188628Simp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25188628Simp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26188628Simp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27188628Simp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28188628Simp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29188628Simp * SUCH DAMAGE. 30188628Simp */ 31188628Simp 32290052Sjhb#include <sys/cdefs.h> 33290052Sjhb__FBSDID("$FreeBSD$"); 34188628Simp 35290052Sjhb/* FreeBSD/mips-specific system call handling. */ 36188628Simp 37188628Simp#include <sys/ptrace.h> 38188628Simp#include <sys/syscall.h> 39188628Simp 40188628Simp#include <machine/frame.h> 41188628Simp#include <machine/reg.h> 42188628Simp 43188628Simp#include <stdio.h> 44188628Simp 45188628Simp#include "truss.h" 46188628Simp 47188628Simp#include "syscalls.h" 48188628Simp 49290052Sjhbstatic int 50290052Sjhbmips_fetch_args(struct trussinfo *trussinfo, u_int narg) 51240562Szont{ 52240005Szont struct ptrace_io_desc iorequest; 53240005Szont struct reg regs; 54290052Sjhb struct current_syscall *cs; 55240562Szont lwpid_t tid; 56290052Sjhb u_int i, reg; 57188628Simp 58240562Szont tid = trussinfo->curthread->tid; 59290052Sjhb cs = &trussinfo->curthread->cs; 60240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 61240005Szont fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 62290052Sjhb return (-1); 63240005Szont } 64188628Simp 65290052Sjhb /* 66290052Sjhb * FreeBSD has two special kinds of system call redirections -- 67290052Sjhb * SYS_syscall, and SYS___syscall. The former is the old syscall() 68290052Sjhb * routine, basically; the latter is for quad-aligned arguments. 69290052Sjhb * 70290052Sjhb * The system call argument count and code from ptrace() already 71290052Sjhb * account for these, but we need to skip over the first argument. 72290052Sjhb */ 73290052Sjhb reg = A0; 74290052Sjhb switch (regs.r_regs[V0]) { 75290052Sjhb case SYS_syscall: 76290052Sjhb reg = A1; 77290052Sjhb break; 78290052Sjhb case SYS___syscall: 79290052Sjhb#if defined(__mips_n32) || defined(__mips_n64) 80290052Sjhb reg = A1; 81290052Sjhb#else 82290052Sjhb reg = A2; 83290052Sjhb#endif 84290052Sjhb break; 85240005Szont } 86188628Simp 87290052Sjhb#if defined(__mips_n32) || defined(__mips_n64) 88290052Sjhb#define MAXREG A7 89188628Simp#else 90290052Sjhb#define MAXREG A3 91188628Simp#endif 92188628Simp 93290052Sjhb for (i = 0; i < narg && reg <= MAXREG; i++, reg++) 94290052Sjhb cs->args[i] = regs.r_regs[reg]; 95290052Sjhb if (narg > i) { 96240005Szont iorequest.piod_op = PIOD_READ_D; 97290052Sjhb iorequest.piod_offs = (void *)((uintptr_t)regs.r_regs[SP] + 98290052Sjhb 4 * sizeof(cs->args[0])); 99290052Sjhb iorequest.piod_addr = &cs->args[i]; 100290052Sjhb iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); 101240562Szont ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); 102240005Szont if (iorequest.piod_len == 0) 103290052Sjhb return (-1); 104240005Szont } 105188628Simp 106290052Sjhb return (0); 107188628Simp} 108188628Simp 109290052Sjhbstatic int 110290052Sjhbmips_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) 111240005Szont{ 112240005Szont struct reg regs; 113240562Szont lwpid_t tid; 114188628Simp 115240562Szont tid = trussinfo->curthread->tid; 116240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 117290052Sjhb fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 118240005Szont return (-1); 119240005Szont } 120188628Simp 121290052Sjhb /* XXX: Does not have special handling for __syscall(). */ 122290052Sjhb retval[0] = regs.r_regs[V0]; 123290052Sjhb retval[1] = regs.r_regs[V1]; 124290052Sjhb *errorp = !!regs.r_regs[A3]; 125290052Sjhb return (0); 126290052Sjhb} 127240005Szont 128188628Simp 129290052Sjhbstatic struct procabi mips_fbsd = { 130290052Sjhb#ifdef __mips_n64 131290052Sjhb "FreeBSD ELF64", 132290052Sjhb#else 133290052Sjhb "FreeBSD ELF32", 134290052Sjhb#endif 135290052Sjhb syscallnames, 136290052Sjhb nitems(syscallnames), 137290052Sjhb mips_fetch_args, 138290052Sjhb mips_fetch_retval 139290052Sjhb}; 140188628Simp 141290052SjhbPROCABI(mips_fbsd); 142