amd64-freebsd32.c revision 288424
1184138Smav/*
2184138Smav * Copyright 1997 Sean Eric Fagan
3184138Smav *
4184138Smav * Redistribution and use in source and binary forms, with or without
5184138Smav * modification, are permitted provided that the following conditions
6184138Smav * are met:
7184138Smav * 1. Redistributions of source code must retain the above copyright
8184138Smav *    notice, this list of conditions and the following disclaimer.
9184138Smav * 2. Redistributions in binary form must reproduce the above copyright
10184138Smav *    notice, this list of conditions and the following disclaimer in the
11184138Smav *    documentation and/or other materials provided with the distribution.
12184138Smav * 3. All advertising materials mentioning features or use of this software
13184138Smav *    must display the following acknowledgement:
14184138Smav *	This product includes software developed by Sean Eric Fagan
15184138Smav * 4. Neither the name of the author may be used to endorse or promote
16184138Smav *    products derived from this software without specific prior written
17184138Smav *    permission.
18184138Smav *
19184138Smav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20184138Smav * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21184138Smav * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22184138Smav * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23184138Smav * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24184138Smav * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25184138Smav * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26184138Smav * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27184138Smav * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28184138Smav * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29184138Smav * SUCH DAMAGE.
30184138Smav */
31184138Smav
32184138Smav#include <sys/cdefs.h>
33184138Smav__FBSDID("$FreeBSD: head/usr.bin/truss/amd64-fbsd32.c 288424 2015-09-30 19:13:32Z jhb $");
34184138Smav
35184138Smav/* FreeBSD/i386-specific system call handling. */
36184138Smav
37184138Smav#include <sys/ptrace.h>
38184138Smav#include <sys/syscall.h>
39184138Smav
40184138Smav#include <machine/reg.h>
41184138Smav#include <machine/psl.h>
42184138Smav
43184138Smav#include <stdio.h>
44184138Smav#include <stdlib.h>
45184138Smav
46184138Smav#include "truss.h"
47184138Smav
48184138Smav#include "freebsd32_syscalls.h"
49184138Smav
50184138Smavstatic int
51184138Smavamd64_fbsd32_fetch_args(struct trussinfo *trussinfo, u_int narg)
52184138Smav{
53184138Smav	struct ptrace_io_desc iorequest;
54184138Smav	struct reg regs;
55184138Smav	struct current_syscall *cs;
56184138Smav	unsigned int args32[narg];
57184138Smav	unsigned long parm_offset;
58184138Smav	lwpid_t tid;
59184138Smav	u_int i;
60184138Smav
61184138Smav	tid = trussinfo->curthread->tid;
62184138Smav	cs = &trussinfo->curthread->cs;
63184138Smav	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
64184138Smav		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
65184138Smav		return (-1);
66184138Smav	}
67184138Smav	parm_offset = regs.r_rsp + sizeof(int);
68184138Smav
69184138Smav	/*
70184138Smav	 * FreeBSD has two special kinds of system call redirections --
71184138Smav	 * SYS_syscall, and SYS___syscall.  The former is the old syscall()
72184138Smav	 * routine, basically; the latter is for quad-aligned arguments.
73184138Smav	 *
74184138Smav	 * The system call argument count and code from ptrace() already
75184138Smav	 * account for these, but we need to skip over the first argument.
76184138Smav	 */
77184138Smav	switch (regs.r_rax) {
78184138Smav	case SYS_syscall:
79184138Smav		parm_offset += sizeof(int);
80184138Smav		break;
81184138Smav	case SYS___syscall:
82184138Smav		parm_offset += sizeof(quad_t);
83184138Smav		break;
84184138Smav	}
85184138Smav
86184138Smav	iorequest.piod_op = PIOD_READ_D;
87184138Smav	iorequest.piod_offs = (void *)parm_offset;
88184138Smav	iorequest.piod_addr = args32;
89184138Smav	iorequest.piod_len = sizeof(args32);
90184138Smav	ptrace(PT_IO, tid, (caddr_t)&iorequest, 0);
91184138Smav	if (iorequest.piod_len == 0) {
92184138Smav		return (-1);
93184138Smav	}
94184138Smav
95184138Smav	for (i = 0; i < narg; i++)
96184138Smav		 cs->args[i] = args32[i];
97184138Smav	return (0);
98184138Smav}
99184138Smav
100184138Smavstatic int
101184138Smavamd64_fbsd32_fetch_retval(struct trussinfo *trussinfo, long *retval,
102184138Smav    int *errorp)
103184138Smav{
104184138Smav	struct reg regs;
105184138Smav	lwpid_t tid;
106184138Smav
107184138Smav	tid = trussinfo->curthread->tid;
108184138Smav	if (ptrace(PT_GETREGS, tid, (caddr_t)&regs, 0) < 0) {
109184138Smav		fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
110184138Smav		return (-1);
111184138Smav	}
112184138Smav
113184138Smav	retval[0] = regs.r_rax & 0xffffffff;
114184138Smav	retval[1] = regs.r_rdx & 0xffffffff;
115184138Smav	*errorp = !!(regs.r_rflags & PSL_C);
116184138Smav	return (0);
117184138Smav}
118184138Smav
119184138Smavstatic struct procabi amd64_fbsd32 = {
120184138Smav	"FreeBSD ELF32",
121184138Smav	freebsd32_syscallnames,
122184138Smav	nitems(freebsd32_syscallnames),
123184138Smav	amd64_fbsd32_fetch_args,
124184138Smav	amd64_fbsd32_fetch_retval
125184138Smav};
126184138Smav
127184138SmavPROCABI(amd64_fbsd32);
128184138Smav
129184138Smavstatic struct procabi amd64_fbsd32_aout = {
130184138Smav	"FreeBSD a.out",
131184138Smav	freebsd32_syscallnames,
132184138Smav	nitems(freebsd32_syscallnames),
133184138Smav	amd64_fbsd32_fetch_args,
134184138Smav	amd64_fbsd32_fetch_retval
135184138Smav};
136184138Smav
137184138SmavPROCABI(amd64_fbsd32_aout);
138184138Smav