1 /*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $Id$
34 */
35
36 #include "defs.h"
37
38 #include <signal.h>
39 #include <time.h>
40 #include <errno.h>
41 #ifndef HAVE_ANDROID_OS
42 #include <sys/user.h>
43 #endif
44 #include <sys/syscall.h>
45 #include <sys/param.h>
46
47 #ifdef HAVE_SYS_REG_H
48 #include <sys/reg.h>
49 #ifndef PTRACE_PEEKUSR
50 # define PTRACE_PEEKUSR PTRACE_PEEKUSER
51 #endif
52 #elif defined(HAVE_LINUX_PTRACE_H)
53 #undef PTRACE_SYSCALL
54 # ifdef HAVE_STRUCT_IA64_FPREG
55 # define ia64_fpreg XXX_ia64_fpreg
56 # endif
57 # ifdef HAVE_STRUCT_PT_ALL_USER_REGS
58 # define pt_all_user_regs XXX_pt_all_user_regs
59 # endif
60 #include <linux/ptrace.h>
61 # undef ia64_fpreg
62 # undef pt_all_user_regs
63 #endif
64
65 #if defined (LINUX) && defined (SPARC64)
66 # undef PTRACE_GETREGS
67 # define PTRACE_GETREGS PTRACE_GETREGS64
68 # undef PTRACE_SETREGS
69 # define PTRACE_SETREGS PTRACE_SETREGS64
70 #endif /* LINUX && SPARC64 */
71
72 #if defined(LINUX) && defined(IA64)
73 # include <asm/ptrace_offsets.h>
74 # include <asm/rse.h>
75 #endif
76
77 #define NR_SYSCALL_BASE 0
78 #ifdef LINUX
79 #ifndef ERESTARTSYS
80 #define ERESTARTSYS 512
81 #endif
82 #ifndef ERESTARTNOINTR
83 #define ERESTARTNOINTR 513
84 #endif
85 #ifndef ERESTARTNOHAND
86 #define ERESTARTNOHAND 514 /* restart if no handler.. */
87 #endif
88 #ifndef ENOIOCTLCMD
89 #define ENOIOCTLCMD 515 /* No ioctl command */
90 #endif
91 #ifndef ERESTART_RESTARTBLOCK
92 #define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
93 #endif
94 #ifndef NSIG
95 #define NSIG 32
96 #endif
97 #ifdef ARM
98 #undef NSIG
99 #define NSIG 32
100 #undef NR_SYSCALL_BASE
101 #define NR_SYSCALL_BASE __NR_SYSCALL_BASE
102 #endif
103 #endif /* LINUX */
104
105 #include "syscall.h"
106
107 /* Define these shorthand notations to simplify the syscallent files. */
108 #define TD TRACE_DESC
109 #define TF TRACE_FILE
110 #define TI TRACE_IPC
111 #define TN TRACE_NETWORK
112 #define TP TRACE_PROCESS
113 #define TS TRACE_SIGNAL
114 #define NF SYSCALL_NEVER_FAILS
115
116 static const struct sysent sysent0[] = {
117 #include "syscallent.h"
118 };
119 static const int nsyscalls0 = sizeof sysent0 / sizeof sysent0[0];
120 int qual_flags0[MAX_QUALS];
121
122 #if SUPPORTED_PERSONALITIES >= 2
123 static const struct sysent sysent1[] = {
124 #include "syscallent1.h"
125 };
126 static const int nsyscalls1 = sizeof sysent1 / sizeof sysent1[0];
127 int qual_flags1[MAX_QUALS];
128 #endif /* SUPPORTED_PERSONALITIES >= 2 */
129
130 #if SUPPORTED_PERSONALITIES >= 3
131 static const struct sysent sysent2[] = {
132 #include "syscallent2.h"
133 };
134 static const int nsyscalls2 = sizeof sysent2 / sizeof sysent2[0];
135 int qual_flags2[MAX_QUALS];
136 #endif /* SUPPORTED_PERSONALITIES >= 3 */
137
138 const struct sysent *sysent;
139 int *qual_flags;
140 int nsyscalls;
141
142 /* Now undef them since short defines cause wicked namespace pollution. */
143 #undef TD
144 #undef TF
145 #undef TI
146 #undef TN
147 #undef TP
148 #undef TS
149 #undef NF
150
151 static const char *const errnoent0[] = {
152 #include "errnoent.h"
153 };
154 static const int nerrnos0 = sizeof errnoent0 / sizeof errnoent0[0];
155
156 #if SUPPORTED_PERSONALITIES >= 2
157 static const char *const errnoent1[] = {
158 #include "errnoent1.h"
159 };
160 static const int nerrnos1 = sizeof errnoent1 / sizeof errnoent1[0];
161 #endif /* SUPPORTED_PERSONALITIES >= 2 */
162
163 #if SUPPORTED_PERSONALITIES >= 3
164 static const char *const errnoent2[] = {
165 #include "errnoent2.h"
166 };
167 static const int nerrnos2 = sizeof errnoent2 / sizeof errnoent2[0];
168 #endif /* SUPPORTED_PERSONALITIES >= 3 */
169
170 const char *const *errnoent;
171 int nerrnos;
172
173 int current_personality;
174
175 #ifndef PERSONALITY0_WORDSIZE
176 # define PERSONALITY0_WORDSIZE sizeof(long)
177 #endif
178 const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
179 PERSONALITY0_WORDSIZE,
180 #if SUPPORTED_PERSONALITIES > 1
181 PERSONALITY1_WORDSIZE,
182 #endif
183 #if SUPPORTED_PERSONALITIES > 2
184 PERSONALITY2_WORDSIZE,
185 #endif
186 };;
187
188 int
set_personality(int personality)189 set_personality(int personality)
190 {
191 switch (personality) {
192 case 0:
193 errnoent = errnoent0;
194 nerrnos = nerrnos0;
195 sysent = sysent0;
196 nsyscalls = nsyscalls0;
197 ioctlent = ioctlent0;
198 nioctlents = nioctlents0;
199 signalent = signalent0;
200 nsignals = nsignals0;
201 qual_flags = qual_flags0;
202 break;
203
204 #if SUPPORTED_PERSONALITIES >= 2
205 case 1:
206 errnoent = errnoent1;
207 nerrnos = nerrnos1;
208 sysent = sysent1;
209 nsyscalls = nsyscalls1;
210 ioctlent = ioctlent1;
211 nioctlents = nioctlents1;
212 signalent = signalent1;
213 nsignals = nsignals1;
214 qual_flags = qual_flags1;
215 break;
216 #endif /* SUPPORTED_PERSONALITIES >= 2 */
217
218 #if SUPPORTED_PERSONALITIES >= 3
219 case 2:
220 errnoent = errnoent2;
221 nerrnos = nerrnos2;
222 sysent = sysent2;
223 nsyscalls = nsyscalls2;
224 ioctlent = ioctlent2;
225 nioctlents = nioctlents2;
226 signalent = signalent2;
227 nsignals = nsignals2;
228 qual_flags = qual_flags2;
229 break;
230 #endif /* SUPPORTED_PERSONALITIES >= 3 */
231
232 default:
233 return -1;
234 }
235
236 current_personality = personality;
237 return 0;
238 }
239
240
241 static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
242
243 static const struct qual_options {
244 int bitflag;
245 const char *option_name;
246 int (*qualify)(const char *, int, int);
247 const char *argument_name;
248 } qual_options[] = {
249 { QUAL_TRACE, "trace", qual_syscall, "system call" },
250 { QUAL_TRACE, "t", qual_syscall, "system call" },
251 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
252 { QUAL_ABBREV, "a", qual_syscall, "system call" },
253 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
254 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
255 { QUAL_RAW, "raw", qual_syscall, "system call" },
256 { QUAL_RAW, "x", qual_syscall, "system call" },
257 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
258 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
259 { QUAL_SIGNAL, "s", qual_signal, "signal" },
260 { QUAL_FAULT, "fault", qual_fault, "fault" },
261 { QUAL_FAULT, "faults", qual_fault, "fault" },
262 { QUAL_FAULT, "m", qual_fault, "fault" },
263 { QUAL_READ, "read", qual_desc, "descriptor" },
264 { QUAL_READ, "reads", qual_desc, "descriptor" },
265 { QUAL_READ, "r", qual_desc, "descriptor" },
266 { QUAL_WRITE, "write", qual_desc, "descriptor" },
267 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
268 { QUAL_WRITE, "w", qual_desc, "descriptor" },
269 { 0, NULL, NULL, NULL },
270 };
271
272 static void
qualify_one(int n,int bitflag,int not,int pers)273 qualify_one(int n, int bitflag, int not, int pers)
274 {
275 if (pers == 0 || pers < 0) {
276 if (not)
277 qual_flags0[n] &= ~bitflag;
278 else
279 qual_flags0[n] |= bitflag;
280 }
281
282 #if SUPPORTED_PERSONALITIES >= 2
283 if (pers == 1 || pers < 0) {
284 if (not)
285 qual_flags1[n] &= ~bitflag;
286 else
287 qual_flags1[n] |= bitflag;
288 }
289 #endif /* SUPPORTED_PERSONALITIES >= 2 */
290
291 #if SUPPORTED_PERSONALITIES >= 3
292 if (pers == 2 || pers < 0) {
293 if (not)
294 qual_flags2[n] &= ~bitflag;
295 else
296 qual_flags2[n] |= bitflag;
297 }
298 #endif /* SUPPORTED_PERSONALITIES >= 3 */
299 }
300
301 static int
qual_syscall(const char * s,int bitflag,int not)302 qual_syscall(const char *s, int bitflag, int not)
303 {
304 int i;
305 int rc = -1;
306
307 if (isdigit((unsigned char)*s)) {
308 int i = atoi(s);
309 if (i < 0 || i >= MAX_QUALS)
310 return -1;
311 qualify_one(i, bitflag, not, -1);
312 return 0;
313 }
314 for (i = 0; i < nsyscalls0; i++)
315 if (strcmp(s, sysent0[i].sys_name) == 0) {
316 qualify_one(i, bitflag, not, 0);
317 rc = 0;
318 }
319
320 #if SUPPORTED_PERSONALITIES >= 2
321 for (i = 0; i < nsyscalls1; i++)
322 if (strcmp(s, sysent1[i].sys_name) == 0) {
323 qualify_one(i, bitflag, not, 1);
324 rc = 0;
325 }
326 #endif /* SUPPORTED_PERSONALITIES >= 2 */
327
328 #if SUPPORTED_PERSONALITIES >= 3
329 for (i = 0; i < nsyscalls2; i++)
330 if (strcmp(s, sysent2[i].sys_name) == 0) {
331 qualify_one(i, bitflag, not, 2);
332 rc = 0;
333 }
334 #endif /* SUPPORTED_PERSONALITIES >= 3 */
335
336 return rc;
337 }
338
339 static int
qual_signal(const char * s,int bitflag,int not)340 qual_signal(const char *s, int bitflag, int not)
341 {
342 int i;
343 char buf[32];
344
345 if (isdigit((unsigned char)*s)) {
346 int signo = atoi(s);
347 if (signo < 0 || signo >= MAX_QUALS)
348 return -1;
349 qualify_one(signo, bitflag, not, -1);
350 return 0;
351 }
352 if (strlen(s) >= sizeof buf)
353 return -1;
354 strcpy(buf, s);
355 s = buf;
356 if (strncasecmp(s, "SIG", 3) == 0)
357 s += 3;
358 for (i = 0; i <= NSIG; i++)
359 if (strcasecmp(s, signame(i) + 3) == 0) {
360 qualify_one(i, bitflag, not, -1);
361 return 0;
362 }
363 return -1;
364 }
365
366 static int
qual_fault(const char * s,int bitflag,int not)367 qual_fault(const char *s, int bitflag, int not)
368 {
369 return -1;
370 }
371
372 static int
qual_desc(const char * s,int bitflag,int not)373 qual_desc(const char *s, int bitflag, int not)
374 {
375 if (isdigit((unsigned char)*s)) {
376 int desc = atoi(s);
377 if (desc < 0 || desc >= MAX_QUALS)
378 return -1;
379 qualify_one(desc, bitflag, not, -1);
380 return 0;
381 }
382 return -1;
383 }
384
385 static int
lookup_class(const char * s)386 lookup_class(const char *s)
387 {
388 if (strcmp(s, "file") == 0)
389 return TRACE_FILE;
390 if (strcmp(s, "ipc") == 0)
391 return TRACE_IPC;
392 if (strcmp(s, "network") == 0)
393 return TRACE_NETWORK;
394 if (strcmp(s, "process") == 0)
395 return TRACE_PROCESS;
396 if (strcmp(s, "signal") == 0)
397 return TRACE_SIGNAL;
398 if (strcmp(s, "desc") == 0)
399 return TRACE_DESC;
400 return -1;
401 }
402
403 void
qualify(const char * s)404 qualify(const char *s)
405 {
406 const struct qual_options *opt;
407 int not;
408 char *copy;
409 const char *p;
410 int i, n;
411
412 opt = &qual_options[0];
413 for (i = 0; (p = qual_options[i].option_name); i++) {
414 n = strlen(p);
415 if (strncmp(s, p, n) == 0 && s[n] == '=') {
416 opt = &qual_options[i];
417 s += n + 1;
418 break;
419 }
420 }
421 not = 0;
422 if (*s == '!') {
423 not = 1;
424 s++;
425 }
426 if (strcmp(s, "none") == 0) {
427 not = 1 - not;
428 s = "all";
429 }
430 if (strcmp(s, "all") == 0) {
431 for (i = 0; i < MAX_QUALS; i++) {
432 qualify_one(i, opt->bitflag, not, -1);
433 }
434 return;
435 }
436 for (i = 0; i < MAX_QUALS; i++) {
437 qualify_one(i, opt->bitflag, !not, -1);
438 }
439 if (!(copy = strdup(s))) {
440 fprintf(stderr, "out of memory\n");
441 exit(1);
442 }
443 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
444 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
445 for (i = 0; i < nsyscalls0; i++)
446 if (sysent0[i].sys_flags & n)
447 qualify_one(i, opt->bitflag, not, 0);
448
449 #if SUPPORTED_PERSONALITIES >= 2
450 for (i = 0; i < nsyscalls1; i++)
451 if (sysent1[i].sys_flags & n)
452 qualify_one(i, opt->bitflag, not, 1);
453 #endif /* SUPPORTED_PERSONALITIES >= 2 */
454
455 #if SUPPORTED_PERSONALITIES >= 3
456 for (i = 0; i < nsyscalls2; i++)
457 if (sysent2[i].sys_flags & n)
458 qualify_one(i, opt->bitflag, not, 2);
459 #endif /* SUPPORTED_PERSONALITIES >= 3 */
460
461 continue;
462 }
463 if (opt->qualify(p, opt->bitflag, not)) {
464 fprintf(stderr, "strace: invalid %s `%s'\n",
465 opt->argument_name, p);
466 exit(1);
467 }
468 }
469 free(copy);
470 return;
471 }
472
473 static void
dumpio(struct tcb * tcp)474 dumpio(struct tcb *tcp)
475 {
476 if (syserror(tcp))
477 return;
478 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS)
479 return;
480 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
481 return;
482 if (sysent[tcp->scno].sys_func == printargs)
483 return;
484 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) {
485 if (sysent[tcp->scno].sys_func == sys_read ||
486 sysent[tcp->scno].sys_func == sys_pread ||
487 sysent[tcp->scno].sys_func == sys_pread64 ||
488 sysent[tcp->scno].sys_func == sys_recv ||
489 sysent[tcp->scno].sys_func == sys_recvfrom)
490 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval);
491 else if (sysent[tcp->scno].sys_func == sys_readv)
492 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
493 return;
494 }
495 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) {
496 if (sysent[tcp->scno].sys_func == sys_write ||
497 sysent[tcp->scno].sys_func == sys_pwrite ||
498 sysent[tcp->scno].sys_func == sys_pwrite64 ||
499 sysent[tcp->scno].sys_func == sys_send ||
500 sysent[tcp->scno].sys_func == sys_sendto)
501 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]);
502 else if (sysent[tcp->scno].sys_func == sys_writev)
503 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]);
504 return;
505 }
506 }
507
508 #ifndef FREEBSD
509 enum subcall_style { shift_style, deref_style, mask_style, door_style };
510 #else /* FREEBSD */
511 enum subcall_style { shift_style, deref_style, mask_style, door_style, table_style };
512
513 struct subcall {
514 int call;
515 int nsubcalls;
516 int subcalls[5];
517 };
518
519 static const struct subcall subcalls_table[] = {
520 { SYS_shmsys, 5, { SYS_shmat, SYS_shmctl, SYS_shmdt, SYS_shmget, SYS_shmctl } },
521 #ifdef SYS_semconfig
522 { SYS_semsys, 4, { SYS___semctl, SYS_semget, SYS_semop, SYS_semconfig } },
523 #else
524 { SYS_semsys, 3, { SYS___semctl, SYS_semget, SYS_semop } },
525 #endif
526 { SYS_msgsys, 4, { SYS_msgctl, SYS_msgget, SYS_msgsnd, SYS_msgrcv } },
527 };
528 #endif /* FREEBSD */
529
530 #if !(defined(LINUX) && ( defined(ALPHA) || defined(MIPS) || defined(__ARM_EABI__) ))
531
532 static void
decode_subcall(tcp,subcall,nsubcalls,style)533 decode_subcall(tcp, subcall, nsubcalls, style)
534 struct tcb *tcp;
535 int subcall;
536 int nsubcalls;
537 enum subcall_style style;
538 {
539 unsigned long addr, mask;
540 int i;
541 int size = personality_wordsize[current_personality];
542
543 switch (style) {
544 case shift_style:
545 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
546 return;
547 tcp->scno = subcall + tcp->u_arg[0];
548 if (sysent[tcp->scno].nargs != -1)
549 tcp->u_nargs = sysent[tcp->scno].nargs;
550 else
551 tcp->u_nargs--;
552 for (i = 0; i < tcp->u_nargs; i++)
553 tcp->u_arg[i] = tcp->u_arg[i + 1];
554 break;
555 case deref_style:
556 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= nsubcalls)
557 return;
558 tcp->scno = subcall + tcp->u_arg[0];
559 addr = tcp->u_arg[1];
560 for (i = 0; i < sysent[tcp->scno].nargs; i++) {
561 if (size == sizeof(int)) {
562 unsigned int arg;
563 if (umove(tcp, addr, &arg) < 0)
564 arg = 0;
565 tcp->u_arg[i] = arg;
566 }
567 else if (size == sizeof(long)) {
568 unsigned long arg;
569 if (umove(tcp, addr, &arg) < 0)
570 arg = 0;
571 tcp->u_arg[i] = arg;
572 }
573 else
574 abort();
575 addr += size;
576 }
577 tcp->u_nargs = sysent[tcp->scno].nargs;
578 break;
579 case mask_style:
580 mask = (tcp->u_arg[0] >> 8) & 0xff;
581 for (i = 0; mask; i++)
582 mask >>= 1;
583 if (i >= nsubcalls)
584 return;
585 tcp->u_arg[0] &= 0xff;
586 tcp->scno = subcall + i;
587 if (sysent[tcp->scno].nargs != -1)
588 tcp->u_nargs = sysent[tcp->scno].nargs;
589 break;
590 case door_style:
591 /*
592 * Oh, yuck. The call code is the *sixth* argument.
593 * (don't you mean the *last* argument? - JH)
594 */
595 if (tcp->u_arg[5] < 0 || tcp->u_arg[5] >= nsubcalls)
596 return;
597 tcp->scno = subcall + tcp->u_arg[5];
598 if (sysent[tcp->scno].nargs != -1)
599 tcp->u_nargs = sysent[tcp->scno].nargs;
600 else
601 tcp->u_nargs--;
602 break;
603 #ifdef FREEBSD
604 case table_style:
605 for (i = 0; i < sizeof(subcalls_table) / sizeof(struct subcall); i++)
606 if (subcalls_table[i].call == tcp->scno) break;
607 if (i < sizeof(subcalls_table) / sizeof(struct subcall) &&
608 tcp->u_arg[0] >= 0 && tcp->u_arg[0] < subcalls_table[i].nsubcalls) {
609 tcp->scno = subcalls_table[i].subcalls[tcp->u_arg[0]];
610 for (i = 0; i < tcp->u_nargs; i++)
611 tcp->u_arg[i] = tcp->u_arg[i + 1];
612 }
613 break;
614 #endif /* FREEBSD */
615 }
616 }
617 #endif
618
619 struct tcb *tcp_last = NULL;
620
621 static int
internal_syscall(struct tcb * tcp)622 internal_syscall(struct tcb *tcp)
623 {
624 /*
625 * We must always trace a few critical system calls in order to
626 * correctly support following forks in the presence of tracing
627 * qualifiers.
628 */
629 int (*func)();
630
631 if (tcp->scno < 0 || tcp->scno >= nsyscalls)
632 return 0;
633
634 func = sysent[tcp->scno].sys_func;
635
636 if (sys_exit == func)
637 return internal_exit(tcp);
638
639 if ( sys_fork == func
640 #if defined(FREEBSD) || defined(LINUX) || defined(SUNOS4)
641 || sys_vfork == func
642 #endif
643 #ifdef LINUX
644 || sys_clone == func
645 #endif
646 #if UNIXWARE > 2
647 || sys_rfork == func
648 #endif
649 )
650 return internal_fork(tcp);
651
652 if ( sys_execve == func
653 #if defined(SPARC) || defined(SPARC64) || defined(SUNOS4)
654 || sys_execv == func
655 #endif
656 #if UNIXWARE > 2
657 || sys_rexecve == func
658 #endif
659 )
660 return internal_exec(tcp);
661
662 if ( sys_waitpid == func
663 || sys_wait4 == func
664 #if defined(SVR4) || defined(FREEBSD) || defined(SUNOS4)
665 || sys_wait == func
666 #endif
667 #ifdef ALPHA
668 || sys_osf_wait4 == func
669 #endif
670 )
671 return internal_wait(tcp, 2);
672
673 #if defined(LINUX) || defined(SVR4)
674 if (sys_waitid == func)
675 return internal_wait(tcp, 3);
676 #endif
677
678 return 0;
679 }
680
681
682 #ifdef LINUX
683 #if defined (I386)
684 static long eax;
685 #elif defined (IA64)
686 long r8, r10, psr;
687 long ia32 = 0;
688 #elif defined (POWERPC)
689 static long result,flags;
690 #elif defined (M68K)
691 static long d0;
692 #elif defined(BFIN)
693 static long r0;
694 #elif defined (ARM)
695 static struct pt_regs regs;
696 #elif defined (ALPHA)
697 static long r0;
698 static long a3;
699 #elif defined(AVR32)
700 static struct pt_regs regs;
701 #elif defined (SPARC) || defined (SPARC64)
702 static struct pt_regs regs;
703 static unsigned long trap;
704 #elif defined(LINUX_MIPSN32)
705 static long long a3;
706 static long long r2;
707 #elif defined(MIPS)
708 static long a3;
709 static long r2;
710 #elif defined(S390) || defined(S390X)
711 static long gpr2;
712 static long pc;
713 static long syscall_mode;
714 #elif defined(HPPA)
715 static long r28;
716 #elif defined(SH)
717 static long r0;
718 #elif defined(SH64)
719 static long r9;
720 #elif defined(X86_64)
721 static long rax;
722 #elif defined(CRISV10) || defined(CRISV32)
723 static long r10;
724 #elif defined(MICROBLAZE)
725 static long r3;
726 #endif
727 #endif /* LINUX */
728 #ifdef FREEBSD
729 struct reg regs;
730 #endif /* FREEBSD */
731
732 int
get_scno(struct tcb * tcp)733 get_scno(struct tcb *tcp)
734 {
735 long scno = 0;
736
737 #ifdef LINUX
738 # if defined(S390) || defined(S390X)
739 if (tcp->flags & TCB_WAITEXECVE) {
740 /*
741 * When the execve system call completes successfully, the
742 * new process still has -ENOSYS (old style) or __NR_execve
743 * (new style) in gpr2. We cannot recover the scno again
744 * by disassembly, because the image that executed the
745 * syscall is gone now. Fortunately, we don't want it. We
746 * leave the flag set so that syscall_fixup can fake the
747 * result.
748 */
749 if (tcp->flags & TCB_INSYSCALL)
750 return 1;
751 /*
752 * This is the SIGTRAP after execve. We cannot try to read
753 * the system call here either.
754 */
755 tcp->flags &= ~TCB_WAITEXECVE;
756 return 0;
757 }
758
759 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
760 return -1;
761
762 if (syscall_mode != -ENOSYS) {
763 /*
764 * Since kernel version 2.5.44 the scno gets passed in gpr2.
765 */
766 scno = syscall_mode;
767 } else {
768 /*
769 * Old style of "passing" the scno via the SVC instruction.
770 */
771
772 long opcode, offset_reg, tmp;
773 void * svc_addr;
774 int gpr_offset[16] = {PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3,
775 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7,
776 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11,
777 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15};
778
779 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
780 return -1;
781 errno = 0;
782 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
783 if (errno) {
784 perror("peektext(pc-oneword)");
785 return -1;
786 }
787
788 /*
789 * We have to check if the SVC got executed directly or via an
790 * EXECUTE instruction. In case of EXECUTE it is necessary to do
791 * instruction decoding to derive the system call number.
792 * Unfortunately the opcode sizes of EXECUTE and SVC are differently,
793 * so that this doesn't work if a SVC opcode is part of an EXECUTE
794 * opcode. Since there is no way to find out the opcode size this
795 * is the best we can do...
796 */
797
798 if ((opcode & 0xff00) == 0x0a00) {
799 /* SVC opcode */
800 scno = opcode & 0xff;
801 }
802 else {
803 /* SVC got executed by EXECUTE instruction */
804
805 /*
806 * Do instruction decoding of EXECUTE. If you really want to
807 * understand this, read the Principles of Operations.
808 */
809 svc_addr = (void *) (opcode & 0xfff);
810
811 tmp = 0;
812 offset_reg = (opcode & 0x000f0000) >> 16;
813 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
814 return -1;
815 svc_addr += tmp;
816
817 tmp = 0;
818 offset_reg = (opcode & 0x0000f000) >> 12;
819 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
820 return -1;
821 svc_addr += tmp;
822
823 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
824 if (errno)
825 return -1;
826 # if defined(S390X)
827 scno >>= 48;
828 # else
829 scno >>= 16;
830 # endif
831 tmp = 0;
832 offset_reg = (opcode & 0x00f00000) >> 20;
833 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
834 return -1;
835
836 scno = (scno | tmp) & 0xff;
837 }
838 }
839 # elif defined (POWERPC)
840 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
841 return -1;
842 if (!(tcp->flags & TCB_INSYSCALL)) {
843 /* Check if we return from execve. */
844 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
845 tcp->flags &= ~TCB_WAITEXECVE;
846 return 0;
847 }
848 }
849
850 # ifdef POWERPC64
851 if (!(tcp->flags & TCB_INSYSCALL)) {
852 static int currpers = -1;
853 long val;
854 int pid = tcp->pid;
855
856 /* Check for 64/32 bit mode. */
857 if (upeek(tcp, sizeof (unsigned long)*PT_MSR, &val) < 0)
858 return -1;
859 /* SF is bit 0 of MSR */
860 if (val < 0)
861 currpers = 0;
862 else
863 currpers = 1;
864 if (currpers != current_personality) {
865 static const char *const names[] = {"64 bit", "32 bit"};
866 set_personality(currpers);
867 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
868 pid, names[current_personality]);
869 }
870 }
871 # endif
872 # elif defined(AVR32)
873 /*
874 * Read complete register set in one go.
875 */
876 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0)
877 return -1;
878
879 /*
880 * We only need to grab the syscall number on syscall entry.
881 */
882 if (!(tcp->flags & TCB_INSYSCALL)) {
883 scno = regs.r8;
884
885 /* Check if we return from execve. */
886 if (tcp->flags & TCB_WAITEXECVE) {
887 tcp->flags &= ~TCB_WAITEXECVE;
888 return 0;
889 }
890 }
891 # elif defined(BFIN)
892 if (upeek(tcp, PT_ORIG_P0, &scno))
893 return -1;
894 # elif defined (I386)
895 if (upeek(tcp, 4*ORIG_EAX, &scno) < 0)
896 return -1;
897 # elif defined (X86_64)
898 if (upeek(tcp, 8*ORIG_RAX, &scno) < 0)
899 return -1;
900
901 if (!(tcp->flags & TCB_INSYSCALL)) {
902 static int currpers = -1;
903 long val;
904 int pid = tcp->pid;
905
906 /* Check CS register value. On x86-64 linux it is:
907 * 0x33 for long mode (64 bit)
908 * 0x23 for compatibility mode (32 bit)
909 * It takes only one ptrace and thus doesn't need
910 * to be cached.
911 */
912 if (upeek(tcp, 8*CS, &val) < 0)
913 return -1;
914 switch (val) {
915 case 0x23: currpers = 1; break;
916 case 0x33: currpers = 0; break;
917 default:
918 fprintf(stderr, "Unknown value CS=0x%02X while "
919 "detecting personality of process "
920 "PID=%d\n", (int)val, pid);
921 currpers = current_personality;
922 break;
923 }
924 # if 0
925 /* This version analyzes the opcode of a syscall instruction.
926 * (int 0x80 on i386 vs. syscall on x86-64)
927 * It works, but is too complicated.
928 */
929 unsigned long val, rip, i;
930
931 if (upeek(tcp, 8*RIP, &rip) < 0)
932 perror("upeek(RIP)");
933
934 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
935 rip -= 2;
936 errno = 0;
937
938 call = ptrace(PTRACE_PEEKTEXT, pid, (char *)rip, (char *)0);
939 if (errno)
940 fprintf(stderr, "ptrace_peektext failed: %s\n",
941 strerror(errno));
942 switch (call & 0xffff) {
943 /* x86-64: syscall = 0x0f 0x05 */
944 case 0x050f: currpers = 0; break;
945 /* i386: int 0x80 = 0xcd 0x80 */
946 case 0x80cd: currpers = 1; break;
947 default:
948 currpers = current_personality;
949 fprintf(stderr,
950 "Unknown syscall opcode (0x%04X) while "
951 "detecting personality of process "
952 "PID=%d\n", (int)call, pid);
953 break;
954 }
955 # endif
956 if (currpers != current_personality) {
957 static const char *const names[] = {"64 bit", "32 bit"};
958 set_personality(currpers);
959 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
960 pid, names[current_personality]);
961 }
962 }
963 # elif defined(IA64)
964 # define IA64_PSR_IS ((long)1 << 34)
965 if (upeek (tcp, PT_CR_IPSR, &psr) >= 0)
966 ia32 = (psr & IA64_PSR_IS) != 0;
967 if (!(tcp->flags & TCB_INSYSCALL)) {
968 if (ia32) {
969 if (upeek(tcp, PT_R1, &scno) < 0) /* orig eax */
970 return -1;
971 } else {
972 if (upeek (tcp, PT_R15, &scno) < 0)
973 return -1;
974 }
975 /* Check if we return from execve. */
976 if (tcp->flags & TCB_WAITEXECVE) {
977 tcp->flags &= ~TCB_WAITEXECVE;
978 return 0;
979 }
980 } else {
981 /* syscall in progress */
982 if (upeek (tcp, PT_R8, &r8) < 0)
983 return -1;
984 if (upeek (tcp, PT_R10, &r10) < 0)
985 return -1;
986 }
987 # elif defined (ARM)
988 /*
989 * Read complete register set in one go.
990 */
991 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1)
992 return -1;
993
994 /*
995 * We only need to grab the syscall number on syscall entry.
996 */
997 if (regs.ARM_ip == 0) {
998 if (!(tcp->flags & TCB_INSYSCALL)) {
999 /* Check if we return from execve. */
1000 if (tcp->flags & TCB_WAITEXECVE) {
1001 tcp->flags &= ~TCB_WAITEXECVE;
1002 return 0;
1003 }
1004 }
1005
1006 /*
1007 * Note: we only deal with only 32-bit CPUs here.
1008 */
1009 if (regs.ARM_cpsr & 0x20) {
1010 /*
1011 * Get the Thumb-mode system call number
1012 */
1013 scno = regs.ARM_r7;
1014 } else {
1015 /*
1016 * Get the ARM-mode system call number
1017 */
1018 errno = 0;
1019 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL);
1020 if (errno)
1021 return -1;
1022
1023 if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1024 tcp->flags &= ~TCB_WAITEXECVE;
1025 return 0;
1026 }
1027
1028 /* Handle the EABI syscall convention. We do not
1029 bother converting structures between the two
1030 ABIs, but basic functionality should work even
1031 if strace and the traced program have different
1032 ABIs. */
1033 if (scno == 0xef000000) {
1034 scno = regs.ARM_r7;
1035 } else {
1036 if ((scno & 0x0ff00000) != 0x0f900000) {
1037 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1038 scno);
1039 return -1;
1040 }
1041
1042 /*
1043 * Fixup the syscall number
1044 */
1045 scno &= 0x000fffff;
1046 }
1047 }
1048 if (scno & 0x0f0000) {
1049 /*
1050 * Handle ARM specific syscall
1051 */
1052 set_personality(1);
1053 scno &= 0x0000ffff;
1054 } else
1055 set_personality(0);
1056
1057 if (tcp->flags & TCB_INSYSCALL) {
1058 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1059 tcp->flags &= ~TCB_INSYSCALL;
1060 }
1061 } else {
1062 if (!(tcp->flags & TCB_INSYSCALL)) {
1063 fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1064 tcp->flags |= TCB_INSYSCALL;
1065 }
1066 }
1067 # elif defined (M68K)
1068 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
1069 return -1;
1070 # elif defined (LINUX_MIPSN32)
1071 unsigned long long regs[38];
1072
1073 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
1074 return -1;
1075 a3 = regs[REG_A3];
1076 r2 = regs[REG_V0];
1077
1078 if(!(tcp->flags & TCB_INSYSCALL)) {
1079 scno = r2;
1080
1081 /* Check if we return from execve. */
1082 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1083 tcp->flags &= ~TCB_WAITEXECVE;
1084 return 0;
1085 }
1086
1087 if (scno < 0 || scno > nsyscalls) {
1088 if(a3 == 0 || a3 == -1) {
1089 if(debug)
1090 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1091 return 0;
1092 }
1093 }
1094 }
1095 # elif defined (MIPS)
1096 if (upeek(tcp, REG_A3, &a3) < 0)
1097 return -1;
1098 if(!(tcp->flags & TCB_INSYSCALL)) {
1099 if (upeek(tcp, REG_V0, &scno) < 0)
1100 return -1;
1101
1102 /* Check if we return from execve. */
1103 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1104 tcp->flags &= ~TCB_WAITEXECVE;
1105 return 0;
1106 }
1107
1108 if (scno < 0 || scno > nsyscalls) {
1109 if(a3 == 0 || a3 == -1) {
1110 if(debug)
1111 fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1112 return 0;
1113 }
1114 }
1115 } else {
1116 if (upeek(tcp, REG_V0, &r2) < 0)
1117 return -1;
1118 }
1119 # elif defined (ALPHA)
1120 if (upeek(tcp, REG_A3, &a3) < 0)
1121 return -1;
1122
1123 if (!(tcp->flags & TCB_INSYSCALL)) {
1124 if (upeek(tcp, REG_R0, &scno) < 0)
1125 return -1;
1126
1127 /* Check if we return from execve. */
1128 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1129 tcp->flags &= ~TCB_WAITEXECVE;
1130 return 0;
1131 }
1132
1133 /*
1134 * Do some sanity checks to figure out if it's
1135 * really a syscall entry
1136 */
1137 if (scno < 0 || scno > nsyscalls) {
1138 if (a3 == 0 || a3 == -1) {
1139 if (debug)
1140 fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1141 return 0;
1142 }
1143 }
1144 }
1145 else {
1146 if (upeek(tcp, REG_R0, &r0) < 0)
1147 return -1;
1148 }
1149 # elif defined (SPARC) || defined (SPARC64)
1150 /* Everything we need is in the current register set. */
1151 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1152 return -1;
1153
1154 /* If we are entering, then disassemble the syscall trap. */
1155 if (!(tcp->flags & TCB_INSYSCALL)) {
1156 /* Retrieve the syscall trap instruction. */
1157 errno = 0;
1158 # if defined(SPARC64)
1159 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1160 trap >>= 32;
1161 # else
1162 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
1163 # endif
1164 if (errno)
1165 return -1;
1166
1167 /* Disassemble the trap to see what personality to use. */
1168 switch (trap) {
1169 case 0x91d02010:
1170 /* Linux/SPARC syscall trap. */
1171 set_personality(0);
1172 break;
1173 case 0x91d0206d:
1174 /* Linux/SPARC64 syscall trap. */
1175 set_personality(2);
1176 break;
1177 case 0x91d02000:
1178 /* SunOS syscall trap. (pers 1) */
1179 fprintf(stderr,"syscall: SunOS no support\n");
1180 return -1;
1181 case 0x91d02008:
1182 /* Solaris 2.x syscall trap. (per 2) */
1183 set_personality(1);
1184 break;
1185 case 0x91d02009:
1186 /* NetBSD/FreeBSD syscall trap. */
1187 fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1188 return -1;
1189 case 0x91d02027:
1190 /* Solaris 2.x gettimeofday */
1191 set_personality(1);
1192 break;
1193 default:
1194 /* Unknown syscall trap. */
1195 if(tcp->flags & TCB_WAITEXECVE) {
1196 tcp->flags &= ~TCB_WAITEXECVE;
1197 return 0;
1198 }
1199 # if defined (SPARC64)
1200 fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
1201 # else
1202 fprintf(stderr,"syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
1203 # endif
1204 return -1;
1205 }
1206
1207 /* Extract the system call number from the registers. */
1208 if (trap == 0x91d02027)
1209 scno = 156;
1210 else
1211 scno = regs.u_regs[U_REG_G1];
1212 if (scno == 0) {
1213 scno = regs.u_regs[U_REG_O0];
1214 memmove (®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1215 }
1216 }
1217 # elif defined(HPPA)
1218 if (upeek(tcp, PT_GR20, &scno) < 0)
1219 return -1;
1220 if (!(tcp->flags & TCB_INSYSCALL)) {
1221 /* Check if we return from execve. */
1222 if ((tcp->flags & TCB_WAITEXECVE)) {
1223 tcp->flags &= ~TCB_WAITEXECVE;
1224 return 0;
1225 }
1226 }
1227 # elif defined(SH)
1228 /*
1229 * In the new syscall ABI, the system call number is in R3.
1230 */
1231 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0)
1232 return -1;
1233
1234 if (scno < 0) {
1235 /* Odd as it may seem, a glibc bug has been known to cause
1236 glibc to issue bogus negative syscall numbers. So for
1237 our purposes, make strace print what it *should* have been */
1238 long correct_scno = (scno & 0xff);
1239 if (debug)
1240 fprintf(stderr,
1241 "Detected glibc bug: bogus system call"
1242 " number = %ld, correcting to %ld\n",
1243 scno,
1244 correct_scno);
1245 scno = correct_scno;
1246 }
1247
1248 if (!(tcp->flags & TCB_INSYSCALL)) {
1249 /* Check if we return from execve. */
1250 if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1251 tcp->flags &= ~TCB_WAITEXECVE;
1252 return 0;
1253 }
1254 }
1255 # elif defined(SH64)
1256 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
1257 return -1;
1258 scno &= 0xFFFF;
1259
1260 if (!(tcp->flags & TCB_INSYSCALL)) {
1261 /* Check if we return from execve. */
1262 if (tcp->flags & TCB_WAITEXECVE) {
1263 tcp->flags &= ~TCB_WAITEXECVE;
1264 return 0;
1265 }
1266 }
1267 # elif defined(CRISV10) || defined(CRISV32)
1268 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1269 return -1;
1270 # elif defined(TILE)
1271 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0)
1272 return -1;
1273
1274 if (!(tcp->flags & TCB_INSYSCALL)) {
1275 /* Check if we return from execve. */
1276 if (tcp->flags & TCB_WAITEXECVE) {
1277 tcp->flags &= ~TCB_WAITEXECVE;
1278 return 0;
1279 }
1280 }
1281 # elif defined(MICROBLAZE)
1282 if (upeek(tcp, 0, &scno) < 0)
1283 return -1;
1284 # endif
1285 #endif /* LINUX */
1286
1287 #ifdef SUNOS4
1288 if (upeek(tcp, uoff(u_arg[7]), &scno) < 0)
1289 return -1;
1290 #elif defined(SH)
1291 /* new syscall ABI returns result in R0 */
1292 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1293 return -1;
1294 #elif defined(SH64)
1295 /* ABI defines result returned in r9 */
1296 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0)
1297 return -1;
1298 #endif
1299
1300 #ifdef USE_PROCFS
1301 # ifdef HAVE_PR_SYSCALL
1302 scno = tcp->status.PR_SYSCALL;
1303 # else
1304 # ifndef FREEBSD
1305 scno = tcp->status.PR_WHAT;
1306 # else
1307 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1308 perror("pread");
1309 return -1;
1310 }
1311 switch (regs.r_eax) {
1312 case SYS_syscall:
1313 case SYS___syscall:
1314 pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1315 break;
1316 default:
1317 scno = regs.r_eax;
1318 break;
1319 }
1320 # endif /* FREEBSD */
1321 # endif /* !HAVE_PR_SYSCALL */
1322 #endif /* USE_PROCFS */
1323
1324 if (!(tcp->flags & TCB_INSYSCALL))
1325 tcp->scno = scno;
1326 return 1;
1327 }
1328
1329
1330 long
known_scno(struct tcb * tcp)1331 known_scno(struct tcb *tcp)
1332 {
1333 long scno = tcp->scno;
1334 #if SUPPORTED_PERSONALITIES > 1
1335 if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1336 scno = sysent[scno].native_scno;
1337 else
1338 #endif
1339 scno += NR_SYSCALL_BASE;
1340 return scno;
1341 }
1342
1343 /* Called in trace_syscall() at each syscall entry and exit.
1344 * Returns:
1345 * 0: "ignore this syscall", bail out of trace_syscall() silently.
1346 * 1: ok, continue in trace_syscall().
1347 * other: error, trace_syscall() should print error indicator
1348 * ("????" etc) and bail out.
1349 */
1350 static int
syscall_fixup(struct tcb * tcp)1351 syscall_fixup(struct tcb *tcp)
1352 {
1353 #ifdef USE_PROCFS
1354 int scno = known_scno(tcp);
1355
1356 if (!(tcp->flags & TCB_INSYSCALL)) {
1357 if (tcp->status.PR_WHY != PR_SYSENTRY) {
1358 if (
1359 scno == SYS_fork
1360 #ifdef SYS_vfork
1361 || scno == SYS_vfork
1362 #endif /* SYS_vfork */
1363 #ifdef SYS_fork1
1364 || scno == SYS_fork1
1365 #endif /* SYS_fork1 */
1366 #ifdef SYS_forkall
1367 || scno == SYS_forkall
1368 #endif /* SYS_forkall */
1369 #ifdef SYS_rfork1
1370 || scno == SYS_rfork1
1371 #endif /* SYS_fork1 */
1372 #ifdef SYS_rforkall
1373 || scno == SYS_rforkall
1374 #endif /* SYS_rforkall */
1375 ) {
1376 /* We are returning in the child, fake it. */
1377 tcp->status.PR_WHY = PR_SYSENTRY;
1378 trace_syscall(tcp);
1379 tcp->status.PR_WHY = PR_SYSEXIT;
1380 }
1381 else {
1382 fprintf(stderr, "syscall: missing entry\n");
1383 tcp->flags |= TCB_INSYSCALL;
1384 }
1385 }
1386 }
1387 else {
1388 if (tcp->status.PR_WHY != PR_SYSEXIT) {
1389 fprintf(stderr, "syscall: missing exit\n");
1390 tcp->flags &= ~TCB_INSYSCALL;
1391 }
1392 }
1393 #endif /* USE_PROCFS */
1394 #ifdef SUNOS4
1395 if (!(tcp->flags & TCB_INSYSCALL)) {
1396 if (scno == 0) {
1397 fprintf(stderr, "syscall: missing entry\n");
1398 tcp->flags |= TCB_INSYSCALL;
1399 }
1400 }
1401 else {
1402 if (scno != 0) {
1403 if (debug) {
1404 /*
1405 * This happens when a signal handler
1406 * for a signal which interrupted a
1407 * a system call makes another system call.
1408 */
1409 fprintf(stderr, "syscall: missing exit\n");
1410 }
1411 tcp->flags &= ~TCB_INSYSCALL;
1412 }
1413 }
1414 #endif /* SUNOS4 */
1415 #ifdef LINUX
1416 #if defined (I386)
1417 if (upeek(tcp, 4*EAX, &eax) < 0)
1418 return -1;
1419 if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1420 if (debug)
1421 fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1422 return 0;
1423 }
1424 #elif defined (X86_64)
1425 if (upeek(tcp, 8*RAX, &rax) < 0)
1426 return -1;
1427 if (current_personality == 1)
1428 rax = (long int)(int)rax; /* sign extend from 32 bits */
1429 if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1430 if (debug)
1431 fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1432 return 0;
1433 }
1434 #elif defined (S390) || defined (S390X)
1435 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1436 return -1;
1437 if (syscall_mode != -ENOSYS)
1438 syscall_mode = tcp->scno;
1439 if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1440 if (debug)
1441 fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1442 return 0;
1443 }
1444 else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1445 == (TCB_INSYSCALL|TCB_WAITEXECVE))
1446 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1447 /*
1448 * Fake a return value of zero. We leave the TCB_WAITEXECVE
1449 * flag set for the post-execve SIGTRAP to see and reset.
1450 */
1451 gpr2 = 0;
1452 }
1453 #elif defined (POWERPC)
1454 # define SO_MASK 0x10000000
1455 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1456 return -1;
1457 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0)
1458 return -1;
1459 if (flags & SO_MASK)
1460 result = -result;
1461 #elif defined (M68K)
1462 if (upeek(tcp, 4*PT_D0, &d0) < 0)
1463 return -1;
1464 if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1465 if (debug)
1466 fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1467 return 0;
1468 }
1469 #elif defined (ARM)
1470 /*
1471 * Nothing required
1472 */
1473 #elif defined(BFIN)
1474 if (upeek(tcp, PT_R0, &r0) < 0)
1475 return -1;
1476 #elif defined (HPPA)
1477 if (upeek(tcp, PT_GR28, &r28) < 0)
1478 return -1;
1479 #elif defined(IA64)
1480 if (upeek(tcp, PT_R10, &r10) < 0)
1481 return -1;
1482 if (upeek(tcp, PT_R8, &r8) < 0)
1483 return -1;
1484 if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1485 if (debug)
1486 fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1487 return 0;
1488 }
1489 #elif defined(CRISV10) || defined(CRISV32)
1490 if (upeek(tcp, 4*PT_R10, &r10) < 0)
1491 return -1;
1492 if (r10 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1493 if (debug)
1494 fprintf(stderr, "stray syscall exit: r10 = %ld\n", r10);
1495 return 0;
1496 }
1497 #elif defined(MICROBLAZE)
1498 if (upeek(tcp, 3 * 4, &r3) < 0)
1499 return -1;
1500 if (r3 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1501 if (debug)
1502 fprintf(stderr, "stray syscall exit: r3 = %ld\n", r3);
1503 return 0;
1504 }
1505 #endif
1506 #endif /* LINUX */
1507 return 1;
1508 }
1509
1510 #ifdef LINUX
1511 /*
1512 * Check the syscall return value register value for whether it is
1513 * a negated errno code indicating an error, or a success return value.
1514 */
1515 static inline int
is_negated_errno(unsigned long int val)1516 is_negated_errno(unsigned long int val)
1517 {
1518 unsigned long int max = -(long int) nerrnos;
1519 if (personality_wordsize[current_personality] < sizeof(val)) {
1520 val = (unsigned int) val;
1521 max = (unsigned int) max;
1522 }
1523 return val > max;
1524 }
1525 #endif
1526
1527 static int
get_error(struct tcb * tcp)1528 get_error(struct tcb *tcp)
1529 {
1530 int u_error = 0;
1531 #ifdef LINUX
1532 int check_errno = 1;
1533 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
1534 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1535 check_errno = 0;
1536 }
1537 # if defined(S390) || defined(S390X)
1538 if (check_errno && is_negated_errno(gpr2)) {
1539 tcp->u_rval = -1;
1540 u_error = -gpr2;
1541 }
1542 else {
1543 tcp->u_rval = gpr2;
1544 u_error = 0;
1545 }
1546 # elif defined(I386)
1547 if (check_errno && is_negated_errno(eax)) {
1548 tcp->u_rval = -1;
1549 u_error = -eax;
1550 }
1551 else {
1552 tcp->u_rval = eax;
1553 u_error = 0;
1554 }
1555 # elif defined(X86_64)
1556 if (check_errno && is_negated_errno(rax)) {
1557 tcp->u_rval = -1;
1558 u_error = -rax;
1559 }
1560 else {
1561 tcp->u_rval = rax;
1562 u_error = 0;
1563 }
1564 # elif defined(IA64)
1565 if (ia32) {
1566 int err;
1567
1568 err = (int)r8;
1569 if (check_errno && is_negated_errno(err)) {
1570 tcp->u_rval = -1;
1571 u_error = -err;
1572 }
1573 else {
1574 tcp->u_rval = err;
1575 u_error = 0;
1576 }
1577 } else {
1578 if (check_errno && r10) {
1579 tcp->u_rval = -1;
1580 u_error = r8;
1581 } else {
1582 tcp->u_rval = r8;
1583 u_error = 0;
1584 }
1585 }
1586 # elif defined(MIPS)
1587 if (check_errno && a3) {
1588 tcp->u_rval = -1;
1589 u_error = r2;
1590 } else {
1591 tcp->u_rval = r2;
1592 u_error = 0;
1593 }
1594 # elif defined(POWERPC)
1595 if (check_errno && is_negated_errno(result)) {
1596 tcp->u_rval = -1;
1597 u_error = -result;
1598 }
1599 else {
1600 tcp->u_rval = result;
1601 u_error = 0;
1602 }
1603 # elif defined(M68K)
1604 if (check_errno && is_negated_errno(d0)) {
1605 tcp->u_rval = -1;
1606 u_error = -d0;
1607 }
1608 else {
1609 tcp->u_rval = d0;
1610 u_error = 0;
1611 }
1612 # elif defined(ARM)
1613 if (check_errno && is_negated_errno(regs.ARM_r0)) {
1614 tcp->u_rval = -1;
1615 u_error = -regs.ARM_r0;
1616 }
1617 else {
1618 tcp->u_rval = regs.ARM_r0;
1619 u_error = 0;
1620 }
1621 # elif defined(AVR32)
1622 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) {
1623 tcp->u_rval = -1;
1624 u_error = -regs.r12;
1625 }
1626 else {
1627 tcp->u_rval = regs.r12;
1628 u_error = 0;
1629 }
1630 # elif defined(BFIN)
1631 if (check_errno && is_negated_errno(r0)) {
1632 tcp->u_rval = -1;
1633 u_error = -r0;
1634 } else {
1635 tcp->u_rval = r0;
1636 u_error = 0;
1637 }
1638 # elif defined(ALPHA)
1639 if (check_errno && a3) {
1640 tcp->u_rval = -1;
1641 u_error = r0;
1642 }
1643 else {
1644 tcp->u_rval = r0;
1645 u_error = 0;
1646 }
1647 # elif defined(SPARC)
1648 if (check_errno && regs.psr & PSR_C) {
1649 tcp->u_rval = -1;
1650 u_error = regs.u_regs[U_REG_O0];
1651 }
1652 else {
1653 tcp->u_rval = regs.u_regs[U_REG_O0];
1654 u_error = 0;
1655 }
1656 # elif defined(SPARC64)
1657 if (check_errno && regs.tstate & 0x1100000000UL) {
1658 tcp->u_rval = -1;
1659 u_error = regs.u_regs[U_REG_O0];
1660 }
1661 else {
1662 tcp->u_rval = regs.u_regs[U_REG_O0];
1663 u_error = 0;
1664 }
1665 # elif defined(HPPA)
1666 if (check_errno && is_negated_errno(r28)) {
1667 tcp->u_rval = -1;
1668 u_error = -r28;
1669 }
1670 else {
1671 tcp->u_rval = r28;
1672 u_error = 0;
1673 }
1674 # elif defined(SH)
1675 /* interpret R0 as return value or error number */
1676 if (check_errno && is_negated_errno(r0)) {
1677 tcp->u_rval = -1;
1678 u_error = -r0;
1679 }
1680 else {
1681 tcp->u_rval = r0;
1682 u_error = 0;
1683 }
1684 # elif defined(SH64)
1685 /* interpret result as return value or error number */
1686 if (check_errno && is_negated_errno(r9)) {
1687 tcp->u_rval = -1;
1688 u_error = -r9;
1689 }
1690 else {
1691 tcp->u_rval = r9;
1692 u_error = 0;
1693 }
1694 # elif defined(CRISV10) || defined(CRISV32)
1695 if (check_errno && r10 && (unsigned) -r10 < nerrnos) {
1696 tcp->u_rval = -1;
1697 u_error = -r10;
1698 }
1699 else {
1700 tcp->u_rval = r10;
1701 u_error = 0;
1702 }
1703 # elif defined(TILE)
1704 long rval;
1705 /* interpret result as return value or error number */
1706 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0)
1707 return -1;
1708 if (check_errno && rval < 0 && rval > -nerrnos) {
1709 tcp->u_rval = -1;
1710 u_error = -rval;
1711 }
1712 else {
1713 tcp->u_rval = rval;
1714 u_error = 0;
1715 }
1716 # elif defined(MICROBLAZE)
1717 /* interpret result as return value or error number */
1718 if (check_errno && is_negated_errno(r3)) {
1719 tcp->u_rval = -1;
1720 u_error = -r3;
1721 }
1722 else {
1723 tcp->u_rval = r3;
1724 u_error = 0;
1725 }
1726 # endif
1727 #endif /* LINUX */
1728 #ifdef SUNOS4
1729 /* get error code from user struct */
1730 if (upeek(tcp, uoff(u_error), &u_error) < 0)
1731 return -1;
1732 u_error >>= 24; /* u_error is a char */
1733
1734 /* get system call return value */
1735 if (upeek(tcp, uoff(u_rval1), &tcp->u_rval) < 0)
1736 return -1;
1737 #endif /* SUNOS4 */
1738 #ifdef SVR4
1739 #ifdef SPARC
1740 /* Judicious guessing goes a long way. */
1741 if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1742 tcp->u_rval = -1;
1743 u_error = tcp->status.pr_reg[R_O0];
1744 }
1745 else {
1746 tcp->u_rval = tcp->status.pr_reg[R_O0];
1747 u_error = 0;
1748 }
1749 #endif /* SPARC */
1750 #ifdef I386
1751 /* Wanna know how to kill an hour single-stepping? */
1752 if (tcp->status.PR_REG[EFL] & 0x1) {
1753 tcp->u_rval = -1;
1754 u_error = tcp->status.PR_REG[EAX];
1755 }
1756 else {
1757 tcp->u_rval = tcp->status.PR_REG[EAX];
1758 #ifdef HAVE_LONG_LONG
1759 tcp->u_lrval =
1760 ((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1761 tcp->status.PR_REG[EAX];
1762 #endif
1763 u_error = 0;
1764 }
1765 #endif /* I386 */
1766 #ifdef X86_64
1767 /* Wanna know how to kill an hour single-stepping? */
1768 if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1769 tcp->u_rval = -1;
1770 u_error = tcp->status.PR_REG[RAX];
1771 }
1772 else {
1773 tcp->u_rval = tcp->status.PR_REG[RAX];
1774 u_error = 0;
1775 }
1776 #endif /* X86_64 */
1777 #ifdef MIPS
1778 if (tcp->status.pr_reg[CTX_A3]) {
1779 tcp->u_rval = -1;
1780 u_error = tcp->status.pr_reg[CTX_V0];
1781 }
1782 else {
1783 tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1784 u_error = 0;
1785 }
1786 #endif /* MIPS */
1787 #endif /* SVR4 */
1788 #ifdef FREEBSD
1789 if (regs.r_eflags & PSL_C) {
1790 tcp->u_rval = -1;
1791 u_error = regs.r_eax;
1792 } else {
1793 tcp->u_rval = regs.r_eax;
1794 tcp->u_lrval =
1795 ((unsigned long long) regs.r_edx << 32) + regs.r_eax;
1796 u_error = 0;
1797 }
1798 #endif /* FREEBSD */
1799 tcp->u_error = u_error;
1800 return 1;
1801 }
1802
1803 int
force_result(tcp,error,rval)1804 force_result(tcp, error, rval)
1805 struct tcb *tcp;
1806 int error;
1807 long rval;
1808 {
1809 #ifdef LINUX
1810 # if defined(S390) || defined(S390X)
1811 gpr2 = error ? -error : rval;
1812 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1813 return -1;
1814 # elif defined(I386)
1815 eax = error ? -error : rval;
1816 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1817 return -1;
1818 # elif defined(X86_64)
1819 rax = error ? -error : rval;
1820 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1821 return -1;
1822 # elif defined(IA64)
1823 if (ia32) {
1824 r8 = error ? -error : rval;
1825 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1826 return -1;
1827 }
1828 else {
1829 if (error) {
1830 r8 = error;
1831 r10 = -1;
1832 }
1833 else {
1834 r8 = rval;
1835 r10 = 0;
1836 }
1837 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1838 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1839 return -1;
1840 }
1841 # elif defined(BFIN)
1842 r0 = error ? -error : rval;
1843 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_R0, r0) < 0)
1844 return -1;
1845 # elif defined(MIPS)
1846 if (error) {
1847 r2 = error;
1848 a3 = -1;
1849 }
1850 else {
1851 r2 = rval;
1852 a3 = 0;
1853 }
1854 /* PTRACE_POKEUSER is OK even for n32 since rval is only a long. */
1855 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1856 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1857 return -1;
1858 # elif defined(POWERPC)
1859 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1860 return -1;
1861 if (error) {
1862 flags |= SO_MASK;
1863 result = error;
1864 }
1865 else {
1866 flags &= ~SO_MASK;
1867 result = rval;
1868 }
1869 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1870 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1871 return -1;
1872 # elif defined(M68K)
1873 d0 = error ? -error : rval;
1874 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1875 return -1;
1876 # elif defined(ARM)
1877 regs.ARM_r0 = error ? -error : rval;
1878 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1879 return -1;
1880 # elif defined(AVR32)
1881 regs.r12 = error ? -error : rval;
1882 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_R12, regs.r12) < 0)
1883 return -1;
1884 # elif defined(ALPHA)
1885 if (error) {
1886 a3 = -1;
1887 r0 = error;
1888 }
1889 else {
1890 a3 = 0;
1891 r0 = rval;
1892 }
1893 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1894 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1895 return -1;
1896 # elif defined(SPARC)
1897 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1898 return -1;
1899 if (error) {
1900 regs.psr |= PSR_C;
1901 regs.u_regs[U_REG_O0] = error;
1902 }
1903 else {
1904 regs.psr &= ~PSR_C;
1905 regs.u_regs[U_REG_O0] = rval;
1906 }
1907 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1908 return -1;
1909 # elif defined(SPARC64)
1910 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0)
1911 return -1;
1912 if (error) {
1913 regs.tstate |= 0x1100000000UL;
1914 regs.u_regs[U_REG_O0] = error;
1915 }
1916 else {
1917 regs.tstate &= ~0x1100000000UL;
1918 regs.u_regs[U_REG_O0] = rval;
1919 }
1920 if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)®s, 0) < 0)
1921 return -1;
1922 # elif defined(HPPA)
1923 r28 = error ? -error : rval;
1924 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1925 return -1;
1926 # elif defined(SH)
1927 r0 = error ? -error : rval;
1928 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1929 return -1;
1930 # elif defined(SH64)
1931 r9 = error ? -error : rval;
1932 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1933 return -1;
1934 # endif
1935 #endif /* LINUX */
1936
1937 #ifdef SUNOS4
1938 if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1939 error << 24) < 0 ||
1940 ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1941 return -1;
1942 #endif /* SUNOS4 */
1943
1944 #ifdef SVR4
1945 /* XXX no clue */
1946 return -1;
1947 #endif /* SVR4 */
1948
1949 #ifdef FREEBSD
1950 if (pread(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1951 perror("pread");
1952 return -1;
1953 }
1954 if (error) {
1955 regs.r_eflags |= PSL_C;
1956 regs.r_eax = error;
1957 }
1958 else {
1959 regs.r_eflags &= ~PSL_C;
1960 regs.r_eax = rval;
1961 }
1962 if (pwrite(tcp->pfd_reg, ®s, sizeof(regs), 0) < 0) {
1963 perror("pwrite");
1964 return -1;
1965 }
1966 #endif /* FREEBSD */
1967
1968 /* All branches reach here on success (only). */
1969 tcp->u_error = error;
1970 tcp->u_rval = rval;
1971 return 0;
1972 }
1973
1974 static int
syscall_enter(struct tcb * tcp)1975 syscall_enter(struct tcb *tcp)
1976 {
1977 #ifdef LINUX
1978 #if defined(S390) || defined(S390X)
1979 {
1980 int i;
1981 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1982 tcp->u_nargs = sysent[tcp->scno].nargs;
1983 else
1984 tcp->u_nargs = MAX_ARGS;
1985 for (i = 0; i < tcp->u_nargs; i++) {
1986 if (upeek(tcp,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1987 return -1;
1988 }
1989 }
1990 #elif defined (ALPHA)
1991 {
1992 int i;
1993 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1994 tcp->u_nargs = sysent[tcp->scno].nargs;
1995 else
1996 tcp->u_nargs = MAX_ARGS;
1997 for (i = 0; i < tcp->u_nargs; i++) {
1998 /* WTA: if scno is out-of-bounds this will bomb. Add range-check
1999 * for scno somewhere above here!
2000 */
2001 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
2002 return -1;
2003 }
2004 }
2005 #elif defined (IA64)
2006 {
2007 if (!ia32) {
2008 unsigned long *out0, cfm, sof, sol, i;
2009 long rbs_end;
2010 /* be backwards compatible with kernel < 2.4.4... */
2011 # ifndef PT_RBS_END
2012 # define PT_RBS_END PT_AR_BSP
2013 # endif
2014
2015 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
2016 return -1;
2017 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
2018 return -1;
2019
2020 sof = (cfm >> 0) & 0x7f;
2021 sol = (cfm >> 7) & 0x7f;
2022 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
2023
2024 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2025 && sysent[tcp->scno].nargs != -1)
2026 tcp->u_nargs = sysent[tcp->scno].nargs;
2027 else
2028 tcp->u_nargs = MAX_ARGS;
2029 for (i = 0; i < tcp->u_nargs; ++i) {
2030 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
2031 sizeof(long), (char *) &tcp->u_arg[i]) < 0)
2032 return -1;
2033 }
2034 } else {
2035 int i;
2036
2037 if (/* EBX = out0 */
2038 upeek(tcp, PT_R11, (long *) &tcp->u_arg[0]) < 0
2039 /* ECX = out1 */
2040 || upeek(tcp, PT_R9, (long *) &tcp->u_arg[1]) < 0
2041 /* EDX = out2 */
2042 || upeek(tcp, PT_R10, (long *) &tcp->u_arg[2]) < 0
2043 /* ESI = out3 */
2044 || upeek(tcp, PT_R14, (long *) &tcp->u_arg[3]) < 0
2045 /* EDI = out4 */
2046 || upeek(tcp, PT_R15, (long *) &tcp->u_arg[4]) < 0
2047 /* EBP = out5 */
2048 || upeek(tcp, PT_R13, (long *) &tcp->u_arg[5]) < 0)
2049 return -1;
2050
2051 for (i = 0; i < 6; ++i)
2052 /* truncate away IVE sign-extension */
2053 tcp->u_arg[i] &= 0xffffffff;
2054
2055 if (tcp->scno >= 0 && tcp->scno < nsyscalls
2056 && sysent[tcp->scno].nargs != -1)
2057 tcp->u_nargs = sysent[tcp->scno].nargs;
2058 else
2059 tcp->u_nargs = 5;
2060 }
2061 }
2062 #elif defined (LINUX_MIPSN32) || defined (LINUX_MIPSN64)
2063 /* N32 and N64 both use up to six registers. */
2064 {
2065 unsigned long long regs[38];
2066 int i, nargs;
2067
2068 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2069 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2070 else
2071 nargs = tcp->u_nargs = MAX_ARGS;
2072
2073 if (ptrace (PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0)
2074 return -1;
2075
2076 for(i = 0; i < nargs; i++) {
2077 tcp->u_arg[i] = regs[REG_A0 + i];
2078 # if defined (LINUX_MIPSN32)
2079 tcp->ext_arg[i] = regs[REG_A0 + i];
2080 # endif
2081 }
2082 }
2083 #elif defined (MIPS)
2084 {
2085 long sp;
2086 int i, nargs;
2087
2088 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2089 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
2090 else
2091 nargs = tcp->u_nargs = MAX_ARGS;
2092 if(nargs > 4) {
2093 if(upeek(tcp, REG_SP, &sp) < 0)
2094 return -1;
2095 for(i = 0; i < 4; i++) {
2096 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i])<0)
2097 return -1;
2098 }
2099 umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
2100 (char *)(tcp->u_arg + 4));
2101 } else {
2102 for(i = 0; i < nargs; i++) {
2103 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
2104 return -1;
2105 }
2106 }
2107 }
2108 #elif defined (POWERPC)
2109 # ifndef PT_ORIG_R3
2110 # define PT_ORIG_R3 34
2111 # endif
2112 {
2113 int i;
2114 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2115 tcp->u_nargs = sysent[tcp->scno].nargs;
2116 else
2117 tcp->u_nargs = MAX_ARGS;
2118 for (i = 0; i < tcp->u_nargs; i++) {
2119 if (upeek(tcp, (i==0) ?
2120 (sizeof(unsigned long)*PT_ORIG_R3) :
2121 ((i+PT_R3)*sizeof(unsigned long)),
2122 &tcp->u_arg[i]) < 0)
2123 return -1;
2124 }
2125 }
2126 #elif defined (SPARC) || defined (SPARC64)
2127 {
2128 int i;
2129
2130 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2131 tcp->u_nargs = sysent[tcp->scno].nargs;
2132 else
2133 tcp->u_nargs = MAX_ARGS;
2134 for (i = 0; i < tcp->u_nargs; i++)
2135 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
2136 }
2137 #elif defined (HPPA)
2138 {
2139 int i;
2140
2141 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2142 tcp->u_nargs = sysent[tcp->scno].nargs;
2143 else
2144 tcp->u_nargs = MAX_ARGS;
2145 for (i = 0; i < tcp->u_nargs; i++) {
2146 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2147 return -1;
2148 }
2149 }
2150 #elif defined(ARM)
2151 {
2152 int i;
2153
2154 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2155 tcp->u_nargs = sysent[tcp->scno].nargs;
2156 else
2157 tcp->u_nargs = MAX_ARGS;
2158 for (i = 0; i < tcp->u_nargs; i++)
2159 tcp->u_arg[i] = regs.uregs[i];
2160 }
2161 #elif defined(AVR32)
2162 tcp->u_nargs = sysent[tcp->scno].nargs;
2163 tcp->u_arg[0] = regs.r12;
2164 tcp->u_arg[1] = regs.r11;
2165 tcp->u_arg[2] = regs.r10;
2166 tcp->u_arg[3] = regs.r9;
2167 tcp->u_arg[4] = regs.r5;
2168 tcp->u_arg[5] = regs.r3;
2169 #elif defined(BFIN)
2170 {
2171 int i;
2172 int argreg[] = {PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5};
2173
2174 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2175 tcp->u_nargs = sysent[tcp->scno].nargs;
2176 else
2177 tcp->u_nargs = sizeof(argreg) / sizeof(argreg[0]);
2178
2179 for (i = 0; i < tcp->u_nargs; ++i)
2180 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
2181 return -1;
2182 }
2183 #elif defined(SH)
2184 {
2185 int i;
2186 static int syscall_regs[] = {
2187 REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2188 REG_REG0, REG_REG0+1, REG_REG0+2
2189 };
2190
2191 tcp->u_nargs = sysent[tcp->scno].nargs;
2192 for (i = 0; i < tcp->u_nargs; i++) {
2193 if (upeek(tcp, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2194 return -1;
2195 }
2196 }
2197 #elif defined(SH64)
2198 {
2199 int i;
2200 /* Registers used by SH5 Linux system calls for parameters */
2201 static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2202
2203 /*
2204 * TODO: should also check that the number of arguments encoded
2205 * in the trap number matches the number strace expects.
2206 */
2207 /*
2208 assert(sysent[tcp->scno].nargs <
2209 sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2210 */
2211
2212 tcp->u_nargs = sysent[tcp->scno].nargs;
2213 for (i = 0; i < tcp->u_nargs; i++) {
2214 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2215 return -1;
2216 }
2217 }
2218
2219 #elif defined(X86_64)
2220 {
2221 int i;
2222 static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2223 {RDI,RSI,RDX,R10,R8,R9}, /* x86-64 ABI */
2224 {RBX,RCX,RDX,RSI,RDI,RBP} /* i386 ABI */
2225 };
2226
2227 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2228 tcp->u_nargs = sysent[tcp->scno].nargs;
2229 else
2230 tcp->u_nargs = MAX_ARGS;
2231 for (i = 0; i < tcp->u_nargs; i++) {
2232 if (upeek(tcp, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2233 return -1;
2234 }
2235 }
2236 #elif defined(MICROBLAZE)
2237 {
2238 int i;
2239 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2240 tcp->u_nargs = sysent[tcp->scno].nargs;
2241 else
2242 tcp->u_nargs = 0;
2243 for (i = 0; i < tcp->u_nargs; i++) {
2244 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
2245 return -1;
2246 }
2247 }
2248 #elif defined(CRISV10) || defined(CRISV32)
2249 {
2250 int i;
2251 static const int crisregs[] = {
2252 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
2253 4*PT_R13, 4*PT_MOF, 4*PT_SRP
2254 };
2255
2256 if (tcp->scno >= 0 && tcp->scno < nsyscalls)
2257 tcp->u_nargs = sysent[tcp->scno].nargs;
2258 else
2259 tcp->u_nargs = 0;
2260 for (i = 0; i < tcp->u_nargs; i++) {
2261 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
2262 return -1;
2263 }
2264 }
2265 #elif defined(TILE)
2266 {
2267 int i;
2268 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2269 tcp->u_nargs = sysent[tcp->scno].nargs;
2270 else
2271 tcp->u_nargs = MAX_ARGS;
2272 for (i = 0; i < tcp->u_nargs; ++i) {
2273 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0)
2274 return -1;
2275 }
2276 }
2277 #elif defined (M68K)
2278 {
2279 int i;
2280 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2281 tcp->u_nargs = sysent[tcp->scno].nargs;
2282 else
2283 tcp->u_nargs = MAX_ARGS;
2284 for (i = 0; i < tcp->u_nargs; i++) {
2285 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
2286 return -1;
2287 }
2288 }
2289 #else /* Other architecture (like i386) (32bits specific) */
2290 {
2291 int i;
2292 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2293 tcp->u_nargs = sysent[tcp->scno].nargs;
2294 else
2295 tcp->u_nargs = MAX_ARGS;
2296 for (i = 0; i < tcp->u_nargs; i++) {
2297 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
2298 return -1;
2299 }
2300 }
2301 #endif
2302 #endif /* LINUX */
2303 #ifdef SUNOS4
2304 {
2305 int i;
2306 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2307 tcp->u_nargs = sysent[tcp->scno].nargs;
2308 else
2309 tcp->u_nargs = MAX_ARGS;
2310 for (i = 0; i < tcp->u_nargs; i++) {
2311 struct user *u;
2312
2313 if (upeek(tcp, uoff(u_arg[0]) +
2314 (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2315 return -1;
2316 }
2317 }
2318 #endif /* SUNOS4 */
2319 #ifdef SVR4
2320 #ifdef MIPS
2321 /*
2322 * SGI is broken: even though it has pr_sysarg, it doesn't
2323 * set them on system call entry. Get a clue.
2324 */
2325 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2326 tcp->u_nargs = sysent[tcp->scno].nargs;
2327 else
2328 tcp->u_nargs = tcp->status.pr_nsysarg;
2329 if (tcp->u_nargs > 4) {
2330 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2331 4*sizeof(tcp->u_arg[0]));
2332 umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2333 (tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2334 }
2335 else {
2336 memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2337 tcp->u_nargs*sizeof(tcp->u_arg[0]));
2338 }
2339 #elif UNIXWARE >= 2
2340 /*
2341 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2342 */
2343 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2344 tcp->u_nargs = sysent[tcp->scno].nargs;
2345 else
2346 tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2347 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2348 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2349 #elif defined (HAVE_PR_SYSCALL)
2350 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2351 tcp->u_nargs = sysent[tcp->scno].nargs;
2352 else
2353 tcp->u_nargs = tcp->status.pr_nsysarg;
2354 {
2355 int i;
2356 for (i = 0; i < tcp->u_nargs; i++)
2357 tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2358 }
2359 #elif defined (I386)
2360 if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2361 tcp->u_nargs = sysent[tcp->scno].nargs;
2362 else
2363 tcp->u_nargs = 5;
2364 umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2365 tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2366 #else
2367 I DONT KNOW WHAT TO DO
2368 #endif /* !HAVE_PR_SYSCALL */
2369 #endif /* SVR4 */
2370 #ifdef FREEBSD
2371 if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2372 sysent[tcp->scno].nargs > tcp->status.val)
2373 tcp->u_nargs = sysent[tcp->scno].nargs;
2374 else
2375 tcp->u_nargs = tcp->status.val;
2376 if (tcp->u_nargs < 0)
2377 tcp->u_nargs = 0;
2378 if (tcp->u_nargs > MAX_ARGS)
2379 tcp->u_nargs = MAX_ARGS;
2380 switch(regs.r_eax) {
2381 case SYS___syscall:
2382 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2383 regs.r_esp + sizeof(int) + sizeof(quad_t));
2384 break;
2385 case SYS_syscall:
2386 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2387 regs.r_esp + 2 * sizeof(int));
2388 break;
2389 default:
2390 pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2391 regs.r_esp + sizeof(int));
2392 break;
2393 }
2394 #endif /* FREEBSD */
2395 return 1;
2396 }
2397
2398 static int
trace_syscall_exiting(struct tcb * tcp)2399 trace_syscall_exiting(struct tcb *tcp)
2400 {
2401 int sys_res;
2402 struct timeval tv;
2403 int res, scno_good;
2404 long u_error;
2405
2406 /* Measure the exit time as early as possible to avoid errors. */
2407 if (dtime || cflag)
2408 gettimeofday(&tv, NULL);
2409
2410 /* BTW, why we don't just memorize syscall no. on entry
2411 * in tcp->something?
2412 */
2413 scno_good = res = get_scno(tcp);
2414 if (res == 0)
2415 return res;
2416 if (res == 1)
2417 res = syscall_fixup(tcp);
2418 if (res == 0)
2419 return res;
2420 if (res == 1)
2421 res = get_error(tcp);
2422 if (res == 0)
2423 return res;
2424 if (res == 1)
2425 internal_syscall(tcp);
2426
2427 if (res == 1 && tcp->scno >= 0 && tcp->scno < nsyscalls &&
2428 !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2429 tcp->flags &= ~TCB_INSYSCALL;
2430 return 0;
2431 }
2432
2433 if (tcp->flags & TCB_REPRINT) {
2434 printleader(tcp);
2435 tprintf("<... ");
2436 if (scno_good != 1)
2437 tprintf("????");
2438 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2439 tprintf("syscall_%lu", tcp->scno);
2440 else
2441 tprintf("%s", sysent[tcp->scno].sys_name);
2442 tprintf(" resumed> ");
2443 }
2444
2445 if (cflag) {
2446 struct timeval t = tv;
2447 int rc = count_syscall(tcp, &t);
2448 if (cflag == CFLAG_ONLY_STATS)
2449 {
2450 tcp->flags &= ~TCB_INSYSCALL;
2451 return rc;
2452 }
2453 }
2454
2455 if (res != 1) {
2456 tprintf(") ");
2457 tabto(acolumn);
2458 tprintf("= ? <unavailable>");
2459 printtrailer();
2460 tcp->flags &= ~TCB_INSYSCALL;
2461 return res;
2462 }
2463
2464 if (tcp->scno >= nsyscalls || tcp->scno < 0
2465 || (qual_flags[tcp->scno] & QUAL_RAW))
2466 sys_res = printargs(tcp);
2467 else {
2468 if (not_failing_only && tcp->u_error)
2469 return 0; /* ignore failed syscalls */
2470 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2471 }
2472
2473 u_error = tcp->u_error;
2474 tprintf(") ");
2475 tabto(acolumn);
2476 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2477 qual_flags[tcp->scno] & QUAL_RAW) {
2478 if (u_error)
2479 tprintf("= -1 (errno %ld)", u_error);
2480 else
2481 tprintf("= %#lx", tcp->u_rval);
2482 }
2483 else if (!(sys_res & RVAL_NONE) && u_error) {
2484 switch (u_error) {
2485 #ifdef LINUX
2486 case ERESTARTSYS:
2487 tprintf("= ? ERESTARTSYS (To be restarted)");
2488 break;
2489 case ERESTARTNOINTR:
2490 tprintf("= ? ERESTARTNOINTR (To be restarted)");
2491 break;
2492 case ERESTARTNOHAND:
2493 tprintf("= ? ERESTARTNOHAND (To be restarted)");
2494 break;
2495 case ERESTART_RESTARTBLOCK:
2496 tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2497 break;
2498 #endif /* LINUX */
2499 default:
2500 tprintf("= -1 ");
2501 if (u_error < 0)
2502 tprintf("E??? (errno %ld)", u_error);
2503 else if (u_error < nerrnos)
2504 tprintf("%s (%s)", errnoent[u_error],
2505 strerror(u_error));
2506 else
2507 tprintf("ERRNO_%ld (%s)", u_error,
2508 strerror(u_error));
2509 break;
2510 }
2511 if ((sys_res & RVAL_STR) && tcp->auxstr)
2512 tprintf(" (%s)", tcp->auxstr);
2513 }
2514 else {
2515 if (sys_res & RVAL_NONE)
2516 tprintf("= ?");
2517 else {
2518 switch (sys_res & RVAL_MASK) {
2519 case RVAL_HEX:
2520 tprintf("= %#lx", tcp->u_rval);
2521 break;
2522 case RVAL_OCTAL:
2523 tprintf("= %#lo", tcp->u_rval);
2524 break;
2525 case RVAL_UDECIMAL:
2526 tprintf("= %lu", tcp->u_rval);
2527 break;
2528 case RVAL_DECIMAL:
2529 tprintf("= %ld", tcp->u_rval);
2530 break;
2531 #ifdef HAVE_LONG_LONG
2532 case RVAL_LHEX:
2533 tprintf("= %#llx", tcp->u_lrval);
2534 break;
2535 case RVAL_LOCTAL:
2536 tprintf("= %#llo", tcp->u_lrval);
2537 break;
2538 case RVAL_LUDECIMAL:
2539 tprintf("= %llu", tcp->u_lrval);
2540 break;
2541 case RVAL_LDECIMAL:
2542 tprintf("= %lld", tcp->u_lrval);
2543 break;
2544 #endif
2545 default:
2546 fprintf(stderr,
2547 "invalid rval format\n");
2548 break;
2549 }
2550 }
2551 if ((sys_res & RVAL_STR) && tcp->auxstr)
2552 tprintf(" (%s)", tcp->auxstr);
2553 }
2554 if (dtime) {
2555 tv_sub(&tv, &tv, &tcp->etime);
2556 tprintf(" <%ld.%06ld>",
2557 (long) tv.tv_sec, (long) tv.tv_usec);
2558 }
2559 printtrailer();
2560
2561 dumpio(tcp);
2562 if (fflush(tcp->outf) == EOF)
2563 return -1;
2564 tcp->flags &= ~TCB_INSYSCALL;
2565 return 0;
2566 }
2567
2568 static int
trace_syscall_entering(struct tcb * tcp)2569 trace_syscall_entering(struct tcb *tcp)
2570 {
2571 int sys_res;
2572 int res, scno_good;
2573
2574 scno_good = res = get_scno(tcp);
2575 if (res == 0)
2576 return res;
2577 if (res == 1)
2578 res = syscall_fixup(tcp);
2579 if (res == 0)
2580 return res;
2581 if (res == 1)
2582 res = syscall_enter(tcp);
2583 if (res == 0)
2584 return res;
2585
2586 if (res != 1) {
2587 printleader(tcp);
2588 tcp->flags &= ~TCB_REPRINT;
2589 tcp_last = tcp;
2590 if (scno_good != 1)
2591 tprintf("????" /* anti-trigraph gap */ "(");
2592 else if (tcp->scno >= nsyscalls || tcp->scno < 0)
2593 tprintf("syscall_%lu(", tcp->scno);
2594 else
2595 tprintf("%s(", sysent[tcp->scno].sys_name);
2596 /*
2597 * " <unavailable>" will be added later by the code which
2598 * detects ptrace errors.
2599 */
2600 tcp->flags |= TCB_INSYSCALL;
2601 return res;
2602 }
2603
2604 switch (known_scno(tcp)) {
2605 #ifndef __ARM_EABI__
2606 #ifdef SYS_socket_subcall
2607 case SYS_socketcall:
2608 decode_subcall(tcp, SYS_socket_subcall,
2609 SYS_socket_nsubcalls, deref_style);
2610 break;
2611 #endif
2612 #ifdef SYS_ipc_subcall
2613 case SYS_ipc:
2614 decode_subcall(tcp, SYS_ipc_subcall,
2615 SYS_ipc_nsubcalls, shift_style);
2616 break;
2617 #endif
2618 #endif
2619 #ifdef SVR4
2620 #ifdef SYS_pgrpsys_subcall
2621 case SYS_pgrpsys:
2622 decode_subcall(tcp, SYS_pgrpsys_subcall,
2623 SYS_pgrpsys_nsubcalls, shift_style);
2624 break;
2625 #endif /* SYS_pgrpsys_subcall */
2626 #ifdef SYS_sigcall_subcall
2627 case SYS_sigcall:
2628 decode_subcall(tcp, SYS_sigcall_subcall,
2629 SYS_sigcall_nsubcalls, mask_style);
2630 break;
2631 #endif /* SYS_sigcall_subcall */
2632 case SYS_msgsys:
2633 decode_subcall(tcp, SYS_msgsys_subcall,
2634 SYS_msgsys_nsubcalls, shift_style);
2635 break;
2636 case SYS_shmsys:
2637 decode_subcall(tcp, SYS_shmsys_subcall,
2638 SYS_shmsys_nsubcalls, shift_style);
2639 break;
2640 case SYS_semsys:
2641 decode_subcall(tcp, SYS_semsys_subcall,
2642 SYS_semsys_nsubcalls, shift_style);
2643 break;
2644 case SYS_sysfs:
2645 decode_subcall(tcp, SYS_sysfs_subcall,
2646 SYS_sysfs_nsubcalls, shift_style);
2647 break;
2648 case SYS_spcall:
2649 decode_subcall(tcp, SYS_spcall_subcall,
2650 SYS_spcall_nsubcalls, shift_style);
2651 break;
2652 #ifdef SYS_context_subcall
2653 case SYS_context:
2654 decode_subcall(tcp, SYS_context_subcall,
2655 SYS_context_nsubcalls, shift_style);
2656 break;
2657 #endif /* SYS_context_subcall */
2658 #ifdef SYS_door_subcall
2659 case SYS_door:
2660 decode_subcall(tcp, SYS_door_subcall,
2661 SYS_door_nsubcalls, door_style);
2662 break;
2663 #endif /* SYS_door_subcall */
2664 #ifdef SYS_kaio_subcall
2665 case SYS_kaio:
2666 decode_subcall(tcp, SYS_kaio_subcall,
2667 SYS_kaio_nsubcalls, shift_style);
2668 break;
2669 #endif
2670 #endif /* SVR4 */
2671 #ifdef FREEBSD
2672 case SYS_msgsys:
2673 case SYS_shmsys:
2674 case SYS_semsys:
2675 decode_subcall(tcp, 0, 0, table_style);
2676 break;
2677 #endif
2678 #ifdef SUNOS4
2679 case SYS_semsys:
2680 decode_subcall(tcp, SYS_semsys_subcall,
2681 SYS_semsys_nsubcalls, shift_style);
2682 break;
2683 case SYS_msgsys:
2684 decode_subcall(tcp, SYS_msgsys_subcall,
2685 SYS_msgsys_nsubcalls, shift_style);
2686 break;
2687 case SYS_shmsys:
2688 decode_subcall(tcp, SYS_shmsys_subcall,
2689 SYS_shmsys_nsubcalls, shift_style);
2690 break;
2691 #endif
2692 }
2693
2694 internal_syscall(tcp);
2695 if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2696 tcp->flags |= TCB_INSYSCALL;
2697 return 0;
2698 }
2699
2700 if (cflag == CFLAG_ONLY_STATS) {
2701 tcp->flags |= TCB_INSYSCALL;
2702 gettimeofday(&tcp->etime, NULL);
2703 return 0;
2704 }
2705
2706 printleader(tcp);
2707 tcp->flags &= ~TCB_REPRINT;
2708 tcp_last = tcp;
2709 if (tcp->scno >= nsyscalls || tcp->scno < 0)
2710 tprintf("syscall_%lu(", tcp->scno);
2711 else
2712 tprintf("%s(", sysent[tcp->scno].sys_name);
2713 if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2714 ((qual_flags[tcp->scno] & QUAL_RAW) &&
2715 sysent[tcp->scno].sys_func != sys_exit))
2716 sys_res = printargs(tcp);
2717 else
2718 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2719 if (fflush(tcp->outf) == EOF)
2720 return -1;
2721 tcp->flags |= TCB_INSYSCALL;
2722 /* Measure the entrance time as late as possible to avoid errors. */
2723 if (dtime || cflag)
2724 gettimeofday(&tcp->etime, NULL);
2725 return sys_res;
2726 }
2727
2728 int
trace_syscall(struct tcb * tcp)2729 trace_syscall(struct tcb *tcp)
2730 {
2731 return exiting(tcp) ?
2732 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2733 }
2734
2735 int
printargs(tcp)2736 printargs(tcp)
2737 struct tcb *tcp;
2738 {
2739 if (entering(tcp)) {
2740 int i;
2741
2742 for (i = 0; i < tcp->u_nargs; i++)
2743 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2744 }
2745 return 0;
2746 }
2747
2748 long
getrval2(tcp)2749 getrval2(tcp)
2750 struct tcb *tcp;
2751 {
2752 long val = -1;
2753
2754 #ifdef LINUX
2755 #if defined (SPARC) || defined (SPARC64)
2756 struct pt_regs regs;
2757 if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)®s,0) < 0)
2758 return -1;
2759 val = regs.u_regs[U_REG_O1];
2760 #elif defined(SH)
2761 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
2762 return -1;
2763 #elif defined(IA64)
2764 if (upeek(tcp, PT_R9, &val) < 0)
2765 return -1;
2766 #endif
2767 #endif /* LINUX */
2768
2769 #ifdef SUNOS4
2770 if (upeek(tcp, uoff(u_rval2), &val) < 0)
2771 return -1;
2772 #endif /* SUNOS4 */
2773
2774 #ifdef SVR4
2775 #ifdef SPARC
2776 val = tcp->status.PR_REG[R_O1];
2777 #endif /* SPARC */
2778 #ifdef I386
2779 val = tcp->status.PR_REG[EDX];
2780 #endif /* I386 */
2781 #ifdef X86_64
2782 val = tcp->status.PR_REG[RDX];
2783 #endif /* X86_64 */
2784 #ifdef MIPS
2785 val = tcp->status.PR_REG[CTX_V1];
2786 #endif /* MIPS */
2787 #endif /* SVR4 */
2788
2789 #ifdef FREEBSD
2790 struct reg regs;
2791 pread(tcp->pfd_reg, ®s, sizeof(regs), 0);
2792 val = regs.r_edx;
2793 #endif
2794 return val;
2795 }
2796
2797 #ifdef SUNOS4
2798 /*
2799 * Apparently, indirect system calls have already be converted by ptrace(2),
2800 * so if you see "indir" this program has gone astray.
2801 */
2802 int
sys_indir(tcp)2803 sys_indir(tcp)
2804 struct tcb *tcp;
2805 {
2806 int i, scno, nargs;
2807
2808 if (entering(tcp)) {
2809 if ((scno = tcp->u_arg[0]) > nsyscalls) {
2810 fprintf(stderr, "Bogus syscall: %u\n", scno);
2811 return 0;
2812 }
2813 nargs = sysent[scno].nargs;
2814 tprintf("%s", sysent[scno].sys_name);
2815 for (i = 0; i < nargs; i++)
2816 tprintf(", %#lx", tcp->u_arg[i+1]);
2817 }
2818 return 0;
2819 }
2820 #endif /* SUNOS4 */
2821
2822 int
is_restart_error(struct tcb * tcp)2823 is_restart_error(struct tcb *tcp)
2824 {
2825 #ifdef LINUX
2826 if (!syserror(tcp))
2827 return 0;
2828 switch (tcp->u_error) {
2829 case ERESTARTSYS:
2830 case ERESTARTNOINTR:
2831 case ERESTARTNOHAND:
2832 case ERESTART_RESTARTBLOCK:
2833 return 1;
2834 default:
2835 break;
2836 }
2837 #endif /* LINUX */
2838 return 0;
2839 }
2840