• 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 		/*
1017 		 * Note: we only deal with only 32-bit CPUs here.
1018 		 */
1019 		if (regs.ARM_cpsr & 0x20) {
1020 			/*
1021 			 * Get the Thumb-mode system call number
1022 			 */
1023 			scno = regs.ARM_r7;
1024 		} else {
1025 			/*
1026 			 * Get the ARM-mode system call number
1027 			 */
1028 			errno = 0;
1029 			scno = ptrace(PTRACE_PEEKTEXT, pid, (void *)(regs.ARM_pc - 4), NULL);
1030 			if (errno)
1031 				return -1;
1032 
1033 			if (scno == 0 && (tcp->flags & TCB_WAITEXECVE)) {
1034 				tcp->flags &= ~TCB_WAITEXECVE;
1035 				return 0;
1036 			}
1037 
1038 			/* Handle the EABI syscall convention.  We do not
1039 			   bother converting structures between the two
1040 			   ABIs, but basic functionality should work even
1041 			   if strace and the traced program have different
1042 			   ABIs.  */
1043 			if (scno == 0xef000000) {
1044 				scno = regs.ARM_r7;
1045 			} else {
1046 				if ((scno & 0x0ff00000) != 0x0f900000) {
1047 					fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1048 						scno);
1049 					return -1;
1050 				}
1051 
1052 				/*
1053 				 * Fixup the syscall number
1054 				 */
1055 				scno &= 0x000fffff;
1056 			}
1057 		}
1058 
1059 		if (tcp->flags & TCB_INSYSCALL) {
1060 			fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1061 			tcp->flags &= ~TCB_INSYSCALL;
1062 		}
1063 	} else {
1064 		if (!(tcp->flags & TCB_INSYSCALL)) {
1065 			fprintf(stderr, "pid %d stray syscall exit\n", tcp->pid);
1066 			tcp->flags |= TCB_INSYSCALL;
1067 		}
1068 	}
1069 #elif defined (M68K)
1070 	if (upeek(pid, 4*PT_ORIG_D0, &scno) < 0)
1071 		return -1;
1072 #elif defined (MIPS)
1073 	if (upeek(pid, REG_A3, &a3) < 0)
1074 	  	return -1;
1075 
1076 	if(!(tcp->flags & TCB_INSYSCALL)) {
1077 	  	if (upeek(pid, REG_V0, &scno) < 0)
1078 		  	return -1;
1079 
1080 		if (scno < 0 || scno > nsyscalls) {
1081 			if(a3 == 0 || a3 == -1) {
1082 				if(debug)
1083 					fprintf (stderr, "stray syscall exit: v0 = %ld\n", scno);
1084 				return 0;
1085 			}
1086 		}
1087 	} else {
1088 	  	if (upeek(pid, REG_V0, &r2) < 0)
1089 	    		return -1;
1090 	}
1091 #elif defined (ALPHA)
1092 	if (upeek(pid, REG_A3, &a3) < 0)
1093 		return -1;
1094 
1095 	if (!(tcp->flags & TCB_INSYSCALL)) {
1096 		if (upeek(pid, REG_R0, &scno) < 0)
1097 			return -1;
1098 
1099 		/* Check if we return from execve. */
1100 		if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1101 			tcp->flags &= ~TCB_WAITEXECVE;
1102 			return 0;
1103 		}
1104 
1105 		/*
1106 		 * Do some sanity checks to figure out if it's
1107 		 * really a syscall entry
1108 		 */
1109 		if (scno < 0 || scno > nsyscalls) {
1110 			if (a3 == 0 || a3 == -1) {
1111 				if (debug)
1112 					fprintf (stderr, "stray syscall exit: r0 = %ld\n", scno);
1113 				return 0;
1114 			}
1115 		}
1116 	}
1117 	else {
1118 		if (upeek(pid, REG_R0, &r0) < 0)
1119 			return -1;
1120 	}
1121 #elif defined (SPARC) || defined (SPARC64)
1122 	/* Everything we need is in the current register set. */
1123 	if (ptrace(PTRACE_GETREGS,pid,(char *)&regs,0) < 0)
1124 		return -1;
1125 
1126         /* If we are entering, then disassemble the syscall trap. */
1127 	if (!(tcp->flags & TCB_INSYSCALL)) {
1128 		/* Retrieve the syscall trap instruction. */
1129 		errno = 0;
1130 		trap = ptrace(PTRACE_PEEKTEXT,pid,(char *)regs.r_pc,0);
1131 #if defined(SPARC64)
1132 		trap >>= 32;
1133 #endif
1134 		if (errno)
1135 			return -1;
1136 
1137 		/* Disassemble the trap to see what personality to use. */
1138 		switch (trap) {
1139 		case 0x91d02010:
1140 			/* Linux/SPARC syscall trap. */
1141 			set_personality(0);
1142 			break;
1143 		case 0x91d0206d:
1144 			/* Linux/SPARC64 syscall trap. */
1145 			set_personality(2);
1146 			break;
1147 		case 0x91d02000:
1148 			/* SunOS syscall trap. (pers 1) */
1149 			fprintf(stderr,"syscall: SunOS no support\n");
1150 			return -1;
1151 		case 0x91d02008:
1152 			/* Solaris 2.x syscall trap. (per 2) */
1153 			set_personality(1);
1154 			break;
1155 		case 0x91d02009:
1156 			/* NetBSD/FreeBSD syscall trap. */
1157 			fprintf(stderr,"syscall: NetBSD/FreeBSD not supported\n");
1158 			return -1;
1159 		case 0x91d02027:
1160 			/* Solaris 2.x gettimeofday */
1161 			set_personality(1);
1162 			break;
1163 		default:
1164 			/* Unknown syscall trap. */
1165 			if(tcp->flags & TCB_WAITEXECVE) {
1166 				tcp->flags &= ~TCB_WAITEXECVE;
1167 				return 0;
1168 			}
1169 #if defined (SPARC64)
1170 			fprintf(stderr,"syscall: unknown syscall trap %08lx %016lx\n", trap, regs.r_tpc);
1171 #else
1172 			fprintf(stderr,"syscall: unknown syscall trap %08x %08x\n", trap, regs.r_pc);
1173 #endif
1174 			return -1;
1175 		}
1176 
1177 		/* Extract the system call number from the registers. */
1178 		if (trap == 0x91d02027)
1179 			scno = 156;
1180 		else
1181 			scno = regs.r_g1;
1182 		if (scno == 0) {
1183 			scno = regs.r_o0;
1184 			memmove (&regs.r_o0, &regs.r_o1, 7*sizeof(regs.r_o0));
1185 		}
1186 	}
1187 #elif defined(HPPA)
1188 	if (upeek(pid, PT_GR20, &scno) < 0)
1189 		return -1;
1190 	if (!(tcp->flags & TCB_INSYSCALL)) {
1191 		/* Check if we return from execve. */
1192 		if ((tcp->flags & TCB_WAITEXECVE)) {
1193 			tcp->flags &= ~TCB_WAITEXECVE;
1194 			return 0;
1195 		}
1196 	}
1197 #elif defined(SH)
1198        /*
1199         * In the new syscall ABI, the system call number is in R3.
1200         */
1201        if (upeek(pid, 4*(REG_REG0+3), &scno) < 0)
1202                return -1;
1203 
1204        if (scno < 0) {
1205            /* Odd as it may seem, a glibc bug has been known to cause
1206               glibc to issue bogus negative syscall numbers.  So for
1207               our purposes, make strace print what it *should* have been */
1208            long correct_scno = (scno & 0xff);
1209            if (debug)
1210                fprintf(stderr,
1211                    "Detected glibc bug: bogus system call number = %ld, "
1212 		   "correcting to %ld\n",
1213                    scno,
1214                    correct_scno);
1215            scno = correct_scno;
1216        }
1217 
1218 
1219        if (!(tcp->flags & TCB_INSYSCALL)) {
1220                /* Check if we return from execve. */
1221                if (scno == 0 && tcp->flags & TCB_WAITEXECVE) {
1222                        tcp->flags &= ~TCB_WAITEXECVE;
1223                        return 0;
1224                }
1225        }
1226 #elif defined(SH64)
1227 	if (upeek(pid, REG_SYSCALL, &scno) < 0)
1228 		return -1;
1229         scno &= 0xFFFF;
1230 
1231 	if (!(tcp->flags & TCB_INSYSCALL)) {
1232 		/* Check if we return from execve. */
1233 		if (tcp->flags & TCB_WAITEXECVE) {
1234 			tcp->flags &= ~TCB_WAITEXECVE;
1235 			return 0;
1236 		}
1237 	}
1238 #endif /* SH64 */
1239 #endif /* LINUX */
1240 #ifdef SUNOS4
1241 	if (upeek(pid, uoff(u_arg[7]), &scno) < 0)
1242 		return -1;
1243 #elif defined(SH)
1244         /* new syscall ABI returns result in R0 */
1245         if (upeek(pid, 4*REG_REG0, (long *)&r0) < 0)
1246                 return -1;
1247 #elif defined(SH64)
1248         /* ABI defines result returned in r9 */
1249         if (upeek(pid, REG_GENERAL(9), (long *)&r9) < 0)
1250                 return -1;
1251 
1252 #endif
1253 #ifdef USE_PROCFS
1254 #ifdef HAVE_PR_SYSCALL
1255 	scno = tcp->status.PR_SYSCALL;
1256 #else /* !HAVE_PR_SYSCALL */
1257 #ifndef FREEBSD
1258 	scno = tcp->status.PR_WHAT;
1259 #else /* FREEBSD */
1260 	if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1261 	        perror("pread");
1262                 return -1;
1263         }
1264 	switch (regs.r_eax) {
1265 	case SYS_syscall:
1266 	case SYS___syscall:
1267     	        pread(tcp->pfd, &scno, sizeof(scno), regs.r_esp + sizeof(int));
1268 	        break;
1269 	default:
1270 	        scno = regs.r_eax;
1271 	        break;
1272 	}
1273 #endif /* FREEBSD */
1274 #endif /* !HAVE_PR_SYSCALL */
1275 #endif /* USE_PROCFS */
1276 	if (!(tcp->flags & TCB_INSYSCALL))
1277 		tcp->scno = scno;
1278 	return 1;
1279 }
1280 
1281 
1282 long
known_scno(tcp)1283 known_scno(tcp)
1284 struct tcb *tcp;
1285 {
1286 	long scno = tcp->scno;
1287 	if (scno >= 0 && scno < nsyscalls && sysent[scno].native_scno != 0)
1288 		scno = sysent[scno].native_scno;
1289 	else
1290 		scno += NR_SYSCALL_BASE;
1291 	return scno;
1292 }
1293 
1294 static int
syscall_fixup(tcp)1295 syscall_fixup(tcp)
1296 struct tcb *tcp;
1297 {
1298 #ifndef USE_PROCFS
1299 	int pid = tcp->pid;
1300 #else /* USE_PROCFS */
1301 	int scno = known_scno(tcp);
1302 
1303 	if (!(tcp->flags & TCB_INSYSCALL)) {
1304 		if (tcp->status.PR_WHY != PR_SYSENTRY) {
1305 			if (
1306 			    scno == SYS_fork
1307 #ifdef SYS_vfork
1308 			    || scno == SYS_vfork
1309 #endif /* SYS_vfork */
1310 #ifdef SYS_fork1
1311 			    || scno == SYS_fork1
1312 #endif /* SYS_fork1 */
1313 #ifdef SYS_forkall
1314 			    || scno == SYS_forkall
1315 #endif /* SYS_forkall */
1316 #ifdef SYS_rfork1
1317 			    || scno == SYS_rfork1
1318 #endif /* SYS_fork1 */
1319 #ifdef SYS_rforkall
1320 			    || scno == SYS_rforkall
1321 #endif /* SYS_rforkall */
1322 			    ) {
1323 				/* We are returning in the child, fake it. */
1324 				tcp->status.PR_WHY = PR_SYSENTRY;
1325 				trace_syscall(tcp);
1326 				tcp->status.PR_WHY = PR_SYSEXIT;
1327 			}
1328 			else {
1329 				fprintf(stderr, "syscall: missing entry\n");
1330 				tcp->flags |= TCB_INSYSCALL;
1331 			}
1332 		}
1333 	}
1334 	else {
1335 		if (tcp->status.PR_WHY != PR_SYSEXIT) {
1336 			fprintf(stderr, "syscall: missing exit\n");
1337 			tcp->flags &= ~TCB_INSYSCALL;
1338 		}
1339 	}
1340 #endif /* USE_PROCFS */
1341 #ifdef SUNOS4
1342 	if (!(tcp->flags & TCB_INSYSCALL)) {
1343 		if (scno == 0) {
1344 			fprintf(stderr, "syscall: missing entry\n");
1345 			tcp->flags |= TCB_INSYSCALL;
1346 		}
1347 	}
1348 	else {
1349 		if (scno != 0) {
1350 			if (debug) {
1351 				/*
1352 				 * This happens when a signal handler
1353 				 * for a signal which interrupted a
1354 				 * a system call makes another system call.
1355 				 */
1356 				fprintf(stderr, "syscall: missing exit\n");
1357 			}
1358 			tcp->flags &= ~TCB_INSYSCALL;
1359 		}
1360 	}
1361 #endif /* SUNOS4 */
1362 #ifdef LINUX
1363 #if defined (I386)
1364 	if (upeek(pid, 4*EAX, &eax) < 0)
1365 		return -1;
1366 	if (eax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1367 		if (debug)
1368 			fprintf(stderr, "stray syscall exit: eax = %ld\n", eax);
1369 		return 0;
1370 	}
1371 #elif defined (X86_64)
1372 	if (upeek(pid, 8*RAX, &rax) < 0)
1373 		return -1;
1374 	if (current_personality == 1)
1375 		rax = (long int)(int)rax; /* sign extend from 32 bits */
1376 	if (rax != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1377 		if (debug)
1378 			fprintf(stderr, "stray syscall exit: rax = %ld\n", rax);
1379 		return 0;
1380 	}
1381 #elif defined (S390) || defined (S390X)
1382 	if (upeek(pid, PT_GPR2, &gpr2) < 0)
1383 		return -1;
1384 	if (syscall_mode != -ENOSYS)
1385 		syscall_mode = tcp->scno;
1386 	if (gpr2 != syscall_mode && !(tcp->flags & TCB_INSYSCALL)) {
1387 		if (debug)
1388 			fprintf(stderr, "stray syscall exit: gpr2 = %ld\n", gpr2);
1389 		return 0;
1390 	}
1391 	else if (((tcp->flags & (TCB_INSYSCALL|TCB_WAITEXECVE))
1392 		  == (TCB_INSYSCALL|TCB_WAITEXECVE))
1393 		 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) {
1394 		/*
1395 		 * Fake a return value of zero.  We leave the TCB_WAITEXECVE
1396 		 * flag set for the post-execve SIGTRAP to see and reset.
1397 		 */
1398 		gpr2 = 0;
1399 	}
1400 #elif defined (POWERPC)
1401 # define SO_MASK 0x10000000
1402 	if (upeek(pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1403 		return -1;
1404 	if (upeek(pid, sizeof(unsigned long)*PT_R3, &result) < 0)
1405 		return -1;
1406 	if (flags & SO_MASK)
1407 		result = -result;
1408 #elif defined (M68K)
1409 	if (upeek(pid, 4*PT_D0, &d0) < 0)
1410 		return -1;
1411 	if (d0 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1412 		if (debug)
1413 			fprintf(stderr, "stray syscall exit: d0 = %ld\n", d0);
1414 		return 0;
1415 	}
1416 #elif defined (ARM)
1417 	/*
1418 	 * Nothing required
1419 	 */
1420 #elif defined (HPPA)
1421 	if (upeek(pid, PT_GR28, &r28) < 0)
1422 		return -1;
1423 #elif defined(IA64)
1424 	if (upeek(pid, PT_R10, &r10) < 0)
1425 		return -1;
1426 	if (upeek(pid, PT_R8, &r8) < 0)
1427 		return -1;
1428 	if (ia32 && r8 != -ENOSYS && !(tcp->flags & TCB_INSYSCALL)) {
1429 		if (debug)
1430 			fprintf(stderr, "stray syscall exit: r8 = %ld\n", r8);
1431 		return 0;
1432 	}
1433 #endif
1434 #endif /* LINUX */
1435 	return 1;
1436 }
1437 
1438 static int
get_error(tcp)1439 get_error(tcp)
1440 struct tcb *tcp;
1441 {
1442 	int u_error = 0;
1443 #ifdef LINUX
1444 #if defined(S390) || defined(S390X)
1445 		if (gpr2 && (unsigned) -gpr2 < nerrnos) {
1446 			tcp->u_rval = -1;
1447 			u_error = -gpr2;
1448 		}
1449 		else {
1450 			tcp->u_rval = gpr2;
1451 			u_error = 0;
1452 		}
1453 #else /* !S390 && !S390X */
1454 #ifdef I386
1455 		if (eax < 0 && -eax < nerrnos) {
1456 			tcp->u_rval = -1;
1457 			u_error = -eax;
1458 		}
1459 		else {
1460 			tcp->u_rval = eax;
1461 			u_error = 0;
1462 		}
1463 #else /* !I386 */
1464 #ifdef X86_64
1465 		if (rax < 0 && -rax < nerrnos) {
1466 			tcp->u_rval = -1;
1467 			u_error = -rax;
1468 		}
1469 		else {
1470 			tcp->u_rval = rax;
1471 			u_error = 0;
1472 		}
1473 #else
1474 #ifdef IA64
1475 		if (ia32) {
1476 			int err;
1477 
1478 			err = (int)r8;
1479 			if (err < 0 && -err < nerrnos) {
1480 				tcp->u_rval = -1;
1481 				u_error = -err;
1482 			}
1483 			else {
1484 				tcp->u_rval = err;
1485 				u_error = 0;
1486 			}
1487 		} else {
1488 			if (r10) {
1489 				tcp->u_rval = -1;
1490 				u_error = r8;
1491 			} else {
1492 				tcp->u_rval = r8;
1493 				u_error = 0;
1494 			}
1495 		}
1496 #else /* !IA64 */
1497 #ifdef MIPS
1498 		if (a3) {
1499 		  	tcp->u_rval = -1;
1500 			u_error = r2;
1501 		} else {
1502 		  	tcp->u_rval = r2;
1503 			u_error = 0;
1504 		}
1505 #else
1506 #ifdef POWERPC
1507 		if (result && (unsigned long) -result < nerrnos) {
1508 			tcp->u_rval = -1;
1509 			u_error = -result;
1510 		}
1511 		else {
1512 			tcp->u_rval = result;
1513 			u_error = 0;
1514 		}
1515 #else /* !POWERPC */
1516 #ifdef M68K
1517 		if (d0 && (unsigned) -d0 < nerrnos) {
1518 			tcp->u_rval = -1;
1519 			u_error = -d0;
1520 		}
1521 		else {
1522 			tcp->u_rval = d0;
1523 			u_error = 0;
1524 		}
1525 #else /* !M68K */
1526 #ifdef ARM
1527 		if (regs.ARM_r0 && (unsigned) -regs.ARM_r0 < nerrnos) {
1528 			tcp->u_rval = -1;
1529 			u_error = -regs.ARM_r0;
1530 		}
1531 		else {
1532 			tcp->u_rval = regs.ARM_r0;
1533 			u_error = 0;
1534 		}
1535 #else /* !ARM */
1536 #ifdef ALPHA
1537 		if (a3) {
1538 			tcp->u_rval = -1;
1539 			u_error = r0;
1540 		}
1541 		else {
1542 			tcp->u_rval = r0;
1543 			u_error = 0;
1544 		}
1545 #else /* !ALPHA */
1546 #ifdef SPARC
1547 		if (regs.r_psr & PSR_C) {
1548 			tcp->u_rval = -1;
1549 			u_error = regs.r_o0;
1550 		}
1551 		else {
1552 			tcp->u_rval = regs.r_o0;
1553 			u_error = 0;
1554 		}
1555 #else /* !SPARC */
1556 #ifdef SPARC64
1557 		if (regs.r_tstate & 0x1100000000UL) {
1558 			tcp->u_rval = -1;
1559 			u_error = regs.r_o0;
1560 		}
1561 		else {
1562 			tcp->u_rval = regs.r_o0;
1563 			u_error = 0;
1564 		}
1565 #else /* !SPARC64 */
1566 #ifdef HPPA
1567 		if (r28 && (unsigned) -r28 < nerrnos) {
1568 			tcp->u_rval = -1;
1569 			u_error = -r28;
1570 		}
1571 		else {
1572 			tcp->u_rval = r28;
1573 			u_error = 0;
1574 		}
1575 #else
1576 #ifdef SH
1577                /* interpret R0 as return value or error number */
1578                if (r0 && (unsigned) -r0 < nerrnos) {
1579                        tcp->u_rval = -1;
1580                        u_error = -r0;
1581                }
1582                else {
1583                        tcp->u_rval = r0;
1584                        u_error = 0;
1585                }
1586 #else
1587 #ifdef SH64
1588                 /* interpret result as return value or error number */
1589                 if (r9 && (unsigned) -r9 < nerrnos) {
1590 	                tcp->u_rval = -1;
1591 	                u_error = -r9;
1592                 }
1593                 else {
1594                         tcp->u_rval = r9;
1595 	                u_error = 0;
1596                 }
1597 #endif /* SH64 */
1598 #endif /* SH */
1599 #endif /* HPPA */
1600 #endif /* SPARC */
1601 #endif /* SPARC64 */
1602 #endif /* ALPHA */
1603 #endif /* ARM */
1604 #endif /* M68K */
1605 #endif /* POWERPC */
1606 #endif /* MIPS */
1607 #endif /* IA64 */
1608 #endif /* X86_64 */
1609 #endif /* I386 */
1610 #endif /* S390 || S390X */
1611 #endif /* LINUX */
1612 #ifdef SUNOS4
1613 		/* get error code from user struct */
1614 		if (upeek(pid, uoff(u_error), &u_error) < 0)
1615 			return -1;
1616 		u_error >>= 24; /* u_error is a char */
1617 
1618 		/* get system call return value */
1619 		if (upeek(pid, uoff(u_rval1), &tcp->u_rval) < 0)
1620 			return -1;
1621 #endif /* SUNOS4 */
1622 #ifdef SVR4
1623 #ifdef SPARC
1624 		/* Judicious guessing goes a long way. */
1625 		if (tcp->status.pr_reg[R_PSR] & 0x100000) {
1626 			tcp->u_rval = -1;
1627 			u_error = tcp->status.pr_reg[R_O0];
1628 		}
1629 		else {
1630 			tcp->u_rval = tcp->status.pr_reg[R_O0];
1631 			u_error = 0;
1632 		}
1633 #endif /* SPARC */
1634 #ifdef I386
1635 		/* Wanna know how to kill an hour single-stepping? */
1636 		if (tcp->status.PR_REG[EFL] & 0x1) {
1637 			tcp->u_rval = -1;
1638 			u_error = tcp->status.PR_REG[EAX];
1639 		}
1640 		else {
1641 			tcp->u_rval = tcp->status.PR_REG[EAX];
1642 #ifdef HAVE_LONG_LONG
1643 			tcp->u_lrval =
1644 				((unsigned long long) tcp->status.PR_REG[EDX] << 32) +
1645 				tcp->status.PR_REG[EAX];
1646 #endif
1647 			u_error = 0;
1648 		}
1649 #endif /* I386 */
1650 #ifdef X86_64
1651 		/* Wanna know how to kill an hour single-stepping? */
1652 		if (tcp->status.PR_REG[EFLAGS] & 0x1) {
1653 			tcp->u_rval = -1;
1654 			u_error = tcp->status.PR_REG[RAX];
1655 		}
1656 		else {
1657 			tcp->u_rval = tcp->status.PR_REG[RAX];
1658 			u_error = 0;
1659 		}
1660 #endif /* X86_64 */
1661 #ifdef MIPS
1662 		if (tcp->status.pr_reg[CTX_A3]) {
1663 			tcp->u_rval = -1;
1664 			u_error = tcp->status.pr_reg[CTX_V0];
1665 		}
1666 		else {
1667 			tcp->u_rval = tcp->status.pr_reg[CTX_V0];
1668 			u_error = 0;
1669 		}
1670 #endif /* MIPS */
1671 #endif /* SVR4 */
1672 #ifdef FREEBSD
1673 		if (regs.r_eflags & PSL_C) {
1674  		        tcp->u_rval = -1;
1675 		        u_error = regs.r_eax;
1676 		} else {
1677 		        tcp->u_rval = regs.r_eax;
1678 			tcp->u_lrval =
1679 			  ((unsigned long long) regs.r_edx << 32) +  regs.r_eax;
1680 		        u_error = 0;
1681 		}
1682 #endif /* FREEBSD */
1683 	tcp->u_error = u_error;
1684 	return 1;
1685 }
1686 
1687 int
force_result(tcp,error,rval)1688 force_result(tcp, error, rval)
1689 	struct tcb *tcp;
1690 	int error;
1691 	long rval;
1692 {
1693 #ifdef LINUX
1694 #if defined(S390) || defined(S390X)
1695 	gpr2 = error ? -error : rval;
1696 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)PT_GPR2, gpr2) < 0)
1697 		return -1;
1698 #else /* !S390 && !S390X */
1699 #ifdef I386
1700 	eax = error ? -error : rval;
1701 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(EAX * 4), eax) < 0)
1702 		return -1;
1703 #else /* !I386 */
1704 #ifdef X86_64
1705 	rax = error ? -error : rval;
1706 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(RAX * 8), rax) < 0)
1707 		return -1;
1708 #else
1709 #ifdef IA64
1710 	if (ia32) {
1711 		r8 = error ? -error : rval;
1712 		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0)
1713 			return -1;
1714 	}
1715 	else {
1716 		if (error) {
1717 			r8 = error;
1718 			r10 = -1;
1719 		}
1720 		else {
1721 			r8 = rval;
1722 			r10 = 0;
1723 		}
1724 		if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R8), r8) < 0 ||
1725 		    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_R10), r10) < 0)
1726 			return -1;
1727 	}
1728 #else /* !IA64 */
1729 #ifdef MIPS
1730 	if (error) {
1731 		r2 = error;
1732 		a3 = -1;
1733 	}
1734 	else {
1735 		r2 = rval;
1736 		a3 = 0;
1737 	}
1738 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1739 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_V0), r2) < 0)
1740 	    	return -1;
1741 #else
1742 #ifdef POWERPC
1743 	if (upeek(tcp->pid, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1744 		return -1;
1745 	if (error) {
1746 		flags |= SO_MASK;
1747 		result = error;
1748 	}
1749 	else {
1750 		flags &= ~SO_MASK;
1751 		result = rval;
1752 	}
1753 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_CCR), flags) < 0 ||
1754 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(sizeof(unsigned long)*PT_R3), result) < 0)
1755 		return -1;
1756 #else /* !POWERPC */
1757 #ifdef M68K
1758 	d0 = error ? -error : rval;
1759 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*PT_D0), d0) < 0)
1760 		return -1;
1761 #else /* !M68K */
1762 #ifdef ARM
1763        regs.ARM_r0 = error ? -error : rval;
1764        if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*0), regs.ARM_r0) < 0)
1765 		return -1;
1766 #else /* !ARM */
1767 #ifdef ALPHA
1768 	if (error) {
1769 		a3 = -1;
1770 		r0 = error;
1771 	}
1772 	else {
1773 		a3 = 0;
1774 		r0 = rval;
1775 	}
1776 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_A3), a3) < 0 ||
1777 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(REG_R0), r0) < 0)
1778 		return -1;
1779 #else /* !ALPHA */
1780 #ifdef SPARC
1781 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
1782 		return -1;
1783 	if (error) {
1784 		regs.r_psr |= PSR_C;
1785 		regs.r_o0 = error;
1786 	}
1787 	else {
1788 		regs.r_psr &= ~PSR_C;
1789 		regs.r_o0 = rval;
1790 	}
1791 	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
1792 		return -1;
1793 #else /* !SPARC */
1794 #ifdef SPARC64
1795 	if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)&regs, 0) < 0)
1796 		return -1;
1797 	if (error) {
1798 		regs.r_tstate |= 0x1100000000UL;
1799 		regs.r_o0 = error;
1800 	}
1801 	else {
1802 		regs.r_tstate &= ~0x1100000000UL;
1803 		regs.r_o0 = rval;
1804 	}
1805 	if (ptrace(PTRACE_SETREGS, tcp->pid, (char *)&regs, 0) < 0)
1806 		return -1;
1807 #else /* !SPARC64 */
1808 #ifdef HPPA
1809 	r28 = error ? -error : rval;
1810 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(PT_GR28), r28) < 0)
1811 		return -1;
1812 #else
1813 #ifdef SH
1814 	r0 = error ? -error : rval;
1815 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)(4*REG_REG0), r0) < 0)
1816 		return -1;
1817 #else
1818 #ifdef SH64
1819         r9 = error ? -error : rval;
1820 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)REG_GENERAL(9), r9) < 0)
1821 		return -1;
1822 #endif /* SH64 */
1823 #endif /* SH */
1824 #endif /* HPPA */
1825 #endif /* SPARC */
1826 #endif /* SPARC64 */
1827 #endif /* ALPHA */
1828 #endif /* ARM */
1829 #endif /* M68K */
1830 #endif /* POWERPC */
1831 #endif /* MIPS */
1832 #endif /* IA64 */
1833 #endif /* X86_64 */
1834 #endif /* I386 */
1835 #endif /* S390 || S390X */
1836 #endif /* LINUX */
1837 #ifdef SUNOS4
1838 	if (ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_error),
1839 		   error << 24) < 0 ||
1840 	    ptrace(PTRACE_POKEUSER, tcp->pid, (char*)uoff(u_rval1), rval) < 0)
1841 		return -1;
1842 #endif /* SUNOS4 */
1843 #ifdef SVR4
1844 	/* XXX no clue */
1845 	return -1;
1846 #endif /* SVR4 */
1847 #ifdef FREEBSD
1848 	if (pread(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1849 	        perror("pread");
1850                 return -1;
1851         }
1852 	if (error) {
1853 		regs.r_eflags |= PSL_C;
1854 		regs.r_eax = error;
1855 	}
1856 	else {
1857 		regs.r_eflags &= ~PSL_C;
1858 		regs.r_eax = rval;
1859 	}
1860 	if (pwrite(tcp->pfd_reg, &regs, sizeof(regs), 0) < 0) {
1861 	        perror("pwrite");
1862                 return -1;
1863         }
1864 #endif /* FREEBSD */
1865 
1866 	/* All branches reach here on success (only).  */
1867 	tcp->u_error = error;
1868 	tcp->u_rval = rval;
1869 	return 0;
1870 }
1871 
1872 static int
syscall_enter(tcp)1873 syscall_enter(tcp)
1874 struct tcb *tcp;
1875 {
1876 #ifndef USE_PROCFS
1877 	int pid = tcp->pid;
1878 #endif /* !USE_PROCFS */
1879 #ifdef LINUX
1880 #if defined(S390) || defined(S390X)
1881 	{
1882 		int i;
1883 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1884 			tcp->u_nargs = sysent[tcp->scno].nargs;
1885 		else
1886      	        	tcp->u_nargs = MAX_ARGS;
1887 		for (i = 0; i < tcp->u_nargs; i++) {
1888 			if (upeek(pid,i==0 ? PT_ORIGGPR2:PT_GPR2+i*sizeof(long), &tcp->u_arg[i]) < 0)
1889 				return -1;
1890 		}
1891 	}
1892 #elif defined (ALPHA)
1893 	{
1894 		int i;
1895 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1896 			tcp->u_nargs = sysent[tcp->scno].nargs;
1897 		else
1898      	        	tcp->u_nargs = MAX_ARGS;
1899 		for (i = 0; i < tcp->u_nargs; i++) {
1900 			/* WTA: if scno is out-of-bounds this will bomb. Add range-check
1901 			 * for scno somewhere above here!
1902 			 */
1903 			if (upeek(pid, REG_A0+i, &tcp->u_arg[i]) < 0)
1904 				return -1;
1905 		}
1906 	}
1907 #elif defined (IA64)
1908 	{
1909 		if (!ia32) {
1910 			unsigned long *out0, *rbs_end, cfm, sof, sol, i;
1911 			/* be backwards compatible with kernel < 2.4.4... */
1912 #			ifndef PT_RBS_END
1913 #			  define PT_RBS_END	PT_AR_BSP
1914 #			endif
1915 
1916 			if (upeek(pid, PT_RBS_END, (long *) &rbs_end) < 0)
1917 				return -1;
1918 			if (upeek(pid, PT_CFM, (long *) &cfm) < 0)
1919 				return -1;
1920 
1921 			sof = (cfm >> 0) & 0x7f;
1922 			sol = (cfm >> 7) & 0x7f;
1923 			out0 = ia64_rse_skip_regs(rbs_end, -sof + sol);
1924 
1925 			if (tcp->scno >= 0 && tcp->scno < nsyscalls
1926 			    && sysent[tcp->scno].nargs != -1)
1927 				tcp->u_nargs = sysent[tcp->scno].nargs;
1928 			else
1929 				tcp->u_nargs = MAX_ARGS;
1930 			for (i = 0; i < tcp->u_nargs; ++i) {
1931 				if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i),
1932 					   sizeof(long), (char *) &tcp->u_arg[i]) < 0)
1933 					return -1;
1934 			}
1935 		} else {
1936 			int i;
1937 
1938 			if (/* EBX = out0 */
1939 			    upeek(pid, PT_R11, (long *) &tcp->u_arg[0]) < 0
1940 			    /* ECX = out1 */
1941 			    || upeek(pid, PT_R9,  (long *) &tcp->u_arg[1]) < 0
1942 			    /* EDX = out2 */
1943 			    || upeek(pid, PT_R10, (long *) &tcp->u_arg[2]) < 0
1944 			    /* ESI = out3 */
1945 			    || upeek(pid, PT_R14, (long *) &tcp->u_arg[3]) < 0
1946 			    /* EDI = out4 */
1947 			    || upeek(pid, PT_R15, (long *) &tcp->u_arg[4]) < 0
1948 			    /* EBP = out5 */
1949 			    || upeek(pid, PT_R13, (long *) &tcp->u_arg[5]) < 0)
1950 				return -1;
1951 
1952 			for (i = 0; i < 6; ++i)
1953 				/* truncate away IVE sign-extension */
1954 				tcp->u_arg[i] &= 0xffffffff;
1955 
1956 			if (tcp->scno >= 0 && tcp->scno < nsyscalls
1957 			    && sysent[tcp->scno].nargs != -1)
1958 				tcp->u_nargs = sysent[tcp->scno].nargs;
1959 			else
1960 				tcp->u_nargs = 5;
1961 		}
1962 	}
1963 #elif defined (MIPS)
1964 	{
1965 	  	long sp;
1966 	  	int i, nargs;
1967 
1968 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1969 			nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
1970 		else
1971      	        	nargs = tcp->u_nargs = MAX_ARGS;
1972 		if(nargs > 4) {
1973 		  	if(upeek(pid, REG_SP, &sp) < 0)
1974 			  	return -1;
1975 			for(i = 0; i < 4; i++) {
1976 			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i])<0)
1977 				  	return -1;
1978 			}
1979 			umoven(tcp, sp+16, (nargs-4) * sizeof(tcp->u_arg[0]),
1980 			       (char *)(tcp->u_arg + 4));
1981 		} else {
1982 		  	for(i = 0; i < nargs; i++) {
1983 			  	if (upeek(pid, REG_A0 + i, &tcp->u_arg[i]) < 0)
1984 				  	return -1;
1985 			}
1986 		}
1987 	}
1988 #elif defined (POWERPC)
1989 #ifndef PT_ORIG_R3
1990 #define PT_ORIG_R3 34
1991 #endif
1992 	{
1993 		int i;
1994 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
1995 			tcp->u_nargs = sysent[tcp->scno].nargs;
1996 		else
1997      	        	tcp->u_nargs = MAX_ARGS;
1998 		for (i = 0; i < tcp->u_nargs; i++) {
1999 			if (upeek(pid, (i==0) ?
2000 				(sizeof(unsigned long)*PT_ORIG_R3) :
2001 				((i+PT_R3)*sizeof(unsigned long)),
2002 					&tcp->u_arg[i]) < 0)
2003 				return -1;
2004 		}
2005 	}
2006 #elif defined (SPARC) || defined (SPARC64)
2007 	{
2008 		int i;
2009 
2010 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2011 			tcp->u_nargs = sysent[tcp->scno].nargs;
2012 		else
2013      	        	tcp->u_nargs = MAX_ARGS;
2014 		for (i = 0; i < tcp->u_nargs; i++)
2015 			tcp->u_arg[i] = *((&regs.r_o0) + i);
2016 	}
2017 #elif defined (HPPA)
2018 	{
2019 		int i;
2020 
2021 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2022 			tcp->u_nargs = sysent[tcp->scno].nargs;
2023 		else
2024      	        	tcp->u_nargs = MAX_ARGS;
2025 		for (i = 0; i < tcp->u_nargs; i++) {
2026 			if (upeek(pid, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
2027 				return -1;
2028 		}
2029 	}
2030 #elif defined(ARM)
2031 	{
2032 		int i;
2033 
2034 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2035 			tcp->u_nargs = sysent[tcp->scno].nargs;
2036 		else
2037 			tcp->u_nargs = MAX_ARGS;
2038 		for (i = 0; i < tcp->u_nargs; i++)
2039 			tcp->u_arg[i] = regs.uregs[i];
2040  	}
2041 #elif defined(SH)
2042        {
2043                int i;
2044                static int syscall_regs[] = {
2045                    REG_REG0+4, REG_REG0+5, REG_REG0+6, REG_REG0+7,
2046                    REG_REG0, REG_REG0+1, REG_REG0+2
2047                    };
2048 
2049                tcp->u_nargs = sysent[tcp->scno].nargs;
2050                for (i = 0; i < tcp->u_nargs; i++) {
2051                        if (upeek(pid, 4*syscall_regs[i], &tcp->u_arg[i]) < 0)
2052                                return -1;
2053                }
2054         }
2055 #elif defined(SH64)
2056 	{
2057 		int i;
2058                 /* Registers used by SH5 Linux system calls for parameters */
2059 		static int syscall_regs[] = { 2, 3, 4, 5, 6, 7 };
2060 
2061 		/*
2062 		 * TODO: should also check that the number of arguments encoded
2063 		 *       in the trap number matches the number strace expects.
2064 		 */
2065 		/*
2066 		    assert(sysent[tcp->scno].nargs <
2067 		    	sizeof(syscall_regs)/sizeof(syscall_regs[0]));
2068 		 */
2069 
2070 		tcp->u_nargs = sysent[tcp->scno].nargs;
2071 		for (i = 0; i < tcp->u_nargs; i++) {
2072 			if (upeek(pid, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
2073 				return -1;
2074 		}
2075 	}
2076 
2077 #elif defined(X86_64)
2078 	{
2079 		int i;
2080 		static int argreg[SUPPORTED_PERSONALITIES][MAX_ARGS] = {
2081 			{RDI,RSI,RDX,R10,R8,R9},	/* x86-64 ABI */
2082 			{RBX,RCX,RDX,RSI,RDI,RBP}	/* i386 ABI */
2083 		};
2084 
2085 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2086 			tcp->u_nargs = sysent[tcp->scno].nargs;
2087 		else
2088      	        	tcp->u_nargs = MAX_ARGS;
2089 		for (i = 0; i < tcp->u_nargs; i++) {
2090 			if (upeek(pid, argreg[current_personality][i]*8, &tcp->u_arg[i]) < 0)
2091 				return -1;
2092 		}
2093 	}
2094 #else /* Other architecture (like i386) (32bits specific) */
2095 	{
2096 		int i;
2097 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2098 			tcp->u_nargs = sysent[tcp->scno].nargs;
2099 		else
2100      	        	tcp->u_nargs = MAX_ARGS;
2101 		for (i = 0; i < tcp->u_nargs; i++) {
2102 			if (upeek(pid, i*4, &tcp->u_arg[i]) < 0)
2103 				return -1;
2104 		}
2105 	}
2106 #endif
2107 #endif /* LINUX */
2108 #ifdef SUNOS4
2109 	{
2110 		int i;
2111 		if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2112 			tcp->u_nargs = sysent[tcp->scno].nargs;
2113 		else
2114      	        	tcp->u_nargs = MAX_ARGS;
2115 		for (i = 0; i < tcp->u_nargs; i++) {
2116 			struct user *u;
2117 
2118 			if (upeek(pid, uoff(u_arg[0]) +
2119 			    (i*sizeof(u->u_arg[0])), &tcp->u_arg[i]) < 0)
2120 				return -1;
2121 		}
2122 	}
2123 #endif /* SUNOS4 */
2124 #ifdef SVR4
2125 #ifdef MIPS
2126 	/*
2127 	 * SGI is broken: even though it has pr_sysarg, it doesn't
2128 	 * set them on system call entry.  Get a clue.
2129 	 */
2130 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2131 		tcp->u_nargs = sysent[tcp->scno].nargs;
2132 	else
2133 		tcp->u_nargs = tcp->status.pr_nsysarg;
2134 	if (tcp->u_nargs > 4) {
2135 		memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2136 			4*sizeof(tcp->u_arg[0]));
2137 		umoven(tcp, tcp->status.pr_reg[CTX_SP] + 16,
2138 			(tcp->u_nargs - 4)*sizeof(tcp->u_arg[0]), (char *) (tcp->u_arg + 4));
2139 	}
2140 	else {
2141 		memcpy(tcp->u_arg, &tcp->status.pr_reg[CTX_A0],
2142 			tcp->u_nargs*sizeof(tcp->u_arg[0]));
2143 	}
2144 #elif UNIXWARE >= 2
2145 	/*
2146 	 * Like SGI, UnixWare doesn't set pr_sysarg until system call exit
2147 	 */
2148 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2149 		tcp->u_nargs = sysent[tcp->scno].nargs;
2150 	else
2151 		tcp->u_nargs = tcp->status.pr_lwp.pr_nsysarg;
2152 	umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2153 		tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2154 #elif defined (HAVE_PR_SYSCALL)
2155 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2156 		tcp->u_nargs = sysent[tcp->scno].nargs;
2157 	else
2158 		tcp->u_nargs = tcp->status.pr_nsysarg;
2159 	{
2160 		int i;
2161 		for (i = 0; i < tcp->u_nargs; i++)
2162 			tcp->u_arg[i] = tcp->status.pr_sysarg[i];
2163 	}
2164 #elif defined (I386)
2165 	if (tcp->scno >= 0 && tcp->scno < nsyscalls && sysent[tcp->scno].nargs != -1)
2166 		tcp->u_nargs = sysent[tcp->scno].nargs;
2167 	else
2168 		tcp->u_nargs = 5;
2169 	umoven(tcp, tcp->status.PR_REG[UESP] + 4,
2170 		tcp->u_nargs*sizeof(tcp->u_arg[0]), (char *) tcp->u_arg);
2171 #else
2172 	I DONT KNOW WHAT TO DO
2173 #endif /* !HAVE_PR_SYSCALL */
2174 #endif /* SVR4 */
2175 #ifdef FREEBSD
2176 	if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2177 	    sysent[tcp->scno].nargs > tcp->status.val)
2178 		tcp->u_nargs = sysent[tcp->scno].nargs;
2179 	else
2180 	  	tcp->u_nargs = tcp->status.val;
2181 	if (tcp->u_nargs < 0)
2182 		tcp->u_nargs = 0;
2183 	if (tcp->u_nargs > MAX_ARGS)
2184 		tcp->u_nargs = MAX_ARGS;
2185 	switch(regs.r_eax) {
2186 	case SYS___syscall:
2187 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2188 		      regs.r_esp + sizeof(int) + sizeof(quad_t));
2189 	  break;
2190         case SYS_syscall:
2191 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2192 		      regs.r_esp + 2 * sizeof(int));
2193 	  break;
2194         default:
2195 		pread(tcp->pfd, &tcp->u_arg, tcp->u_nargs * sizeof(unsigned long),
2196 		      regs.r_esp + sizeof(int));
2197 	  break;
2198 	}
2199 #endif /* FREEBSD */
2200 	return 1;
2201 }
2202 
2203 int
trace_syscall(tcp)2204 trace_syscall(tcp)
2205 struct tcb *tcp;
2206 {
2207 	int sys_res;
2208 	struct timeval tv;
2209 	int res;
2210 
2211 	/* Measure the exit time as early as possible to avoid errors. */
2212 	if (dtime && (tcp->flags & TCB_INSYSCALL))
2213 		gettimeofday(&tv, NULL);
2214 
2215 	res = get_scno(tcp);
2216 	if (res != 1)
2217 		return res;
2218 
2219 	res = syscall_fixup(tcp);
2220 	if (res != 1)
2221 		return res;
2222 
2223 	if (tcp->flags & TCB_INSYSCALL) {
2224 		long u_error;
2225 		res = get_error(tcp);
2226 		if (res != 1)
2227 			return res;
2228 
2229 		internal_syscall(tcp);
2230 		if (tcp->scno >= 0 && tcp->scno < nsyscalls &&
2231 		    !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2232 			tcp->flags &= ~TCB_INSYSCALL;
2233 			return 0;
2234 		}
2235 
2236 		if (tcp->flags & TCB_REPRINT) {
2237 			printleader(tcp);
2238 			tprintf("<... ");
2239 			if (tcp->scno >= nsyscalls || tcp->scno < 0)
2240 				tprintf("syscall_%lu", tcp->scno);
2241 			else
2242 				tprintf("%s", sysent[tcp->scno].sys_name);
2243 			tprintf(" resumed> ");
2244 		}
2245 
2246 		if (cflag && tcp->scno < nsyscalls && tcp->scno >= 0) {
2247 			if (counts == NULL) {
2248 				counts = calloc(sizeof *counts, nsyscalls);
2249 				if (counts == NULL) {
2250 					fprintf(stderr, "\
2251 strace: out of memory for call counts\n");
2252 					exit(1);
2253 				}
2254 			}
2255 
2256 			counts[tcp->scno].calls++;
2257 			if (tcp->u_error)
2258 				counts[tcp->scno].errors++;
2259 			tv_sub(&tv, &tv, &tcp->etime);
2260 #ifndef HAVE_ANDROID_OS
2261 #ifdef LINUX
2262 			if (tv_cmp(&tv, &tcp->dtime) > 0) {
2263 				static struct timeval one_tick;
2264 				if (one_tick.tv_usec == 0) {
2265 					/* Initialize it.  */
2266 					struct itimerval it;
2267 					memset(&it, 0, sizeof it);
2268 					it.it_interval.tv_usec = 1;
2269 					setitimer(ITIMER_REAL, &it, NULL);
2270 					getitimer(ITIMER_REAL, &it);
2271 					one_tick = it.it_interval;
2272 				}
2273 
2274 				if (tv_nz(&tcp->dtime))
2275 					tv = tcp->dtime;
2276 				else if (tv_cmp(&tv, &one_tick) > 0) {
2277 					if (tv_cmp(&shortest, &one_tick) < 0)
2278 						tv = shortest;
2279 					else
2280 						tv = one_tick;
2281 				}
2282 			}
2283 #endif /* LINUX */
2284 #endif
2285 			if (tv_cmp(&tv, &shortest) < 0)
2286 				shortest = tv;
2287 			tv_add(&counts[tcp->scno].time,
2288 				&counts[tcp->scno].time, &tv);
2289 			tcp->flags &= ~TCB_INSYSCALL;
2290 			return 0;
2291 		}
2292 
2293 		if (tcp->scno >= nsyscalls || tcp->scno < 0
2294 		    || (qual_flags[tcp->scno] & QUAL_RAW))
2295 			sys_res = printargs(tcp);
2296 		else {
2297 			if (not_failing_only && tcp->u_error)
2298 				return 0;	/* ignore failed syscalls */
2299 			sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2300 		}
2301 		u_error = tcp->u_error;
2302 		tprintf(") ");
2303 		tabto(acolumn);
2304 		if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2305 		    qual_flags[tcp->scno] & QUAL_RAW) {
2306 			if (u_error)
2307 				tprintf("= -1 (errno %ld)", u_error);
2308 			else
2309 				tprintf("= %#lx", tcp->u_rval);
2310 		}
2311 		else if (!(sys_res & RVAL_NONE) && u_error) {
2312 			switch (u_error) {
2313 #ifdef LINUX
2314 			case ERESTARTSYS:
2315 				tprintf("= ? ERESTARTSYS (To be restarted)");
2316 				break;
2317 			case ERESTARTNOINTR:
2318 				tprintf("= ? ERESTARTNOINTR (To be restarted)");
2319 				break;
2320 			case ERESTARTNOHAND:
2321 				tprintf("= ? ERESTARTNOHAND (To be restarted)");
2322 				break;
2323 			case ERESTART_RESTARTBLOCK:
2324 				tprintf("= ? ERESTART_RESTARTBLOCK (To be restarted)");
2325 				break;
2326 #endif /* LINUX */
2327 			default:
2328 				tprintf("= -1 ");
2329 				if (u_error < 0)
2330 					tprintf("E??? (errno %ld)", u_error);
2331 				else if (u_error < nerrnos)
2332 					tprintf("%s (%s)", errnoent[u_error],
2333 						strerror(u_error));
2334 				else
2335 					tprintf("ERRNO_%ld (%s)", u_error,
2336 						strerror(u_error));
2337 				break;
2338 			}
2339 		}
2340 		else {
2341 			if (sys_res & RVAL_NONE)
2342 				tprintf("= ?");
2343 			else {
2344 				switch (sys_res & RVAL_MASK) {
2345 				case RVAL_HEX:
2346 					tprintf("= %#lx", tcp->u_rval);
2347 					break;
2348 				case RVAL_OCTAL:
2349 					tprintf("= %#lo", tcp->u_rval);
2350 					break;
2351 				case RVAL_UDECIMAL:
2352 					tprintf("= %lu", tcp->u_rval);
2353 					break;
2354 				case RVAL_DECIMAL:
2355 					tprintf("= %ld", tcp->u_rval);
2356 					break;
2357 #ifdef HAVE_LONG_LONG
2358 				case RVAL_LHEX:
2359 					tprintf("= %#llx", tcp->u_lrval);
2360 					break;
2361 				case RVAL_LOCTAL:
2362 					tprintf("= %#llo", tcp->u_lrval);
2363 					break;
2364 				case RVAL_LUDECIMAL:
2365 					tprintf("= %llu", tcp->u_lrval);
2366 					break;
2367 				case RVAL_LDECIMAL:
2368 					tprintf("= %lld", tcp->u_lrval);
2369 					break;
2370 #endif
2371 				default:
2372 					fprintf(stderr,
2373 						"invalid rval format\n");
2374 					break;
2375 				}
2376 			}
2377 			if ((sys_res & RVAL_STR) && tcp->auxstr)
2378 				tprintf(" (%s)", tcp->auxstr);
2379 		}
2380 		if (dtime) {
2381 			tv_sub(&tv, &tv, &tcp->etime);
2382 			tprintf(" <%ld.%06ld>",
2383 				(long) tv.tv_sec, (long) tv.tv_usec);
2384 		}
2385 		printtrailer(tcp);
2386 
2387 		dumpio(tcp);
2388 		if (fflush(tcp->outf) == EOF)
2389 			return -1;
2390 		tcp->flags &= ~TCB_INSYSCALL;
2391 		return 0;
2392 	}
2393 
2394 	/* Entering system call */
2395 	res = syscall_enter(tcp);
2396 	if (res != 1)
2397 		return res;
2398 
2399 	switch (known_scno(tcp)) {
2400 #ifdef LINUX
2401 #if !defined (ALPHA) && !defined(SPARC) && !defined(SPARC64) && !defined(MIPS) && !defined(HPPA) && !defined(__ARM_EABI__) //ANDROID
2402 	case SYS_socketcall:
2403 		decode_subcall(tcp, SYS_socket_subcall,
2404 			SYS_socket_nsubcalls, deref_style);
2405 		break;
2406 	case SYS_ipc:
2407 		decode_subcall(tcp, SYS_ipc_subcall,
2408 			SYS_ipc_nsubcalls, shift_style);
2409 		break;
2410 #endif /* !ALPHA && !MIPS && !SPARC && !SPARC64 && !HPPA */
2411 #if defined (SPARC) || defined (SPARC64)
2412 	case SYS_socketcall:
2413 		sparc_socket_decode (tcp);
2414 		break;
2415 #endif
2416 #endif /* LINUX */
2417 #ifdef SVR4
2418 #ifdef SYS_pgrpsys_subcall
2419 	case SYS_pgrpsys:
2420 		decode_subcall(tcp, SYS_pgrpsys_subcall,
2421 			SYS_pgrpsys_nsubcalls, shift_style);
2422 		break;
2423 #endif /* SYS_pgrpsys_subcall */
2424 #ifdef SYS_sigcall_subcall
2425 	case SYS_sigcall:
2426 		decode_subcall(tcp, SYS_sigcall_subcall,
2427 			SYS_sigcall_nsubcalls, mask_style);
2428 		break;
2429 #endif /* SYS_sigcall_subcall */
2430 	case SYS_msgsys:
2431 		decode_subcall(tcp, SYS_msgsys_subcall,
2432 			SYS_msgsys_nsubcalls, shift_style);
2433 		break;
2434 	case SYS_shmsys:
2435 		decode_subcall(tcp, SYS_shmsys_subcall,
2436 			SYS_shmsys_nsubcalls, shift_style);
2437 		break;
2438 	case SYS_semsys:
2439 		decode_subcall(tcp, SYS_semsys_subcall,
2440 			SYS_semsys_nsubcalls, shift_style);
2441 		break;
2442 #if 0 /* broken */
2443 	case SYS_utssys:
2444 		decode_subcall(tcp, SYS_utssys_subcall,
2445 			SYS_utssys_nsubcalls, shift_style);
2446 		break;
2447 #endif
2448 	case SYS_sysfs:
2449 		decode_subcall(tcp, SYS_sysfs_subcall,
2450 			SYS_sysfs_nsubcalls, shift_style);
2451 		break;
2452 	case SYS_spcall:
2453 		decode_subcall(tcp, SYS_spcall_subcall,
2454 			SYS_spcall_nsubcalls, shift_style);
2455 		break;
2456 #ifdef SYS_context_subcall
2457 	case SYS_context:
2458 		decode_subcall(tcp, SYS_context_subcall,
2459 			SYS_context_nsubcalls, shift_style);
2460 		break;
2461 #endif /* SYS_context_subcall */
2462 #ifdef SYS_door_subcall
2463 	case SYS_door:
2464 		decode_subcall(tcp, SYS_door_subcall,
2465 			SYS_door_nsubcalls, door_style);
2466 		break;
2467 #endif /* SYS_door_subcall */
2468 #ifdef SYS_kaio_subcall
2469 	case SYS_kaio:
2470 		decode_subcall(tcp, SYS_kaio_subcall,
2471 			SYS_kaio_nsubcalls, shift_style);
2472 		break;
2473 #endif
2474 #endif /* SVR4 */
2475 #ifdef FREEBSD
2476 	case SYS_msgsys:
2477 	case SYS_shmsys:
2478 	case SYS_semsys:
2479 		decode_subcall(tcp, 0, 0, table_style);
2480 		break;
2481 #endif
2482 #ifdef SUNOS4
2483 	case SYS_semsys:
2484 		decode_subcall(tcp, SYS_semsys_subcall,
2485 			SYS_semsys_nsubcalls, shift_style);
2486 		break;
2487 	case SYS_msgsys:
2488 		decode_subcall(tcp, SYS_msgsys_subcall,
2489 			SYS_msgsys_nsubcalls, shift_style);
2490 		break;
2491 	case SYS_shmsys:
2492 		decode_subcall(tcp, SYS_shmsys_subcall,
2493 			SYS_shmsys_nsubcalls, shift_style);
2494 		break;
2495 #endif
2496 	}
2497 
2498 	internal_syscall(tcp);
2499 	if (tcp->scno >=0 && tcp->scno < nsyscalls && !(qual_flags[tcp->scno] & QUAL_TRACE)) {
2500 		tcp->flags |= TCB_INSYSCALL;
2501 		return 0;
2502 	}
2503 
2504 	if (cflag) {
2505 		gettimeofday(&tcp->etime, NULL);
2506 		tcp->flags |= TCB_INSYSCALL;
2507 		return 0;
2508 	}
2509 
2510 	printleader(tcp);
2511 	tcp->flags &= ~TCB_REPRINT;
2512 	tcp_last = tcp;
2513 	if (tcp->scno >= nsyscalls || tcp->scno < 0)
2514 		tprintf("syscall_%lu(", tcp->scno);
2515 	else
2516 		tprintf("%s(", sysent[tcp->scno].sys_name);
2517 	if (tcp->scno >= nsyscalls || tcp->scno < 0 ||
2518 	    ((qual_flags[tcp->scno] & QUAL_RAW) && tcp->scno != SYS_exit))
2519 		sys_res = printargs(tcp);
2520 	else
2521 		sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2522 	if (fflush(tcp->outf) == EOF)
2523 		return -1;
2524 	tcp->flags |= TCB_INSYSCALL;
2525 	/* Measure the entrance time as late as possible to avoid errors. */
2526 	if (dtime)
2527 		gettimeofday(&tcp->etime, NULL);
2528 	return sys_res;
2529 }
2530 
2531 int
printargs(tcp)2532 printargs(tcp)
2533 struct tcb *tcp;
2534 {
2535 	if (entering(tcp)) {
2536 		int i;
2537 
2538 		for (i = 0; i < tcp->u_nargs; i++)
2539 			tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
2540 	}
2541 	return 0;
2542 }
2543 
2544 long
getrval2(tcp)2545 getrval2(tcp)
2546 struct tcb *tcp;
2547 {
2548 	long val = -1;
2549 
2550 #ifdef LINUX
2551 #if defined (SPARC) || defined (SPARC64)
2552 	struct regs regs;
2553 	if (ptrace(PTRACE_GETREGS,tcp->pid,(char *)&regs,0) < 0)
2554 		return -1;
2555 	val = regs.r_o1;
2556 #elif defined(SH)
2557 	if (upeek(tcp->pid, 4*(REG_REG0+1), &val) < 0)
2558 		return -1;
2559 #elif defined(IA64)
2560 	if (upeek(tcp->pid, PT_R9, &val) < 0)
2561 		return -1;
2562 #endif /* SPARC || SPARC64 */
2563 #endif /* LINUX */
2564 
2565 #ifdef SUNOS4
2566 	if (upeek(tcp->pid, uoff(u_rval2), &val) < 0)
2567 		return -1;
2568 #endif /* SUNOS4 */
2569 
2570 #ifdef SVR4
2571 #ifdef SPARC
2572 	val = tcp->status.PR_REG[R_O1];
2573 #endif /* SPARC */
2574 #ifdef I386
2575 	val = tcp->status.PR_REG[EDX];
2576 #endif /* I386 */
2577 #ifdef X86_64
2578 	val = tcp->status.PR_REG[RDX];
2579 #endif /* X86_64 */
2580 #ifdef MIPS
2581 	val = tcp->status.PR_REG[CTX_V1];
2582 #endif /* MIPS */
2583 #endif /* SVR4 */
2584 #ifdef FREEBSD
2585 	struct reg regs;
2586 	pread(tcp->pfd_reg, &regs, sizeof(regs), 0);
2587 	val = regs.r_edx;
2588 #endif
2589 	return val;
2590 }
2591 
2592 /*
2593  * Apparently, indirect system calls have already be converted by ptrace(2),
2594  * so if you see "indir" this program has gone astray.
2595  */
2596 int
sys_indir(tcp)2597 sys_indir(tcp)
2598 struct tcb *tcp;
2599 {
2600 	int i, scno, nargs;
2601 
2602 	if (entering(tcp)) {
2603 		if ((scno = tcp->u_arg[0]) > nsyscalls) {
2604 			fprintf(stderr, "Bogus syscall: %u\n", scno);
2605 			return 0;
2606 		}
2607 		nargs = sysent[scno].nargs;
2608 		tprintf("%s", sysent[scno].sys_name);
2609 		for (i = 0; i < nargs; i++)
2610 			tprintf(", %#lx", tcp->u_arg[i+1]);
2611 	}
2612 	return 0;
2613 }
2614 
2615 static int
time_cmp(a,b)2616 time_cmp(a, b)
2617 void *a;
2618 void *b;
2619 {
2620 	return -tv_cmp(&counts[*((int *) a)].time, &counts[*((int *) b)].time);
2621 }
2622 
2623 static int
syscall_cmp(a,b)2624 syscall_cmp(a, b)
2625 void *a;
2626 void *b;
2627 {
2628 	return strcmp(sysent[*((int *) a)].sys_name,
2629 		sysent[*((int *) b)].sys_name);
2630 }
2631 
2632 static int
count_cmp(a,b)2633 count_cmp(a, b)
2634 void *a;
2635 void *b;
2636 {
2637 	int m = counts[*((int *) a)].calls, n = counts[*((int *) b)].calls;
2638 
2639 	return (m < n) ? 1 : (m > n) ? -1 : 0;
2640 }
2641 
2642 static int (*sortfun)();
2643 static struct timeval overhead = { -1, -1 };
2644 
2645 void
set_sortby(sortby)2646 set_sortby(sortby)
2647 char *sortby;
2648 {
2649 	if (strcmp(sortby, "time") == 0)
2650 		sortfun = time_cmp;
2651 	else if (strcmp(sortby, "calls") == 0)
2652 		sortfun = count_cmp;
2653 	else if (strcmp(sortby, "name") == 0)
2654 		sortfun = syscall_cmp;
2655 	else if (strcmp(sortby, "nothing") == 0)
2656 		sortfun = NULL;
2657 	else {
2658 		fprintf(stderr, "invalid sortby: `%s'\n", sortby);
2659 		exit(1);
2660 	}
2661 }
2662 
set_overhead(n)2663 void set_overhead(n)
2664 int n;
2665 {
2666 	overhead.tv_sec = n / 1000000;
2667 	overhead.tv_usec = n % 1000000;
2668 }
2669 
2670 void
call_summary(outf)2671 call_summary(outf)
2672 FILE *outf;
2673 {
2674 	int i, j;
2675 	int call_cum, error_cum;
2676 	struct timeval tv_cum, dtv;
2677 	double percent;
2678 	char *dashes = "-------------------------";
2679 	char error_str[16];
2680 
2681 	int *sorted_count = malloc(nsyscalls * sizeof(int));
2682 
2683 	call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
2684 	if (overhead.tv_sec == -1) {
2685 		tv_mul(&overhead, &shortest, 8);
2686 		tv_div(&overhead, &overhead, 10);
2687 	}
2688 	for (i = 0; i < nsyscalls; i++) {
2689 		sorted_count[i] = i;
2690 		if (counts == NULL || counts[i].calls == 0)
2691 			continue;
2692 		tv_mul(&dtv, &overhead, counts[i].calls);
2693 		tv_sub(&counts[i].time, &counts[i].time, &dtv);
2694 		call_cum += counts[i].calls;
2695 		error_cum += counts[i].errors;
2696 		tv_add(&tv_cum, &tv_cum, &counts[i].time);
2697 	}
2698 	if (counts && sortfun)
2699 		qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
2700 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
2701 		"% time", "seconds", "usecs/call",
2702 		"calls", "errors", "syscall");
2703 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
2704 		dashes, dashes, dashes, dashes, dashes, dashes);
2705 	if (counts) {
2706 		for (i = 0; i < nsyscalls; i++) {
2707 			j = sorted_count[i];
2708 			if (counts[j].calls == 0)
2709 				continue;
2710 			tv_div(&dtv, &counts[j].time, counts[j].calls);
2711 			if (counts[j].errors)
2712 				sprintf(error_str, "%d", counts[j].errors);
2713 			else
2714 				error_str[0] = '\0';
2715 			percent = (100.0 * tv_float(&counts[j].time)
2716 				   / tv_float(&tv_cum));
2717 			fprintf(outf, "%6.2f %4ld.%06ld %11ld %9d %9.9s %s\n",
2718 				percent, (long) counts[j].time.tv_sec,
2719 				(long) counts[j].time.tv_usec,
2720 				(long) 1000000 * dtv.tv_sec + dtv.tv_usec,
2721 				counts[j].calls,
2722 				error_str, sysent[j].sys_name);
2723 		}
2724 	}
2725 	free(sorted_count);
2726 
2727 	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %-16.16s\n",
2728 		dashes, dashes, dashes, dashes, dashes, dashes);
2729 	if (error_cum)
2730 		sprintf(error_str, "%d", error_cum);
2731 	else
2732 		error_str[0] = '\0';
2733 	fprintf(outf, "%6.6s %4ld.%06ld %11.11s %9d %9.9s %s\n",
2734 		"100.00", (long) tv_cum.tv_sec, (long) tv_cum.tv_usec, "",
2735 		call_cum, error_str, "total");
2736 
2737 }
2738