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