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