131567Ssef/*
2204977Simp * Copyright 1997 Sean Eric Fagan
331899Ssef *
431899Ssef * Redistribution and use in source and binary forms, with or without
531899Ssef * modification, are permitted provided that the following conditions
631899Ssef * are met:
731899Ssef * 1. Redistributions of source code must retain the above copyright
831899Ssef *    notice, this list of conditions and the following disclaimer.
931899Ssef * 2. Redistributions in binary form must reproduce the above copyright
1031899Ssef *    notice, this list of conditions and the following disclaimer in the
1131899Ssef *    documentation and/or other materials provided with the distribution.
1231899Ssef * 3. All advertising materials mentioning features or use of this software
1331899Ssef *    must display the following acknowledgement:
1431899Ssef *	This product includes software developed by Sean Eric Fagan
1531899Ssef * 4. Neither the name of the author may be used to endorse or promote
1631899Ssef *    products derived from this software without specific prior written
1731899Ssef *    permission.
1831899Ssef *
1931899Ssef * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2031899Ssef * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2131899Ssef * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2231899Ssef * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2331899Ssef * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2431899Ssef * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2531899Ssef * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2631899Ssef * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2731899Ssef * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2831899Ssef * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2931899Ssef * SUCH DAMAGE.
3031899Ssef */
3131899Ssef
32290052Sjhb#include <sys/cdefs.h>
33290052Sjhb__FBSDID("$FreeBSD$");
3432275Scharnier
35290052Sjhb/* FreeBSD/i386-specific system call handling. */
3631567Ssef
37240005Szont#include <sys/ptrace.h>
3885301Sdes#include <sys/syscall.h>
3985301Sdes
4085301Sdes#include <machine/reg.h>
4185301Sdes#include <machine/psl.h>
4285301Sdes
4331567Ssef#include <stdio.h>
4431567Ssef#include <stdlib.h>
4531567Ssef
46101282Smdodd#include "truss.h"
4731567Ssef
48179051Sjhb#include "freebsd32_syscalls.h"
4931567Ssef
50290052Sjhbstatic int
51290052Sjhbamd64_fbsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
52240562Szont{
53240005Szont	struct ptrace_io_desc iorequest;
54240005Szont	struct reg regs;
55290052Sjhb	struct current_syscall *cs;
56290052Sjhb	unsigned int args32[narg];
57290052Sjhb	unsigned long parm_offset;
58240562Szont	lwpid_t tid;
59290052Sjhb	u_int i;
6031567Ssef
61240562Szont	tid = trussinfo->curthread->tid;
62290052Sjhb	cs = &trussinfo->curthread->cs;
63240562Szont	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
64240005Szont		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
65290052Sjhb		return (-1);
66240005Szont	}
67240005Szont	parm_offset = regs.r_rsp + sizeof(int);
6831567Ssef
69240005Szont	/*
70290052Sjhb	 * FreeBSD has two special kinds of system call redirections --
71240005Szont	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
72240005Szont	 * routine, basically; the latter is for quad-aligned arguments.
73290052Sjhb	 *
74290052Sjhb	 * The system call argument count and code from ptrace() already
75290052Sjhb	 * account for these, but we need to skip over the first argument.
76240005Szont	 */
77290052Sjhb	switch (regs.r_rax) {
78240005Szont	case SYS_syscall:
79240005Szont		parm_offset += sizeof(int);
80240005Szont		break;
81240005Szont	case SYS___syscall:
82240005Szont		parm_offset += sizeof(quad_t);
83240005Szont		break;
84240005Szont	}
85101283Smdodd
86240005Szont	iorequest.piod_op = PIOD_READ_D;
87240005Szont	iorequest.piod_offs = (void *)parm_offset;
88290052Sjhb	iorequest.piod_addr = args32;
89290052Sjhb	iorequest.piod_len = sizeof(args32);
90240562Szont	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
91290052Sjhb	if (iorequest.piod_len == 0) {
92290052Sjhb		return (-1);
93240005Szont	}
9431567Ssef
95290052Sjhb	for (i = 0; i < narg; i++)
96290052Sjhb		 cs->args[i] = args32[i];
97290052Sjhb	return (0);
9831567Ssef}
9931567Ssef
100290052Sjhbstatic int
101290052Sjhbamd64_fbsd32_fetch_retval(struct trussinfo *trussinfo, long *retval,
102290052Sjhb    int *errorp)
103122348Smarcel{
104240005Szont	struct reg regs;
105240562Szont	lwpid_t tid;
10631567Ssef
107240562Szont	tid = trussinfo->curthread->tid;
108240562Szont	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
109240005Szont		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
110240005Szont		return (-1);
111240005Szont	}
11231567Ssef
113290052Sjhb	retval[0] = regs.r_rax & 0xffffffff;
114290052Sjhb	retval[1] = regs.r_rdx & 0xffffffff;
115290052Sjhb	*errorp = !!(regs.r_rflags & PSL_C);
116290052Sjhb	return (0);
117290052Sjhb}
118240005Szont
119290052Sjhbstatic struct procabi amd64_fbsd32 = {
120290052Sjhb	"FreeBSD ELF32",
121290052Sjhb	freebsd32_syscallnames,
122290052Sjhb	nitems(freebsd32_syscallnames),
123290052Sjhb	amd64_fbsd32_fetch_args,
124290052Sjhb	amd64_fbsd32_fetch_retval
125290052Sjhb};
12631567Ssef
127290052SjhbPROCABI(amd64_fbsd32);
128171055Sdelphij
129290052Sjhbstatic struct procabi amd64_fbsd32_aout = {
130290052Sjhb	"FreeBSD a.out",
131290052Sjhb	freebsd32_syscallnames,
132290052Sjhb	nitems(freebsd32_syscallnames),
133290052Sjhb	amd64_fbsd32_fetch_args,
134290052Sjhb	amd64_fbsd32_fetch_retval
135290052Sjhb};
13631567Ssef
137290052SjhbPROCABI(amd64_fbsd32_aout);
138