Deleted Added
sdiff udiff text old ( 158626 ) new ( 168569 )
full compact
1/*
2 * Copryight 1997 Sean Eric Fagan
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.

--- 17 unchanged lines hidden (view full) ---

26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#ifndef lint
33static const char rcsid[] =
34 "$FreeBSD: head/usr.bin/truss/amd64-linux32.c 158626 2006-05-15 21:03:02Z pav $";
35#endif /* not lint */
36
37/*
38 * Linux/i386-specific system call handling. Given how much of this code
39 * is taken from the freebsd equivalent, I can probably put even more of
40 * it in support routines that can be used by any personality support.
41 */
42
43#include <sys/types.h>
44#include <sys/ioctl.h>
45#include <sys/pioctl.h>
46
47#include <machine/reg.h>
48#include <machine/psl.h>
49
50#include <errno.h>
51#include <fcntl.h>
52#include <signal.h>
53#include <stdio.h>
54#include <stdlib.h>
55#include <string.h>
56#include <time.h>
57#include <unistd.h>
58
59#include "truss.h"
60#include "syscall.h"
61#include "extern.h"
62
63static int fd = -1;
64static int cpid = -1;
65
66#include "linux_syscalls.h"
67
68static int nsyscalls =
69 sizeof(linux_syscallnames) / sizeof(linux_syscallnames[0]);
70
71/*

--- 31 unchanged lines hidden (view full) ---

103 * Called when a process has entered a system call. nargs is the
104 * number of words, not number of arguments (a necessary distinction
105 * in some cases). Note that if the STOPEVENT() code in i386/i386/trap.c
106 * is ever changed these functions need to keep up.
107 */
108
109void
110i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) {
111 char buf[32];
112 struct reg regs;
113 int syscall_num;
114 int i;
115 struct syscall *sc;
116
117 if (fd == -1 || trussinfo->pid != cpid) {
118 sprintf(buf, "/proc/%d/regs", trussinfo->pid);
119 fd = open(buf, O_RDWR);
120 if (fd == -1) {
121 fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n");
122 return;
123 }
124 cpid = trussinfo->pid;
125 }
126
127 clear_fsc();
128 lseek(fd, 0L, 0);
129 if (read(fd, &regs, sizeof(regs)) != sizeof(regs)) {
130 fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
131 return;
132 }
133 syscall_num = regs.r_eax;
134
135 fsc.number = syscall_num;
136 fsc.name =
137 (syscall_num < 0 || syscall_num > nsyscalls) ? NULL : linux_syscallnames[syscall_num];
138 if (!fsc.name) {
139 fprintf(trussinfo->outfile, "-- UNKNOWN SYSCALL %d --\n", syscall_num);
140 }
141
142 if (fsc.name && (trussinfo->flags & FOLLOWFORKS)
143 && ((!strcmp(fsc.name, "linux_fork")
144 || !strcmp(fsc.name, "linux_vfork"))))
145 {
146 trussinfo->in_fork = 1;
147 }
148
149 if (nargs == 0)
150 return;
151
152 /*
153 * Linux passes syscall arguments in registers, not
154 * on the stack. Fortunately, we've got access to the

--- 40 unchanged lines hidden (view full) ---

195#if DEBUG
196 fprintf(stderr, "0x%x%s",
197 sc
198 ? fsc.args[sc->args[i].offset]
199 : fsc.args[i],
200 i < (fsc.nargs - 1) ? "," : "");
201#endif
202 if (sc && !(sc->args[i].type & OUT)) {
203 fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo);
204 }
205 }
206#if DEBUG
207 fprintf(stderr, ")\n");
208#endif
209 }
210
211#if DEBUG

--- 47 unchanged lines hidden (view full) ---

259 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
260 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
261 -6,
262};
263
264long
265i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
266{
267 char buf[32];
268 struct reg regs;
269 long retval;
270 int i;
271 int errorp;
272 struct syscall *sc;
273
274 if (fd == -1 || trussinfo->pid != cpid) {
275 sprintf(buf, "/proc/%d/regs", trussinfo->pid);
276 fd = open(buf, O_RDONLY);
277 if (fd == -1) {
278 fprintf(trussinfo->outfile, "-- CANNOT OPEN REGISTERS --\n");
279 return (-1);
280 }
281 cpid = trussinfo->pid;
282 }
283
284 lseek(fd, 0L, 0);
285 if (read(fd, &regs, sizeof(regs)) != sizeof(regs)) {
286 fprintf(trussinfo->outfile, "\n");
287 return (-1);
288 }
289 retval = regs.r_eax;
290 errorp = !!(regs.r_eflags & PSL_C);
291
292 /*
293 * This code, while simpler than the initial versions I used, could
294 * stand some significant cleaning.
295 */
296

--- 11 unchanged lines hidden (view full) ---

308 if (sc->args[i].type & OUT) {
309 /*
310 * If an error occurred, than don't bothe getting the data;
311 * it may not be valid.
312 */
313 if (errorp)
314 asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
315 else
316 temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo);
317 fsc.s_args[i] = temp;
318 }
319 }
320 }
321
322 /*
323 * It would probably be a good idea to merge the error handling,
324 * but that complicates things considerably.

--- 12 unchanged lines hidden ---