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