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 32288424Sjhb#include <sys/cdefs.h> 33288424Sjhb__FBSDID("$FreeBSD: releng/11.0/usr.bin/truss/mips-freebsd.c 295056 2016-01-30 01:00:54Z jhb $"); 34188628Simp 35288424Sjhb/* 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> 44294849Sjhb#include <sysdecode.h> 45188628Simp 46188628Simp#include "truss.h" 47188628Simp 48288424Sjhbstatic int 49288424Sjhbmips_fetch_args(struct trussinfo *trussinfo, u_int narg) 50240562Szont{ 51240005Szont struct ptrace_io_desc iorequest; 52240005Szont struct reg regs; 53288424Sjhb struct current_syscall *cs; 54240562Szont lwpid_t tid; 55288424Sjhb u_int i, reg; 56188628Simp 57240562Szont tid = trussinfo->curthread->tid; 58288424Sjhb cs = &trussinfo->curthread->cs; 59240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 60240005Szont fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 61288424Sjhb return (-1); 62240005Szont } 63188628Simp 64288424Sjhb /* 65288424Sjhb * FreeBSD has two special kinds of system call redirections -- 66288424Sjhb * SYS_syscall, and SYS___syscall. The former is the old syscall() 67288424Sjhb * routine, basically; the latter is for quad-aligned arguments. 68288424Sjhb * 69288424Sjhb * The system call argument count and code from ptrace() already 70288424Sjhb * account for these, but we need to skip over the first argument. 71288424Sjhb */ 72288424Sjhb reg = A0; 73288424Sjhb switch (regs.r_regs[V0]) { 74288424Sjhb case SYS_syscall: 75288424Sjhb reg = A1; 76288424Sjhb break; 77288424Sjhb case SYS___syscall: 78288424Sjhb#if defined(__mips_n32) || defined(__mips_n64) 79288424Sjhb reg = A1; 80288424Sjhb#else 81288424Sjhb reg = A2; 82288424Sjhb#endif 83288424Sjhb break; 84240005Szont } 85188628Simp 86288424Sjhb#if defined(__mips_n32) || defined(__mips_n64) 87288424Sjhb#define MAXREG A7 88188628Simp#else 89288424Sjhb#define MAXREG A3 90188628Simp#endif 91188628Simp 92288424Sjhb for (i = 0; i < narg && reg <= MAXREG; i++, reg++) 93288424Sjhb cs->args[i] = regs.r_regs[reg]; 94288424Sjhb if (narg > i) { 95240005Szont iorequest.piod_op = PIOD_READ_D; 96288424Sjhb iorequest.piod_offs = (void *)((uintptr_t)regs.r_regs[SP] + 97288424Sjhb 4 * sizeof(cs->args[0])); 98288424Sjhb iorequest.piod_addr = &cs->args[i]; 99288424Sjhb iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); 100240562Szont ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); 101240005Szont if (iorequest.piod_len == 0) 102288424Sjhb return (-1); 103240005Szont } 104188628Simp 105288424Sjhb return (0); 106188628Simp} 107188628Simp 108288424Sjhbstatic int 109288424Sjhbmips_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) 110240005Szont{ 111240005Szont struct reg regs; 112240562Szont lwpid_t tid; 113188628Simp 114240562Szont tid = trussinfo->curthread->tid; 115240562Szont if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 116288424Sjhb fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 117240005Szont return (-1); 118240005Szont } 119188628Simp 120288424Sjhb /* XXX: Does not have special handling for __syscall(). */ 121288424Sjhb retval[0] = regs.r_regs[V0]; 122288424Sjhb retval[1] = regs.r_regs[V1]; 123288424Sjhb *errorp = !!regs.r_regs[A3]; 124288424Sjhb return (0); 125288424Sjhb} 126240005Szont 127188628Simp 128289239Sbdrewerystatic struct procabi mips_freebsd = { 129288424Sjhb#ifdef __mips_n64 130288424Sjhb "FreeBSD ELF64", 131288424Sjhb#else 132288424Sjhb "FreeBSD ELF32", 133288424Sjhb#endif 134295056Sjhb SYSDECODE_ABI_FREEBSD, 135288424Sjhb mips_fetch_args, 136288424Sjhb mips_fetch_retval 137288424Sjhb}; 138286938Sjhb 139289239SbdreweryPROCABI(mips_freebsd); 140