Deleted Added
full compact
amd64-linux32.c (158626) amd64-linux32.c (168569)
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[] =
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 $";
34 "$FreeBSD: head/usr.bin/truss/amd64-linux32.c 168569 2007-04-10 04:03:34Z delphij $";
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>
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>
44#include <sys/ptrace.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
45
46#include <machine/reg.h>
47#include <machine/psl.h>
48
49#include <errno.h>
50#include <fcntl.h>
51#include <signal.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <time.h>
56#include <unistd.h>
57
58#include "truss.h"
59#include "syscall.h"
60#include "extern.h"
61
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) {
62static int cpid = -1;
63
64#include "linux_syscalls.h"
65
66static int nsyscalls =
67 sizeof(linux_syscallnames) / sizeof(linux_syscallnames[0]);
68
69/*

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

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

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

185#if DEBUG
186 fprintf(stderr, "0x%x%s",
187 sc
188 ? fsc.args[sc->args[i].offset]
189 : fsc.args[i],
190 i < (fsc.nargs - 1) ? "," : "");
191#endif
192 if (sc && !(sc->args[i].type & OUT)) {
203 fsc.s_args[i] = print_arg(Procfd, &sc->args[i], fsc.args, 0, trussinfo);
193 fsc.s_args[i] = print_arg(&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{
194 }
195 }
196#if DEBUG
197 fprintf(stderr, ")\n");
198#endif
199 }
200
201#if DEBUG

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

249 -110,-111, -40, -36,-112,-113, -39, -11, -87,-122,
250 -116, -66, -6, -6, -6, -6, -6, -37, -38, -9,
251 -6,
252};
253
254long
255i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused)
256{
267 char buf[32];
268 struct reg regs;
269 long retval;
270 int i;
271 int errorp;
272 struct syscall *sc;
273
257 struct reg regs;
258 long retval;
259 int i;
260 int errorp;
261 struct syscall *sc;
262
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");
263 cpid = trussinfo->curthread->tid;
264 if (ptrace(PT_GETREGS, cpid, (caddr_t)&regs, 0) < 0)
265 {
266 fprintf(trussinfo->outfile, "-- CANNOT READ REGISTERS --\n");
287 return (-1);
288 }
267 return (-1);
268 }
269
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
270 retval = regs.r_eax;
271 errorp = !!(regs.r_eflags & PSL_C);
272
273 /*
274 * This code, while simpler than the initial versions I used, could
275 * stand some significant cleaning.
276 */
277

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

289 if (sc->args[i].type & OUT) {
290 /*
291 * If an error occurred, than don't bothe getting the data;
292 * it may not be valid.
293 */
294 if (errorp)
295 asprintf(&temp, "0x%lx", fsc.args[sc->args[i].offset]);
296 else
316 temp = print_arg(Procfd, &sc->args[i], fsc.args, retval, trussinfo);
297 temp = print_arg(&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 ---
298 fsc.s_args[i] = temp;
299 }
300 }
301 }
302
303 /*
304 * It would probably be a good idea to merge the error handling,
305 * but that complicates things considerably.

--- 12 unchanged lines hidden ---