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
45101282Smdodd#include "truss.h"
4631567Ssef
4731567Ssef#include "syscalls.h"
4831567Ssef
49290052Sjhbstatic int
50290052Sjhbi386_fetch_args(struct trussinfo *trussinfo, u_int narg)
51240562Szont{
52240005Szont	struct ptrace_io_desc iorequest;
53240005Szont	struct reg regs;
54290052Sjhb	struct current_syscall *cs;
55240562Szont	lwpid_t tid;
56240005Szont	unsigned int parm_offset;
5731567Ssef
58240562Szont	tid = trussinfo->curthread->tid;
59290052Sjhb	cs = &trussinfo->curthread->cs;
60240562Szont	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
61240005Szont		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
62290052Sjhb		return (-1);
63240005Szont	}
64240005Szont	parm_offset = regs.r_esp + sizeof(int);
6531567Ssef
66240005Szont	/*
67290052Sjhb	 * FreeBSD has two special kinds of system call redirections --
68240005Szont	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
69240005Szont	 * routine, basically; the latter is for quad-aligned arguments.
70290052Sjhb	 *
71290052Sjhb	 * The system call argument count and code from ptrace() already
72290052Sjhb	 * account for these, but we need to skip over the first argument.
73240005Szont	 */
74290052Sjhb	switch (regs.r_eax) {
75240005Szont	case SYS_syscall:
76240005Szont		parm_offset += sizeof(int);
77240005Szont		break;
78240005Szont	case SYS___syscall:
79240005Szont		parm_offset += sizeof(quad_t);
80240005Szont		break;
81240005Szont	}
82101283Smdodd
83240005Szont	iorequest.piod_op = PIOD_READ_D;
84240005Szont	iorequest.piod_offs = (void *)parm_offset;
85290052Sjhb	iorequest.piod_addr = cs->args;
86290052Sjhb	iorequest.piod_len = narg * sizeof(unsigned long);
87240562Szont	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
88240005Szont	if (iorequest.piod_len == 0)
89290052Sjhb		return (-1);
90240005Szont
91290052Sjhb	return (0);
9231567Ssef}
9331567Ssef
94290052Sjhbstatic int
95290052Sjhbi386_fetch_retval(struct trussinfo *trussinfo, long *retval, int *errorp)
96122348Smarcel{
97240005Szont	struct reg regs;
98240562Szont	lwpid_t tid;
9931567Ssef
100240562Szont	tid = trussinfo->curthread->tid;
101240562Szont	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
102240005Szont		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
103240005Szont		return (-1);
104240005Szont	}
10531567Ssef
106290052Sjhb	retval[0] = regs.r_eax;
107290052Sjhb	retval[1] = regs.r_edx;
108290052Sjhb	*errorp = !!(regs.r_eflags & PSL_C);
109290052Sjhb	return (0);
110290052Sjhb}
111240005Szont
112290052Sjhbstatic struct procabi i386_fbsd = {
113290052Sjhb	"FreeBSD ELF32",
114290052Sjhb	syscallnames,
115290052Sjhb	nitems(syscallnames),
116290052Sjhb	i386_fetch_args,
117290052Sjhb	i386_fetch_retval
118290052Sjhb};
11931567Ssef
120290052SjhbPROCABI(i386_fbsd);
121171055Sdelphij
122290052Sjhbstatic struct procabi i386_fbsd_aout = {
123290052Sjhb	"FreeBSD a.out",
124290052Sjhb	syscallnames,
125290052Sjhb	nitems(syscallnames),
126290052Sjhb	i386_fetch_args,
127290052Sjhb	i386_fetch_retval
128290052Sjhb};
12931567Ssef
130290052SjhbPROCABI(i386_fbsd_aout);
13131567Ssef
132