1331722Seadler/*
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
32288424Sjhb#include <sys/cdefs.h>
33288424Sjhb__FBSDID("$FreeBSD: stable/11/usr.bin/truss/i386-freebsd.c 312084 2017-01-13 21:30:18Z jhb $");
3432275Scharnier
35288424Sjhb/* 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
43311999Sjhb#include <stdbool.h>
4431567Ssef#include <stdio.h>
45294849Sjhb#include <sysdecode.h>
4631567Ssef
47101282Smdodd#include "truss.h"
4831567Ssef
49288424Sjhbstatic int
50288424Sjhbi386_fetch_args(struct trussinfo *trussinfo, u_int narg)
51240562Szont{
52240005Szont	struct ptrace_io_desc iorequest;
53240005Szont	struct reg regs;
54288424Sjhb	struct current_syscall *cs;
55240562Szont	lwpid_t tid;
56240005Szont	unsigned int parm_offset;
5731567Ssef
58240562Szont	tid = trussinfo->curthread->tid;
59288424Sjhb	cs = &trussinfo->curthread->cs;
60240562Szont	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
61240005Szont		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
62288424Sjhb		return (-1);
63240005Szont	}
64240005Szont	parm_offset = regs.r_esp + sizeof(int);
6531567Ssef
66240005Szont	/*
67288424Sjhb	 * 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.
70288424Sjhb	 *
71288424Sjhb	 * The system call argument count and code from ptrace() already
72288424Sjhb	 * account for these, but we need to skip over the first argument.
73240005Szont	 */
74288424Sjhb	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;
85288424Sjhb	iorequest.piod_addr = cs->args;
86288424Sjhb	iorequest.piod_len = narg * sizeof(unsigned long);
87240562Szont	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
88240005Szont	if (iorequest.piod_len == 0)
89288424Sjhb		return (-1);
90240005Szont
91288424Sjhb	return (0);
9231567Ssef}
9331567Ssef
94288424Sjhbstatic int
95288424Sjhbi386_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
106288424Sjhb	retval[0] = regs.r_eax;
107288424Sjhb	retval[1] = regs.r_edx;
108288424Sjhb	*errorp = !!(regs.r_eflags & PSL_C);
109288424Sjhb	return (0);
110288424Sjhb}
111240005Szont
112289239Sbdrewerystatic struct procabi i386_freebsd = {
113288424Sjhb	"FreeBSD ELF32",
114295056Sjhb	SYSDECODE_ABI_FREEBSD,
115288424Sjhb	i386_fetch_args,
116312084Sjhb	i386_fetch_retval,
117312084Sjhb	STAILQ_HEAD_INITIALIZER(i386_freebsd.extra_syscalls),
118312084Sjhb	{ NULL }
119288424Sjhb};
12031567Ssef
121289239SbdreweryPROCABI(i386_freebsd);
122286938Sjhb
123289239Sbdrewerystatic struct procabi i386_freebsd_aout = {
124288424Sjhb	"FreeBSD a.out",
125295056Sjhb	SYSDECODE_ABI_FREEBSD,
126288424Sjhb	i386_fetch_args,
127312084Sjhb	i386_fetch_retval,
128312084Sjhb	STAILQ_HEAD_INITIALIZER(i386_freebsd_aout.extra_syscalls),
129312084Sjhb	{ NULL }
130288424Sjhb};
131171055Sdelphij
132289239SbdreweryPROCABI(i386_freebsd_aout);
13331567Ssef
134