1138447Srwatson/* 2138447Srwatson * Copyright 2006 Peter Grehan <grehan@freebsd.org> 3138447Srwatson * Copyright 2005 Orlando Bassotto <orlando@break.net> 4138447Srwatson * Copyright 1998 Sean Eric Fagan 5138447Srwatson * 6138447Srwatson * Redistribution and use in source and binary forms, with or without 7138447Srwatson * modification, are permitted provided that the following conditions 8138447Srwatson * are met: 9138447Srwatson * 1. Redistributions of source code must retain the above copyright 10138447Srwatson * notice, this list of conditions and the following disclaimer. 11138447Srwatson * 2. Redistributions in binary form must reproduce the above copyright 12138447Srwatson * notice, this list of conditions and the following disclaimer in the 13138447Srwatson * documentation and/or other materials provided with the distribution. 14138447Srwatson * 15138447Srwatson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16138447Srwatson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17138447Srwatson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18138447Srwatson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19138447Srwatson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20138447Srwatson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21138447Srwatson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22138447Srwatson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23138447Srwatson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24138447Srwatson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25138447Srwatson * SUCH DAMAGE. 26138447Srwatson */ 27138447Srwatson 28138447Srwatson#include <sys/cdefs.h> 29138447Srwatson__FBSDID("$FreeBSD: releng/11.0/usr.bin/truss/powerpc64-freebsd.c 295056 2016-01-30 01:00:54Z jhb $"); 30138447Srwatson 31138447Srwatson/* FreeBSD/powerpc64-specific system call handling. */ 32138447Srwatson 33138447Srwatson#include <sys/ptrace.h> 34138447Srwatson#include <sys/syscall.h> 35138447Srwatson 36138447Srwatson#include <machine/reg.h> 37138447Srwatson#include <machine/frame.h> 38138447Srwatson 39138447Srwatson#include <stdio.h> 40138447Srwatson#include <sysdecode.h> 41280893Sngie 42280893Sngie#include "truss.h" 43302074Sjhb 44138447Srwatsonstatic int 45205224Skibpowerpc64_fetch_args(struct trussinfo *trussinfo, u_int narg) 46138447Srwatson{ 47138447Srwatson struct ptrace_io_desc iorequest; 48138447Srwatson struct reg regs; 49138447Srwatson struct current_syscall *cs; 50138447Srwatson lwpid_t tid; 51138447Srwatson u_int i, reg; 52205224Skib 53138447Srwatson tid = trussinfo->curthread->tid; 54253526Skib cs = &trussinfo->curthread->cs; 55138447Srwatson if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 56205224Skib fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 57138447Srwatson return (-1); 58138447Srwatson } 59138447Srwatson 60138447Srwatson /* 61281593Sngie * FreeBSD has two special kinds of system call redirections -- 62138447Srwatson * SYS_syscall, and SYS___syscall. The former is the old syscall() 63282135Sngie * routine, basically; the latter is for quad-aligned arguments. 64296277Sjhb * 65282135Sngie * The system call argument count and code from ptrace() already 66281593Sngie * account for these, but we need to skip over the first argument. 67281593Sngie */ 68138447Srwatson reg = 0; 69138447Srwatson switch (regs.fixreg[0]) { 70138447Srwatson case SYS_syscall: 71138447Srwatson case SYS___syscall: 72138447Srwatson reg += 1; 73138447Srwatson break; 74138447Srwatson } 75138447Srwatson 76138447Srwatson for (i = 0; i < narg && reg < NARGREG; i++, reg++) 77138447Srwatson cs->args[i] = regs.fixreg[FIRSTARG + reg]; 78138447Srwatson if (narg > i) { 79138447Srwatson iorequest.piod_op = PIOD_READ_D; 80138447Srwatson iorequest.piod_offs = (void *)(regs.fixreg[1] + 48); 81138447Srwatson iorequest.piod_addr = &cs->args[i]; 82138447Srwatson iorequest.piod_len = (narg - i) * sizeof(cs->args[0]); 83138447Srwatson ptrace(PT_IO, tid, (caddr_t)&iorequest, 0); 84138447Srwatson if (iorequest.piod_len == 0) 85138447Srwatson return (-1); 86138447Srwatson } 87138447Srwatson 88138447Srwatson return (0); 89138447Srwatson} 90138447Srwatson 91138447Srwatsonstatic int 92138447Srwatsonpowerpc64_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp) 93138447Srwatson{ 94280893Sngie struct reg regs; 95138447Srwatson lwpid_t tid; 96138447Srwatson 97138447Srwatson tid = trussinfo->curthread->tid; 98138447Srwatson if (ptrace(PT_GETREGS, tid, (caddr_t)®s, 0) < 0) { 99138447Srwatson fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n"); 100138447Srwatson return (-1); 101281593Sngie } 102138447Srwatson 103138447Srwatson retval[0] = regs.fixreg[3]; 104138447Srwatson retval[1] = regs.fixreg[4]; 105281593Sngie *errorp = !!(regs.cr & 0x10000000); 106281593Sngie return (0); 107138447Srwatson} 108138447Srwatson 109138447Srwatsonstatic struct procabi powerpc64_freebsd = { 110138447Srwatson "FreeBSD ELF64", 111281593Sngie SYSDECODE_ABI_FREEBSD, 112138447Srwatson powerpc64_fetch_args, 113138447Srwatson powerpc64_fetch_retval 114281593Sngie}; 115281593Sngie 116138447SrwatsonPROCABI(powerpc64_freebsd); 117138447Srwatson