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)&regs, 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)&regs, 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