syscall.c revision 4bdb6bb7346de8577402d73e71616e8632269261
123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/* 223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Linux for s390 port by D.J. Barrow 823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> 923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * All rights reserved. 1023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * 1123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 1223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * modification, are permitted provided that the following conditions 1323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * are met: 1423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 1583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch * notice, this list of conditions and the following disclaimer. 1623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 1723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 1823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * documentation and/or other materials provided with the distribution. 1923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * 3. The name of the author may not be used to endorse or promote products 2023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * derived from this software without specific prior written permission. 2123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * 2223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) */ 3323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 3423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include "defs.h" 3523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include <sys/user.h> 3623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include <sys/param.h> 3723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 3823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifdef HAVE_SYS_REG_H 3923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <sys/reg.h> 4023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# ifndef PTRACE_PEEKUSR 4123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define PTRACE_PEEKUSR PTRACE_PEEKUSER 4223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 4323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(HAVE_LINUX_PTRACE_H) 4423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# undef PTRACE_SYSCALL 4523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# ifdef HAVE_STRUCT_IA64_FPREG 4623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define ia64_fpreg XXX_ia64_fpreg 4723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 4823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 4923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define pt_all_user_regs XXX_pt_all_user_regs 5023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 5123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <linux/ptrace.h> 5223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# undef ia64_fpreg 5323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# undef pt_all_user_regs 5423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 55e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 5623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if defined(SPARC64) 5723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# undef PTRACE_GETREGS 5823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define PTRACE_GETREGS PTRACE_GETREGS64 59e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch# undef PTRACE_SETREGS 6023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define PTRACE_SETREGS PTRACE_SETREGS64 6123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 6223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 6323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if defined(IA64) 6423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <asm/ptrace_offsets.h> 6523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <asm/rse.h> 6623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 6723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 6823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if defined(AARCH64) 6923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <asm/ptrace.h> 7023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <sys/uio.h> 7123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include <elf.h> 7223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 7323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 7423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if defined(TILE) 7523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# ifndef PT_FLAGS_COMPAT 7623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define PT_FLAGS_COMPAT 0x10000 /* from Linux 3.8 on */ 7723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 7823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 7923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 8023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifndef ERESTARTSYS 8123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define ERESTARTSYS 512 8223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 8323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifndef ERESTARTNOINTR 8423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define ERESTARTNOINTR 513 8523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 8623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifndef ERESTARTNOHAND 8723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define ERESTARTNOHAND 514 /* restart if no handler */ 8823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 8923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifndef ERESTART_RESTARTBLOCK 9023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ 9123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 9223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 9323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifndef NSIG 9423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# warning: NSIG is not defined, using 32 9523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define NSIG 32 9623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 9723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifdef ARM 9823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/* Ugh. Is this really correct? ARM has no RT signals?! */ 9923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# undef NSIG 10023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# define NSIG 32 10123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 10223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 10323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include "syscall.h" 10423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 10523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/* Define these shorthand notations to simplify the syscallent files. */ 10623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TD TRACE_DESC 10723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TF TRACE_FILE 10823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TI TRACE_IPC 10923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TN TRACE_NETWORK 11023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TP TRACE_PROCESS 11123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TS TRACE_SIGNAL 11223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define TM TRACE_MEMORY 1137757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#define NF SYSCALL_NEVER_FAILS 11423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#define MA MAX_ARGS 11523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 11623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct sysent sysent0[] = { 11723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include "syscallent.h" 11823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 11923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 12023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 2 12123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct sysent sysent1[] = { 12223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "syscallent1.h" 12323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 12423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 1257757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch 12623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 3 12723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct sysent sysent2[] = { 12823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "syscallent2.h" 12923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 13023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 13123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 13223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/* Now undef them since short defines cause wicked namespace pollution. */ 13323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TD 13423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TF 13523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TI 13623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TN 13723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TP 13823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TS 13923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef TM 14023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef NF 14123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#undef MA 14223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 14323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/* 14423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * `ioctlent.h' may be generated from `ioctlent.raw' by the auxiliary 14523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * program `ioctlsort', such that the list is sorted by the `code' field. 14623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * This has the side-effect of resolving the _IO.. macros into 14723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * plain integers, eliminating the need to include here everything 14823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) * in "/usr/include". 14923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) */ 15023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 15123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const char *const errnoent0[] = { 15223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include "errnoent.h" 15323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 15423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const char *const signalent0[] = { 15583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch#include "signalent.h" 15623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 15723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct ioctlent ioctlent0[] = { 15823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#include "ioctlent.h" 15923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 1607757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdochenum { nsyscalls0 = ARRAY_SIZE(sysent0) }; 16123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nerrnos0 = ARRAY_SIZE(errnoent0) }; 16223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nsignals0 = ARRAY_SIZE(signalent0) }; 16323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nioctlents0 = ARRAY_SIZE(ioctlent0) }; 16423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int qual_flags0[MAX_QUALS]; 16523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 166591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#if SUPPORTED_PERSONALITIES >= 2 16723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const char *const errnoent1[] = { 1680019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch# include "errnoent1.h" 169e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}; 170e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic const char *const signalent1[] = { 17123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "signalent1.h" 172e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch}; 173e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic const struct ioctlent ioctlent1[] = { 17423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "ioctlent1.h" 17523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 17623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nsyscalls1 = ARRAY_SIZE(sysent1) }; 177591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochenum { nerrnos1 = ARRAY_SIZE(errnoent1) }; 17823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nsignals1 = ARRAY_SIZE(signalent1) }; 17923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nioctlents1 = ARRAY_SIZE(ioctlent1) }; 18023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int qual_flags1[MAX_QUALS]; 18123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 18223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 18323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 3 18423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const char *const errnoent2[] = { 18523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "errnoent2.h" 18623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 18723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const char *const signalent2[] = { 18823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "signalent2.h" 18923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 19023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct ioctlent ioctlent2[] = { 19123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# include "ioctlent2.h" 19223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 19323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nsyscalls2 = ARRAY_SIZE(sysent2) }; 19423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nerrnos2 = ARRAY_SIZE(errnoent2) }; 19523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nsignals2 = ARRAY_SIZE(signalent2) }; 19623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)enum { nioctlents2 = ARRAY_SIZE(ioctlent2) }; 19723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int qual_flags2[MAX_QUALS]; 19823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 19923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 20023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)const struct sysent *sysent = sysent0; 20123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)const char *const *errnoent = errnoent0; 20223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)const char *const *signalent = signalent0; 20323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)const struct ioctlent *ioctlent = ioctlent0; 20423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)unsigned nsyscalls = nsyscalls0; 20523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)unsigned nerrnos = nerrnos0; 20623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)unsigned nsignals = nsignals0; 20723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)unsigned nioctlents = nioctlents0; 20823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int *qual_flags = qual_flags0; 20923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 21023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES > 1 21123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int current_personality; 21223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 21323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)const int personality_wordsize[SUPPORTED_PERSONALITIES] = { 21423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) PERSONALITY0_WORDSIZE, 21523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) PERSONALITY1_WORDSIZE, 21623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# if SUPPORTED_PERSONALITIES > 2 21723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) PERSONALITY2_WORDSIZE, 21823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 21923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)}; 22023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 22123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)void 22223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)set_personality(int personality) 22323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 22423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) switch (personality) { 22523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) case 0: 22623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) errnoent = errnoent0; 22723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nerrnos = nerrnos0; 22823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) sysent = sysent0; 22923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nsyscalls = nsyscalls0; 23023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) ioctlent = ioctlent0; 23123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nioctlents = nioctlents0; 23223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) signalent = signalent0; 23323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nsignals = nsignals0; 23423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags = qual_flags0; 23523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) break; 23623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 237591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case 1: 23823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) errnoent = errnoent1; 23923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nerrnos = nerrnos1; 240591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch sysent = sysent1; 24123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nsyscalls = nsyscalls1; 24223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) ioctlent = ioctlent1; 24323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nioctlents = nioctlents1; 24423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) signalent = signalent1; 245591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch nsignals = nsignals1; 24623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags = qual_flags1; 24723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) break; 24823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 24923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# if SUPPORTED_PERSONALITIES >= 3 25023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) case 2: 25123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) errnoent = errnoent2; 25223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nerrnos = nerrnos2; 25323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) sysent = sysent2; 25423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nsyscalls = nsyscalls2; 25523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) ioctlent = ioctlent2; 25623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nioctlents = nioctlents2; 25723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) signalent = signalent2; 25823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) nsignals = nsignals2; 25923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags = qual_flags2; 26023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) break; 26123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 26223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 26323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 26423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) current_personality = personality; 26523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 26623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 26723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static void 26823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)update_personality(struct tcb *tcp, int personality) 26923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 27023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (personality == current_personality) 27123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 27223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) set_personality(personality); 27323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 27423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (personality == tcp->currpers) 27523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 27623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->currpers = personality; 27723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 27823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# if defined(POWERPC64) 27923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!qflag) { 28023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) static const char *const names[] = {"64 bit", "32 bit"}; 28123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 28223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->pid, names[personality]); 28323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 28423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(X86_64) 28523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!qflag) { 28623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) static const char *const names[] = {"64 bit", "32 bit", "x32"}; 28723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 28823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->pid, names[personality]); 28923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 29023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(X32) 29123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!qflag) { 29223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) static const char *const names[] = {"x32", "32 bit"}; 29323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 29423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->pid, names[personality]); 295591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 29623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(AARCH64) 29723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!qflag) { 29823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) static const char *const names[] = {"32-bit ARM", "AArch64"}; 29923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 30023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->pid, names[personality]); 30123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 30223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(TILE) 30323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!qflag) { 30423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) static const char *const names[] = {"64-bit", "32-bit"}; 30523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 30623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->pid, names[personality]); 30723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 30823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 30923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 31023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 31123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 31223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int qual_syscall(), qual_signal(), qual_fault(), qual_desc(); 31323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 31423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static const struct qual_options { 31523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int bitflag; 31623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) const char *option_name; 31723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int (*qualify)(const char *, int, int); 31823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) const char *argument_name; 31923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} qual_options[] = { 32023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_TRACE, "trace", qual_syscall, "system call" }, 32123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_TRACE, "t", qual_syscall, "system call" }, 32223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_ABBREV, "abbrev", qual_syscall, "system call" }, 32323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_ABBREV, "a", qual_syscall, "system call" }, 32423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_VERBOSE, "verbose", qual_syscall, "system call" }, 32523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_VERBOSE, "v", qual_syscall, "system call" }, 32623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_RAW, "raw", qual_syscall, "system call" }, 32723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_RAW, "x", qual_syscall, "system call" }, 32823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_SIGNAL, "signal", qual_signal, "signal" }, 329591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch { QUAL_SIGNAL, "signals", qual_signal, "signal" }, 33023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_SIGNAL, "s", qual_signal, "signal" }, 33123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_FAULT, "fault", qual_fault, "fault" }, 33223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_FAULT, "faults", qual_fault, "fault" }, 33323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_FAULT, "m", qual_fault, "fault" }, 33423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_READ, "read", qual_desc, "descriptor" }, 33523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_READ, "reads", qual_desc, "descriptor" }, 33623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_READ, "r", qual_desc, "descriptor" }, 33723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_WRITE, "write", qual_desc, "descriptor" }, 33823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_WRITE, "writes", qual_desc, "descriptor" }, 33923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { QUAL_WRITE, "w", qual_desc, "descriptor" }, 34023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) { 0, NULL, NULL, NULL }, 341591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}; 34223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 34323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static void 34423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qualify_one(int n, int bitflag, int not, int pers) 34523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 34623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (pers == 0 || pers < 0) { 34723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (not) 34823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags0[n] &= ~bitflag; 34923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) else 35023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags0[n] |= bitflag; 35123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 35223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 35323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 2 35423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (pers == 1 || pers < 0) { 35523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (not) 35623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags1[n] &= ~bitflag; 35723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) else 35823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags1[n] |= bitflag; 35923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 36023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 36123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 36223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 3 36323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (pers == 2 || pers < 0) { 36423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (not) 36523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags2[n] &= ~bitflag; 36623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) else 36723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qual_flags2[n] |= bitflag; 36823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 36923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 37023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 371e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch 37223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int 37323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qual_syscall(const char *s, int bitflag, int not) 37423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 37523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int i; 37623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int rc = -1; 37723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 3787757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (*s >= '0' && *s <= '9') { 3797757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch int i = string_to_uint(s); 38023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (i < 0 || i >= MAX_QUALS) 38123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 38223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, bitflag, not, -1); 38323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return 0; 38423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 38523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < nsyscalls0; i++) 38623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (sysent0[i].sys_name && 38723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) strcmp(s, sysent0[i].sys_name) == 0) { 38823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, bitflag, not, 0); 38923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) rc = 0; 39023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 39123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 392e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#if SUPPORTED_PERSONALITIES >= 2 393e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch for (i = 0; i < nsyscalls1; i++) 39423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (sysent1[i].sys_name && 39523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) strcmp(s, sysent1[i].sys_name) == 0) { 39623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, bitflag, not, 1); 39723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) rc = 0; 39823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 39923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 40023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 40123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 3 40223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < nsyscalls2; i++) 4030019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch if (sysent2[i].sys_name && 4040019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch strcmp(s, sysent2[i].sys_name) == 0) { 40523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, bitflag, not, 2); 40623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) rc = 0; 40723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 40823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 40923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 41023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return rc; 41123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 41223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 41323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int 41423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qual_signal(const char *s, int bitflag, int not) 41523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 41623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int i; 41723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 41823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (*s >= '0' && *s <= '9') { 41923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int signo = string_to_uint(s); 42023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (signo < 0 || signo >= MAX_QUALS) 42123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 42223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(signo, bitflag, not, -1); 42323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return 0; 42423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 42523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strncasecmp(s, "SIG", 3) == 0) 42623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) s += 3; 42723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i <= NSIG; i++) { 42823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcasecmp(s, signame(i) + 3) == 0) { 42923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, bitflag, not, -1); 43023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return 0; 43123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 43223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 43323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 43423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 43523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 43623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int 43723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qual_fault(const char *s, int bitflag, int not) 43823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 43923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 44023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 44123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 44223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int 44323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qual_desc(const char *s, int bitflag, int not) 44423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 44523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (*s >= '0' && *s <= '9') { 44623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int desc = string_to_uint(s); 44723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (desc < 0 || desc >= MAX_QUALS) 44823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 44923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(desc, bitflag, not, -1); 45023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return 0; 45123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 45223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 45323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 454591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 45523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static int 45623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)lookup_class(const char *s) 457591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 45823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "file") == 0) 45923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return TRACE_FILE; 46023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "ipc") == 0) 4617757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch return TRACE_IPC; 462591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (strcmp(s, "network") == 0) 46323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return TRACE_NETWORK; 46423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "process") == 0) 46523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return TRACE_PROCESS; 46623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "signal") == 0) 46723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return TRACE_SIGNAL; 4687757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch if (strcmp(s, "desc") == 0) 46923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return TRACE_DESC; 47023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "memory") == 0) 471e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch return TRACE_MEMORY; 47223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return -1; 47323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 47423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 47523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)void 47623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)qualify(const char *s) 47723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 47823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) const struct qual_options *opt; 47923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int not; 48023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) char *copy; 48123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) const char *p; 48223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int i, n; 48323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 48423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) opt = &qual_options[0]; 48523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; (p = qual_options[i].option_name); i++) { 48623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) n = strlen(p); 48723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strncmp(s, p, n) == 0 && s[n] == '=') { 48823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) opt = &qual_options[i]; 48923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) s += n + 1; 49023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) break; 49123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 49223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 49323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) not = 0; 49423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (*s == '!') { 49523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) not = 1; 49623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) s++; 49723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 49823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "none") == 0) { 49923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) not = 1 - not; 50023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) s = "all"; 50123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 50223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (strcmp(s, "all") == 0) { 503591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (i = 0; i < MAX_QUALS; i++) { 50423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, opt->bitflag, not, -1); 50523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 50623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 50723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 50823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < MAX_QUALS; i++) { 50923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, opt->bitflag, !not, -1); 51023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 51123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) copy = strdup(s); 51223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (!copy) 51323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) die_out_of_memory(); 51423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) { 51523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) { 51623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < nsyscalls0; i++) 51723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (sysent0[i].sys_flags & n) 51823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, opt->bitflag, not, 0); 51923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 52023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 2 52123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < nsyscalls1; i++) 52223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (sysent1[i].sys_flags & n) 52323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, opt->bitflag, not, 1); 52423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 52523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 52623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#if SUPPORTED_PERSONALITIES >= 3 52723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < nsyscalls2; i++) 52823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (sysent2[i].sys_flags & n) 52923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) qualify_one(i, opt->bitflag, not, 2); 53023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 53123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 53223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) continue; 53323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 53423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (opt->qualify(p, opt->bitflag, not)) { 53523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) error_msg_and_die("invalid %s '%s'", 53623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) opt->argument_name, p); 53723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 53823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 539591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch free(copy); 540521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 54123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 54223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 543e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch#ifdef SYS_socket_subcall 544e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic void 54523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)decode_socket_subcall(struct tcb *tcp) 54623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 54723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) unsigned long addr; 54823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) unsigned int i, size; 54983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 55023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls) 55123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 55223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 55323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->scno = SYS_socket_subcall + tcp->u_arg[0]; 55423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) addr = tcp->u_arg[1]; 555521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) tcp->u_nargs = sysent[tcp->scno].nargs; 55623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) size = current_wordsize; 55723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < tcp->u_nargs; ++i) { 55823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (size == sizeof(int)) { 55923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) unsigned int arg; 56023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (umove(tcp, addr, &arg) < 0) 56123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) arg = 0; 56223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->u_arg[i] = arg; 563521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 56423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) else { 56523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) unsigned long arg; 56623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (umove(tcp, addr, &arg) < 0) 56723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) arg = 0; 56823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->u_arg[i] = arg; 56923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 57023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) addr += size; 57123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 57223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 57323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 57423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 57523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#ifdef SYS_ipc_subcall 57623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)static void 57723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)decode_ipc_subcall(struct tcb *tcp) 57823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 57983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch unsigned int i; 58083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 58123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_ipc_nsubcalls) 58283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch return; 58383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 58423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->scno = SYS_ipc_subcall + tcp->u_arg[0]; 58523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->u_nargs = sysent[tcp->scno].nargs; 58623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < tcp->u_nargs; i++) 58723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tcp->u_arg[i] = tcp->u_arg[i + 1]; 58823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)} 58923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#endif 59023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 59123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)int 59223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)printargs(struct tcb *tcp) 59323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles){ 59423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (entering(tcp)) { 59523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) int i; 59623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 59723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) for (i = 0; i < tcp->u_nargs; i++) 59823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); 59923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 600591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 0; 601591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 602591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 603591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochint 604591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochprintargs_lu(struct tcb *tcp) 605591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 606591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (entering(tcp)) { 607591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int i; 608591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 609591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (i = 0; i < tcp->u_nargs; i++) 610591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("%s%lu", i ? ", " : "", tcp->u_arg[i]); 611591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 612591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 0; 613591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 614591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 61583750176c3ee2cea66c8a9751271026a5901be3aBen Murdochint 616591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochprintargs_ld(struct tcb *tcp) 617591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 618591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (entering(tcp)) { 619591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch int i; 620591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 621591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch for (i = 0; i < tcp->u_nargs; i++) 622591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("%s%ld", i ? ", " : "", tcp->u_arg[i]); 623591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 624591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 0; 625591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 626591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 627591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH) 628591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochlong 629591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochgetrval2(struct tcb *tcp) 630591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 631591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch long val; 632591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 633591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# if defined(SPARC) || defined(SPARC64) 634591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch val = regs.u_regs[U_REG_O1]; 635591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# elif defined(SH) 636591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (upeek(tcp, 4*(REG_REG0+1), &val) < 0) 637591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return -1; 638591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# elif defined(IA64) 639591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (upeek(tcp, PT_R9, &val) < 0) 640591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return -1; 641591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# endif 6420019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch 643591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return val; 644591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 645591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#endif 646591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 647591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochint 648591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochis_restart_error(struct tcb *tcp) 649591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 650591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch switch (tcp->u_error) { 651591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ERESTARTSYS: 652591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ERESTARTNOINTR: 653591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ERESTARTNOHAND: 654591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch case ERESTART_RESTARTBLOCK: 655591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 1; 656591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch default: 657591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch break; 658591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 659591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return 0; 660591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 661591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 662591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#if defined(I386) 663591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstruct pt_regs i386_regs; 664591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(X86_64) || defined(X32) 665591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch/* 666591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * On 32 bits, pt_regs and user_regs_struct are the same, 667591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * but on 64 bits, user_regs_struct has six more fields: 668591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * fs_base, gs_base, ds, es, fs, gs. 669591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch * PTRACE_GETREGS fills them too, so struct pt_regs would overflow. 670591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch */ 671591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic struct user_regs_struct x86_64_regs; 672591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(IA64) 673591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochlong r8, r10; /* TODO: make static? */ 674591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochlong ia32 = 0; /* not static */ 675591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(POWERPC) 676591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long ppc_result; 677591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(M68K) 678591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long d0; 679591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(BFIN) 680591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r0; 681591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(ARM) 682591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstruct pt_regs regs; /* not static */ 683591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(AARCH64) 684591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic struct user_pt_regs aarch64_regs; 685591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic struct arm_pt_regs regs; 686591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic struct iovec aarch64_io = { 687591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch .iov_base = &aarch64_regs 688591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch}; 689591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(ALPHA) 690591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r0; 691591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long a3; 692591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(AVR32) 693591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic struct pt_regs regs; 694591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(SPARC) || defined(SPARC64) 695591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstruct pt_regs regs; /* not static */ 696591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(LINUX_MIPSN32) 697591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long long a3; 698591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long long r2; 699591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(MIPS) 700591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long a3; 701591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r2; 702591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(S390) || defined(S390X) 703e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic long gpr2; 704e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdochstatic long pc; 705591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long syscall_mode; 706591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(HPPA) 707591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r28; 708591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(SH) 70983750176c3ee2cea66c8a9751271026a5901be3aBen Murdochstatic long r0; 710591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(SH64) 711591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r9; 712591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(CRISV10) || defined(CRISV32) 713591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r10; 714591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(TILE) 715591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstruct pt_regs tile_regs; 716591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(MICROBLAZE) 717591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochstatic long r3; 718591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#endif 719591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 720591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid 721591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochprintcall(struct tcb *tcp) 722591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 723591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \ 724591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch sizeof(long) == 8 ? "[????????????????] " : \ 725591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch NULL /* crash */) 726591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (get_regs_error) { 727591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch PRINTBADPC; 728591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 729591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 730591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#if defined(I386) 731591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", i386_regs.eip); 732591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(S390) || defined(S390X) 733591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch long psw; 734591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (upeek(tcp, PT_PSWADDR, &psw) < 0) { 735591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch PRINTBADPC; 736591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 737591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 738591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# ifdef S390 73983750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch tprintf("[%08lx] ", psw); 74083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch# elif S390X 741591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%016lx] ", psw); 74283750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch# endif 74383750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch#elif defined(X86_64) || defined(X32) 744591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%016lx] ", (unsigned long) x86_64_regs.rip); 745591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(IA64) 746591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch long ip; 747591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 748591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (upeek(tcp, PT_B0, &ip) < 0) { 749591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch PRINTBADPC; 750591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 751591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 752591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", ip); 753591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(POWERPC) 754591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch long pc; 755591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 756591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) { 757591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch PRINTBADPC; 758591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 759591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 760591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# ifdef POWERPC64 76123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%016lx] ", pc); 76223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# else 76323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 76423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# endif 76523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(M68K) 76623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 76723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 76823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, 4*PT_PC, &pc) < 0) { 76923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????] "); 77023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 771521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) } 77223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 77323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(ALPHA) 77423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 77583750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch 77623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, REG_PC, &pc) < 0) { 77723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????????????] "); 77823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 77923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 78023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 78123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(SPARC) 782591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", regs.pc); 78323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(SPARC64) 78423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", regs.tpc); 78523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(HPPA) 78623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 78723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 78823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, PT_IAOQ0, &pc) < 0) { 78923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????] "); 790521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles) return; 79123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 79223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 79323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(MIPS) 79423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 79523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 79623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, REG_EPC, &pc) < 0) { 79723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????] "); 79823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 79923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 80023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 80123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(SH) 8020019e4eead4d990e4304c54a9028aca9122fb256Ben Murdoch long pc; 80323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 80423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, 4*REG_PC, &pc) < 0) { 80523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????] "); 80623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 80723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 80823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 809591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(SH64) 81023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 81123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 81223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, REG_PC, &pc) < 0) { 81323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprints("[????????????????] "); 81423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 81523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 81623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 81723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(ARM) 81823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", regs.ARM_pc); 81923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)/*#elif defined(AARCH64) ??? */ 82023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(AVR32) 821591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", regs.pc); 822591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(BFIN) 823591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch long pc; 824591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 82523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, PT_PC, &pc) < 0) { 82623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) PRINTBADPC; 827591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 82823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 82923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 83023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(CRISV10) 83123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 83223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 83323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, 4*PT_IRP, &pc) < 0) { 83423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) PRINTBADPC; 83523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 83623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) } 83723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) tprintf("[%08lx] ", pc); 83823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)#elif defined(CRISV32) 83923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) long pc; 84023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) 84123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (upeek(tcp, 4*PT_ERP, &pc) < 0) { 842591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch PRINTBADPC; 843591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch return; 844591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch } 845591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", pc); 846591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#elif defined(TILE) 847591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# ifdef _LP64 848591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%016lx] ", (unsigned long) tile_regs.pc); 849591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# else 850591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch tprintf("[%08lx] ", (unsigned long) tile_regs.pc); 851591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch# endif 852591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#endif /* architecture */ 853591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch} 854591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch 855591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#ifndef get_regs 856591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochlong get_regs_error; 857591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid get_regs(pid_t pid) 858591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch{ 85923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# if defined(AVR32) 86083750176c3ee2cea66c8a9751271026a5901be3aBen Murdoch get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, ®s); 86123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(I386) 86223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &i386_regs); 86323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(X86_64) || defined(X32) 86423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &x86_64_regs); 86523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles)# elif defined(AARCH64) 86623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) /*aarch64_io.iov_base = &aarch64_regs; - already is */ 86723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) aarch64_io.iov_len = sizeof(aarch64_regs); 86823042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) get_regs_error = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void *)&aarch64_io); 86923042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) if (get_regs_error) 87023042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) return; 87123042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) switch (aarch64_io.iov_len) { 87223042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) case sizeof(regs): 87323042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) /* We are in 32-bit mode */ 87423042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) memcpy(®s, &aarch64_regs, sizeof(regs)); 87523042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) break; 87623042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) case sizeof(aarch64_regs): 87723042b77ca894a768b5747ff08f587ed8222772aTorne (Richard Coles) /* We are in 64-bit mode */ 878 /* Data is already in aarch64_regs */ 879 break; 880 default: 881 get_regs_error = -1; 882 break; 883 } 884# elif defined(ARM) 885 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (void *)®s); 886# elif defined(SPARC) || defined(SPARC64) 887 get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)®s, 0); 888# elif defined(TILE) 889 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &tile_regs); 890# endif 891} 892#endif 893 894/* Returns: 895 * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently. 896 * 1: ok, continue in trace_syscall_entering(). 897 * other: error, trace_syscall_entering() should print error indicator 898 * ("????" etc) and bail out. 899 */ 900static int 901get_scno(struct tcb *tcp) 902{ 903 long scno = 0; 904 905#if defined(S390) || defined(S390X) 906 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0) 907 return -1; 908 909 if (syscall_mode != -ENOSYS) { 910 /* 911 * Since kernel version 2.5.44 the scno gets passed in gpr2. 912 */ 913 scno = syscall_mode; 914 } else { 915 /* 916 * Old style of "passing" the scno via the SVC instruction. 917 */ 918 long opcode, offset_reg, tmp; 919 void *svc_addr; 920 static const int gpr_offset[16] = { 921 PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3, 922 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, 923 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, 924 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15 925 }; 926 927 if (upeek(tcp, PT_PSWADDR, &pc) < 0) 928 return -1; 929 errno = 0; 930 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0); 931 if (errno) { 932 perror_msg("%s", "peektext(pc-oneword)"); 933 return -1; 934 } 935 936 /* 937 * We have to check if the SVC got executed directly or via an 938 * EXECUTE instruction. In case of EXECUTE it is necessary to do 939 * instruction decoding to derive the system call number. 940 * Unfortunately the opcode sizes of EXECUTE and SVC are differently, 941 * so that this doesn't work if a SVC opcode is part of an EXECUTE 942 * opcode. Since there is no way to find out the opcode size this 943 * is the best we can do... 944 */ 945 if ((opcode & 0xff00) == 0x0a00) { 946 /* SVC opcode */ 947 scno = opcode & 0xff; 948 } 949 else { 950 /* SVC got executed by EXECUTE instruction */ 951 952 /* 953 * Do instruction decoding of EXECUTE. If you really want to 954 * understand this, read the Principles of Operations. 955 */ 956 svc_addr = (void *) (opcode & 0xfff); 957 958 tmp = 0; 959 offset_reg = (opcode & 0x000f0000) >> 16; 960 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 961 return -1; 962 svc_addr += tmp; 963 964 tmp = 0; 965 offset_reg = (opcode & 0x0000f000) >> 12; 966 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 967 return -1; 968 svc_addr += tmp; 969 970 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0); 971 if (errno) 972 return -1; 973# if defined(S390X) 974 scno >>= 48; 975# else 976 scno >>= 16; 977# endif 978 tmp = 0; 979 offset_reg = (opcode & 0x00f00000) >> 20; 980 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 981 return -1; 982 983 scno = (scno | tmp) & 0xff; 984 } 985 } 986#elif defined(POWERPC) 987 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) 988 return -1; 989# ifdef POWERPC64 990 /* TODO: speed up strace by not doing this at every syscall. 991 * We only need to do it after execve. 992 */ 993 int currpers; 994 long val; 995 996 /* Check for 64/32 bit mode. */ 997 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0) 998 return -1; 999 /* SF is bit 0 of MSR */ 1000 if (val < 0) 1001 currpers = 0; 1002 else 1003 currpers = 1; 1004 update_personality(tcp, currpers); 1005# endif 1006#elif defined(AVR32) 1007 scno = regs.r8; 1008#elif defined(BFIN) 1009 if (upeek(tcp, PT_ORIG_P0, &scno)) 1010 return -1; 1011#elif defined(I386) 1012 scno = i386_regs.orig_eax; 1013#elif defined(X86_64) || defined(X32) 1014# ifndef __X32_SYSCALL_BIT 1015# define __X32_SYSCALL_BIT 0x40000000 1016# endif 1017# ifndef __X32_SYSCALL_MASK 1018# define __X32_SYSCALL_MASK __X32_SYSCALL_BIT 1019# endif 1020 1021 int currpers; 1022 scno = x86_64_regs.orig_rax; 1023 1024 /* Check CS register value. On x86-64 linux it is: 1025 * 0x33 for long mode (64 bit) 1026 * 0x23 for compatibility mode (32 bit) 1027 * Check DS register value. On x86-64 linux it is: 1028 * 0x2b for x32 mode (x86-64 in 32 bit) 1029 */ 1030 switch (x86_64_regs.cs) { 1031 case 0x23: currpers = 1; break; 1032 case 0x33: 1033 if (x86_64_regs.ds == 0x2b) { 1034 currpers = 2; 1035 scno &= ~__X32_SYSCALL_MASK; 1036 } else 1037 currpers = 0; 1038 break; 1039 default: 1040 fprintf(stderr, "Unknown value CS=0x%08X while " 1041 "detecting personality of process " 1042 "PID=%d\n", (int)x86_64_regs.cs, tcp->pid); 1043 currpers = current_personality; 1044 break; 1045 } 1046# if 0 1047 /* This version analyzes the opcode of a syscall instruction. 1048 * (int 0x80 on i386 vs. syscall on x86-64) 1049 * It works, but is too complicated. 1050 */ 1051 unsigned long val, rip, i; 1052 1053 rip = x86_64_regs.rip; 1054 1055 /* sizeof(syscall) == sizeof(int 0x80) == 2 */ 1056 rip -= 2; 1057 errno = 0; 1058 1059 call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0); 1060 if (errno) 1061 fprintf(stderr, "ptrace_peektext failed: %s\n", 1062 strerror(errno)); 1063 switch (call & 0xffff) { 1064 /* x86-64: syscall = 0x0f 0x05 */ 1065 case 0x050f: currpers = 0; break; 1066 /* i386: int 0x80 = 0xcd 0x80 */ 1067 case 0x80cd: currpers = 1; break; 1068 default: 1069 currpers = current_personality; 1070 fprintf(stderr, 1071 "Unknown syscall opcode (0x%04X) while " 1072 "detecting personality of process " 1073 "PID=%d\n", (int)call, tcp->pid); 1074 break; 1075 } 1076# endif 1077# ifdef X32 1078 /* Value of currpers: 1079 * 0: 64 bit 1080 * 1: 32 bit 1081 * 2: X32 1082 * Value of current_personality: 1083 * 0: X32 1084 * 1: 32 bit 1085 */ 1086 switch (currpers) { 1087 case 0: 1088 fprintf(stderr, "syscall_%lu (...) in unsupported " 1089 "64-bit mode of process PID=%d\n", 1090 scno, tcp->pid); 1091 return 0; 1092 case 2: 1093 currpers = 0; 1094 } 1095# endif 1096 update_personality(tcp, currpers); 1097#elif defined(IA64) 1098# define IA64_PSR_IS ((long)1 << 34) 1099 long psr; 1100 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 1101 ia32 = (psr & IA64_PSR_IS) != 0; 1102 if (ia32) { 1103 if (upeek(tcp, PT_R1, &scno) < 0) 1104 return -1; 1105 } else { 1106 if (upeek(tcp, PT_R15, &scno) < 0) 1107 return -1; 1108 } 1109#elif defined(AARCH64) 1110 switch (aarch64_io.iov_len) { 1111 case sizeof(aarch64_regs): 1112 /* We are in 64-bit mode */ 1113 scno = aarch64_regs.regs[8]; 1114 update_personality(tcp, 1); 1115 break; 1116 case sizeof(regs): 1117 /* We are in 32-bit mode */ 1118 scno = regs.uregs[7]; 1119 update_personality(tcp, 0); 1120 break; 1121 } 1122#elif defined(ARM) 1123 /* 1124 * We only need to grab the syscall number on syscall entry. 1125 */ 1126 if (regs.ARM_ip == 0) { 1127 /* 1128 * Note: we only deal with only 32-bit CPUs here. 1129 */ 1130 if (regs.ARM_cpsr & 0x20) { 1131 /* 1132 * Get the Thumb-mode system call number 1133 */ 1134 scno = regs.ARM_r7; 1135 } else { 1136 /* 1137 * Get the ARM-mode system call number 1138 */ 1139 errno = 0; 1140 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL); 1141 if (errno) 1142 return -1; 1143 1144 /* Handle the EABI syscall convention. We do not 1145 bother converting structures between the two 1146 ABIs, but basic functionality should work even 1147 if strace and the traced program have different 1148 ABIs. */ 1149 if (scno == 0xef000000) { 1150 scno = regs.ARM_r7; 1151 } else { 1152 if ((scno & 0x0ff00000) != 0x0f900000) { 1153 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n", 1154 scno); 1155 return -1; 1156 } 1157 1158 /* 1159 * Fixup the syscall number 1160 */ 1161 scno &= 0x000fffff; 1162 } 1163 } 1164 if (scno & 0x0f0000) { 1165 /* 1166 * Handle ARM specific syscall 1167 */ 1168 update_personality(tcp, 1); 1169 scno &= 0x0000ffff; 1170 } else 1171 update_personality(tcp, 0); 1172 1173 } else { 1174 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid); 1175 tcp->flags |= TCB_INSYSCALL; 1176 } 1177#elif defined(M68K) 1178 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0) 1179 return -1; 1180#elif defined(LINUX_MIPSN32) 1181 unsigned long long regs[38]; 1182 1183 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1184 return -1; 1185 a3 = regs[REG_A3]; 1186 r2 = regs[REG_V0]; 1187 1188 scno = r2; 1189 if (!SCNO_IN_RANGE(scno)) { 1190 if (a3 == 0 || a3 == -1) { 1191 if (debug_flag) 1192 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 1193 return 0; 1194 } 1195 } 1196#elif defined(MIPS) 1197 if (upeek(tcp, REG_A3, &a3) < 0) 1198 return -1; 1199 if (upeek(tcp, REG_V0, &scno) < 0) 1200 return -1; 1201 1202 if (!SCNO_IN_RANGE(scno)) { 1203 if (a3 == 0 || a3 == -1) { 1204 if (debug_flag) 1205 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 1206 return 0; 1207 } 1208 } 1209#elif defined(ALPHA) 1210 if (upeek(tcp, REG_A3, &a3) < 0) 1211 return -1; 1212 if (upeek(tcp, REG_R0, &scno) < 0) 1213 return -1; 1214 1215 /* 1216 * Do some sanity checks to figure out if it's 1217 * really a syscall entry 1218 */ 1219 if (!SCNO_IN_RANGE(scno)) { 1220 if (a3 == 0 || a3 == -1) { 1221 if (debug_flag) 1222 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno); 1223 return 0; 1224 } 1225 } 1226#elif defined(SPARC) || defined(SPARC64) 1227 /* Disassemble the syscall trap. */ 1228 /* Retrieve the syscall trap instruction. */ 1229 unsigned long trap; 1230 errno = 0; 1231# if defined(SPARC64) 1232 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0); 1233 trap >>= 32; 1234# else 1235 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0); 1236# endif 1237 if (errno) 1238 return -1; 1239 1240 /* Disassemble the trap to see what personality to use. */ 1241 switch (trap) { 1242 case 0x91d02010: 1243 /* Linux/SPARC syscall trap. */ 1244 update_personality(tcp, 0); 1245 break; 1246 case 0x91d0206d: 1247 /* Linux/SPARC64 syscall trap. */ 1248 update_personality(tcp, 2); 1249 break; 1250 case 0x91d02000: 1251 /* SunOS syscall trap. (pers 1) */ 1252 fprintf(stderr, "syscall: SunOS no support\n"); 1253 return -1; 1254 case 0x91d02008: 1255 /* Solaris 2.x syscall trap. (per 2) */ 1256 update_personality(tcp, 1); 1257 break; 1258 case 0x91d02009: 1259 /* NetBSD/FreeBSD syscall trap. */ 1260 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n"); 1261 return -1; 1262 case 0x91d02027: 1263 /* Solaris 2.x gettimeofday */ 1264 update_personality(tcp, 1); 1265 break; 1266 default: 1267# if defined(SPARC64) 1268 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc); 1269# else 1270 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc); 1271# endif 1272 return -1; 1273 } 1274 1275 /* Extract the system call number from the registers. */ 1276 if (trap == 0x91d02027) 1277 scno = 156; 1278 else 1279 scno = regs.u_regs[U_REG_G1]; 1280 if (scno == 0) { 1281 scno = regs.u_regs[U_REG_O0]; 1282 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0])); 1283 } 1284#elif defined(HPPA) 1285 if (upeek(tcp, PT_GR20, &scno) < 0) 1286 return -1; 1287#elif defined(SH) 1288 /* 1289 * In the new syscall ABI, the system call number is in R3. 1290 */ 1291 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0) 1292 return -1; 1293 1294 if (scno < 0) { 1295 /* Odd as it may seem, a glibc bug has been known to cause 1296 glibc to issue bogus negative syscall numbers. So for 1297 our purposes, make strace print what it *should* have been */ 1298 long correct_scno = (scno & 0xff); 1299 if (debug_flag) 1300 fprintf(stderr, 1301 "Detected glibc bug: bogus system call" 1302 " number = %ld, correcting to %ld\n", 1303 scno, 1304 correct_scno); 1305 scno = correct_scno; 1306 } 1307#elif defined(SH64) 1308 if (upeek(tcp, REG_SYSCALL, &scno) < 0) 1309 return -1; 1310 scno &= 0xFFFF; 1311#elif defined(CRISV10) || defined(CRISV32) 1312 if (upeek(tcp, 4*PT_R9, &scno) < 0) 1313 return -1; 1314#elif defined(TILE) 1315 int currpers; 1316 scno = tile_regs.regs[10]; 1317# ifdef __tilepro__ 1318 currpers = 1; 1319# else 1320 if (tile_regs.flags & PT_FLAGS_COMPAT) 1321 currpers = 1; 1322 else 1323 currpers = 0; 1324# endif 1325 update_personality(tcp, currpers); 1326 1327 if (!(tcp->flags & TCB_INSYSCALL)) { 1328 /* Check if we return from execve. */ 1329 if (tcp->flags & TCB_WAITEXECVE) { 1330 tcp->flags &= ~TCB_WAITEXECVE; 1331 return 0; 1332 } 1333 } 1334#elif defined(MICROBLAZE) 1335 if (upeek(tcp, 0, &scno) < 0) 1336 return -1; 1337#endif 1338 1339#if defined(SH) 1340 /* new syscall ABI returns result in R0 */ 1341 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1342 return -1; 1343#elif defined(SH64) 1344 /* ABI defines result returned in r9 */ 1345 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1346 return -1; 1347#endif 1348 1349 tcp->scno = scno; 1350 return 1; 1351} 1352 1353/* Called at each syscall entry. 1354 * Returns: 1355 * 0: "ignore this ptrace stop", bail out of trace_syscall_entering() silently. 1356 * 1: ok, continue in trace_syscall_entering(). 1357 * other: error, trace_syscall_entering() should print error indicator 1358 * ("????" etc) and bail out. 1359 */ 1360static int 1361syscall_fixup_on_sysenter(struct tcb *tcp) 1362{ 1363 /* A common case of "not a syscall entry" is post-execve SIGTRAP */ 1364#if defined(I386) 1365 if (i386_regs.eax != -ENOSYS) { 1366 if (debug_flag) 1367 fprintf(stderr, "not a syscall entry (eax = %ld)\n", i386_regs.eax); 1368 return 0; 1369 } 1370#elif defined(X86_64) || defined(X32) 1371 { 1372 long rax = x86_64_regs.rax; 1373 if (current_personality == 1) 1374 rax = (int)rax; /* sign extend from 32 bits */ 1375 if (rax != -ENOSYS) { 1376 if (debug_flag) 1377 fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax); 1378 return 0; 1379 } 1380 } 1381#elif defined(S390) || defined(S390X) 1382 /* TODO: we already fetched PT_GPR2 in get_scno 1383 * and stored it in syscall_mode, reuse it here 1384 * instead of re-fetching? 1385 */ 1386 if (upeek(tcp, PT_GPR2, &gpr2) < 0) 1387 return -1; 1388 if (syscall_mode != -ENOSYS) 1389 syscall_mode = tcp->scno; 1390 if (gpr2 != syscall_mode) { 1391 if (debug_flag) 1392 fprintf(stderr, "not a syscall entry (gpr2 = %ld)\n", gpr2); 1393 return 0; 1394 } 1395#elif defined(M68K) 1396 /* TODO? Eliminate upeek's in arches below like we did in x86 */ 1397 if (upeek(tcp, 4*PT_D0, &d0) < 0) 1398 return -1; 1399 if (d0 != -ENOSYS) { 1400 if (debug_flag) 1401 fprintf(stderr, "not a syscall entry (d0 = %ld)\n", d0); 1402 return 0; 1403 } 1404#elif defined(IA64) 1405 if (upeek(tcp, PT_R10, &r10) < 0) 1406 return -1; 1407 if (upeek(tcp, PT_R8, &r8) < 0) 1408 return -1; 1409 if (ia32 && r8 != -ENOSYS) { 1410 if (debug_flag) 1411 fprintf(stderr, "not a syscall entry (r8 = %ld)\n", r8); 1412 return 0; 1413 } 1414#elif defined(CRISV10) || defined(CRISV32) 1415 if (upeek(tcp, 4*PT_R10, &r10) < 0) 1416 return -1; 1417 if (r10 != -ENOSYS) { 1418 if (debug_flag) 1419 fprintf(stderr, "not a syscall entry (r10 = %ld)\n", r10); 1420 return 0; 1421 } 1422#elif defined(MICROBLAZE) 1423 if (upeek(tcp, 3 * 4, &r3) < 0) 1424 return -1; 1425 if (r3 != -ENOSYS) { 1426 if (debug_flag) 1427 fprintf(stderr, "not a syscall entry (r3 = %ld)\n", r3); 1428 return 0; 1429 } 1430#endif 1431 return 1; 1432} 1433 1434static void 1435internal_fork(struct tcb *tcp) 1436{ 1437#if defined S390 || defined S390X || defined CRISV10 || defined CRISV32 1438# define ARG_FLAGS 1 1439#else 1440# define ARG_FLAGS 0 1441#endif 1442#ifndef CLONE_UNTRACED 1443# define CLONE_UNTRACED 0x00800000 1444#endif 1445 if ((ptrace_setoptions 1446 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK)) 1447 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK)) 1448 return; 1449 1450 if (!followfork) 1451 return; 1452 1453 if (entering(tcp)) { 1454 /* 1455 * We won't see the new child if clone is called with 1456 * CLONE_UNTRACED, so we keep the same logic with that option 1457 * and don't trace it. 1458 */ 1459 if ((sysent[tcp->scno].sys_func == sys_clone) && 1460 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED)) 1461 return; 1462 setbpt(tcp); 1463 } else { 1464 if (tcp->flags & TCB_BPTSET) 1465 clearbpt(tcp); 1466 } 1467} 1468 1469#if defined(TCB_WAITEXECVE) 1470static void 1471internal_exec(struct tcb *tcp) 1472{ 1473 /* Maybe we have post-execve SIGTRAP suppressed? */ 1474 if (ptrace_setoptions & PTRACE_O_TRACEEXEC) 1475 return; /* yes, no need to do anything */ 1476 1477 if (exiting(tcp) && syserror(tcp)) 1478 /* Error in execve, no post-execve SIGTRAP expected */ 1479 tcp->flags &= ~TCB_WAITEXECVE; 1480 else 1481 tcp->flags |= TCB_WAITEXECVE; 1482} 1483#endif 1484 1485static void 1486syscall_fixup_for_fork_exec(struct tcb *tcp) 1487{ 1488 /* 1489 * We must always trace a few critical system calls in order to 1490 * correctly support following forks in the presence of tracing 1491 * qualifiers. 1492 */ 1493 int (*func)(); 1494 1495 if (!SCNO_IN_RANGE(tcp->scno)) 1496 return; 1497 1498 func = sysent[tcp->scno].sys_func; 1499 1500 if ( sys_fork == func 1501 || sys_vfork == func 1502 || sys_clone == func 1503 ) { 1504 internal_fork(tcp); 1505 return; 1506 } 1507 1508#if defined(TCB_WAITEXECVE) 1509 if ( sys_execve == func 1510# if defined(SPARC) || defined(SPARC64) 1511 || sys_execv == func 1512# endif 1513 ) { 1514 internal_exec(tcp); 1515 return; 1516 } 1517#endif 1518} 1519 1520/* Return -1 on error or 1 on success (never 0!) */ 1521static int 1522get_syscall_args(struct tcb *tcp) 1523{ 1524 int i, nargs; 1525 1526 if (SCNO_IN_RANGE(tcp->scno)) 1527 nargs = tcp->u_nargs = sysent[tcp->scno].nargs; 1528 else 1529 nargs = tcp->u_nargs = MAX_ARGS; 1530 1531#if defined(S390) || defined(S390X) 1532 for (i = 0; i < nargs; ++i) 1533 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0) 1534 return -1; 1535#elif defined(ALPHA) 1536 for (i = 0; i < nargs; ++i) 1537 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0) 1538 return -1; 1539#elif defined(IA64) 1540 if (!ia32) { 1541 unsigned long *out0, cfm, sof, sol; 1542 long rbs_end; 1543 /* be backwards compatible with kernel < 2.4.4... */ 1544# ifndef PT_RBS_END 1545# define PT_RBS_END PT_AR_BSP 1546# endif 1547 1548 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0) 1549 return -1; 1550 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1551 return -1; 1552 1553 sof = (cfm >> 0) & 0x7f; 1554 sol = (cfm >> 7) & 0x7f; 1555 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol); 1556 1557 for (i = 0; i < nargs; ++i) { 1558 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i), 1559 sizeof(long), (char *) &tcp->u_arg[i]) < 0) 1560 return -1; 1561 } 1562 } else { 1563 static const int argreg[MAX_ARGS] = { PT_R11 /* EBX = out0 */, 1564 PT_R9 /* ECX = out1 */, 1565 PT_R10 /* EDX = out2 */, 1566 PT_R14 /* ESI = out3 */, 1567 PT_R15 /* EDI = out4 */, 1568 PT_R13 /* EBP = out5 */}; 1569 1570 for (i = 0; i < nargs; ++i) { 1571 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 1572 return -1; 1573 /* truncate away IVE sign-extension */ 1574 tcp->u_arg[i] &= 0xffffffff; 1575 } 1576 } 1577#elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64) 1578 /* N32 and N64 both use up to six registers. */ 1579 unsigned long long regs[38]; 1580 1581 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1582 return -1; 1583 1584 for (i = 0; i < nargs; ++i) { 1585 tcp->u_arg[i] = regs[REG_A0 + i]; 1586# if defined(LINUX_MIPSN32) 1587 tcp->ext_arg[i] = regs[REG_A0 + i]; 1588# endif 1589 } 1590#elif defined(MIPS) 1591 if (nargs > 4) { 1592 long sp; 1593 1594 if (upeek(tcp, REG_SP, &sp) < 0) 1595 return -1; 1596 for (i = 0; i < 4; ++i) 1597 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 1598 return -1; 1599 umoven(tcp, sp + 16, (nargs - 4) * sizeof(tcp->u_arg[0]), 1600 (char *)(tcp->u_arg + 4)); 1601 } else { 1602 for (i = 0; i < nargs; ++i) 1603 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 1604 return -1; 1605 } 1606#elif defined(POWERPC) 1607# ifndef PT_ORIG_R3 1608# define PT_ORIG_R3 34 1609# endif 1610 for (i = 0; i < nargs; ++i) { 1611 if (upeek(tcp, (i==0) ? 1612 (sizeof(unsigned long) * PT_ORIG_R3) : 1613 ((i+PT_R3) * sizeof(unsigned long)), 1614 &tcp->u_arg[i]) < 0) 1615 return -1; 1616 } 1617#elif defined(SPARC) || defined(SPARC64) 1618 for (i = 0; i < nargs; ++i) 1619 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i]; 1620#elif defined(HPPA) 1621 for (i = 0; i < nargs; ++i) 1622 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0) 1623 return -1; 1624#elif defined(ARM) || defined(AARCH64) 1625# if defined(AARCH64) 1626 if (tcp->currpers == 1) 1627 for (i = 0; i < nargs; ++i) 1628 tcp->u_arg[i] = aarch64_regs.regs[i]; 1629 else 1630# endif /* AARCH64 */ 1631 for (i = 0; i < nargs; ++i) 1632 tcp->u_arg[i] = regs.uregs[i]; 1633#elif defined(AVR32) 1634 (void)i; 1635 (void)nargs; 1636 tcp->u_arg[0] = regs.r12; 1637 tcp->u_arg[1] = regs.r11; 1638 tcp->u_arg[2] = regs.r10; 1639 tcp->u_arg[3] = regs.r9; 1640 tcp->u_arg[4] = regs.r5; 1641 tcp->u_arg[5] = regs.r3; 1642#elif defined(BFIN) 1643 static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 }; 1644 1645 for (i = 0; i < nargs; ++i) 1646 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 1647 return -1; 1648#elif defined(SH) 1649 static const int syscall_regs[MAX_ARGS] = { 1650 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6), 1651 4 * (REG_REG0+7), 4 * (REG_REG0 ), 4 * (REG_REG0+1) 1652 }; 1653 1654 for (i = 0; i < nargs; ++i) 1655 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0) 1656 return -1; 1657#elif defined(SH64) 1658 int i; 1659 /* Registers used by SH5 Linux system calls for parameters */ 1660 static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 }; 1661 1662 for (i = 0; i < nargs; ++i) 1663 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0) 1664 return -1; 1665#elif defined(X86_64) || defined(X32) 1666 (void)i; 1667 (void)nargs; 1668 if (current_personality != 1) { /* x86-64 or x32 ABI */ 1669 tcp->u_arg[0] = x86_64_regs.rdi; 1670 tcp->u_arg[1] = x86_64_regs.rsi; 1671 tcp->u_arg[2] = x86_64_regs.rdx; 1672 tcp->u_arg[3] = x86_64_regs.r10; 1673 tcp->u_arg[4] = x86_64_regs.r8; 1674 tcp->u_arg[5] = x86_64_regs.r9; 1675# ifdef X32 1676 tcp->ext_arg[0] = x86_64_regs.rdi; 1677 tcp->ext_arg[1] = x86_64_regs.rsi; 1678 tcp->ext_arg[2] = x86_64_regs.rdx; 1679 tcp->ext_arg[3] = x86_64_regs.r10; 1680 tcp->ext_arg[4] = x86_64_regs.r8; 1681 tcp->ext_arg[5] = x86_64_regs.r9; 1682# endif 1683 } else { /* i386 ABI */ 1684 /* Sign-extend lower 32 bits */ 1685 tcp->u_arg[0] = (long)(int)x86_64_regs.rbx; 1686 tcp->u_arg[1] = (long)(int)x86_64_regs.rcx; 1687 tcp->u_arg[2] = (long)(int)x86_64_regs.rdx; 1688 tcp->u_arg[3] = (long)(int)x86_64_regs.rsi; 1689 tcp->u_arg[4] = (long)(int)x86_64_regs.rdi; 1690 tcp->u_arg[5] = (long)(int)x86_64_regs.rbp; 1691 } 1692#elif defined(MICROBLAZE) 1693 for (i = 0; i < nargs; ++i) 1694 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0) 1695 return -1; 1696#elif defined(CRISV10) || defined(CRISV32) 1697 static const int crisregs[MAX_ARGS] = { 1698 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12, 1699 4*PT_R13 , 4*PT_MOF, 4*PT_SRP 1700 }; 1701 1702 for (i = 0; i < nargs; ++i) 1703 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0) 1704 return -1; 1705#elif defined(TILE) 1706 for (i = 0; i < nargs; ++i) 1707 tcp->u_arg[i] = tile_regs.regs[i]; 1708#elif defined(M68K) 1709 for (i = 0; i < nargs; ++i) 1710 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0) 1711 return -1; 1712#elif defined(I386) 1713 (void)i; 1714 (void)nargs; 1715 tcp->u_arg[0] = i386_regs.ebx; 1716 tcp->u_arg[1] = i386_regs.ecx; 1717 tcp->u_arg[2] = i386_regs.edx; 1718 tcp->u_arg[3] = i386_regs.esi; 1719 tcp->u_arg[4] = i386_regs.edi; 1720 tcp->u_arg[5] = i386_regs.ebp; 1721#else /* Other architecture (32bits specific) */ 1722 for (i = 0; i < nargs; ++i) 1723 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0) 1724 return -1; 1725#endif 1726 return 1; 1727} 1728 1729static int 1730trace_syscall_entering(struct tcb *tcp) 1731{ 1732 int res, scno_good; 1733 1734#if defined TCB_WAITEXECVE 1735 if (tcp->flags & TCB_WAITEXECVE) { 1736 /* This is the post-execve SIGTRAP. */ 1737 tcp->flags &= ~TCB_WAITEXECVE; 1738 return 0; 1739 } 1740#endif 1741 1742 scno_good = res = (get_regs_error ? -1 : get_scno(tcp)); 1743 if (res == 0) 1744 return res; 1745 if (res == 1) { 1746 res = syscall_fixup_on_sysenter(tcp); 1747 if (res == 0) 1748 return res; 1749 if (res == 1) 1750 res = get_syscall_args(tcp); 1751 } 1752 1753 if (res != 1) { 1754 printleader(tcp); 1755 if (scno_good != 1) 1756 tprints("????" /* anti-trigraph gap */ "("); 1757 else if (!SCNO_IN_RANGE(tcp->scno)) 1758 tprintf("syscall_%lu(", tcp->scno); 1759 else 1760 tprintf("%s(", sysent[tcp->scno].sys_name); 1761 /* 1762 * " <unavailable>" will be added later by the code which 1763 * detects ptrace errors. 1764 */ 1765 goto ret; 1766 } 1767 1768#if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall) 1769 while (SCNO_IN_RANGE(tcp->scno)) { 1770# ifdef SYS_socket_subcall 1771 if (sysent[tcp->scno].sys_func == sys_socketcall) { 1772 decode_socket_subcall(tcp); 1773 break; 1774 } 1775# endif 1776# ifdef SYS_ipc_subcall 1777 if (sysent[tcp->scno].sys_func == sys_ipc) { 1778 decode_ipc_subcall(tcp); 1779 break; 1780 } 1781# endif 1782 break; 1783 } 1784#endif /* SYS_socket_subcall || SYS_ipc_subcall */ 1785 1786 if (need_fork_exec_workarounds) 1787 syscall_fixup_for_fork_exec(tcp); 1788 1789 if ((SCNO_IN_RANGE(tcp->scno) && 1790 !(qual_flags[tcp->scno] & QUAL_TRACE)) || 1791 (tracing_paths && !pathtrace_match(tcp))) { 1792 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED; 1793 return 0; 1794 } 1795 1796 tcp->flags &= ~TCB_FILTERED; 1797 1798 if (cflag == CFLAG_ONLY_STATS) { 1799 res = 0; 1800 goto ret; 1801 } 1802 1803 printleader(tcp); 1804 if (!SCNO_IN_RANGE(tcp->scno)) 1805 tprintf("syscall_%lu(", tcp->scno); 1806 else 1807 tprintf("%s(", sysent[tcp->scno].sys_name); 1808 if (!SCNO_IN_RANGE(tcp->scno) || 1809 ((qual_flags[tcp->scno] & QUAL_RAW) && 1810 sysent[tcp->scno].sys_func != sys_exit)) 1811 res = printargs(tcp); 1812 else 1813 res = (*sysent[tcp->scno].sys_func)(tcp); 1814 1815 fflush(tcp->outf); 1816 ret: 1817 tcp->flags |= TCB_INSYSCALL; 1818 /* Measure the entrance time as late as possible to avoid errors. */ 1819 if (Tflag || cflag) 1820 gettimeofday(&tcp->etime, NULL); 1821 return res; 1822} 1823 1824/* Returns: 1825 * 1: ok, continue in trace_syscall_exiting(). 1826 * -1: error, trace_syscall_exiting() should print error indicator 1827 * ("????" etc) and bail out. 1828 */ 1829static int 1830get_syscall_result(struct tcb *tcp) 1831{ 1832#if defined(S390) || defined(S390X) 1833 if (upeek(tcp, PT_GPR2, &gpr2) < 0) 1834 return -1; 1835#elif defined(POWERPC) 1836# define SO_MASK 0x10000000 1837 { 1838 long flags; 1839 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1840 return -1; 1841 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &ppc_result) < 0) 1842 return -1; 1843 if (flags & SO_MASK) 1844 ppc_result = -ppc_result; 1845 } 1846#elif defined(AVR32) 1847 /* already done by get_regs */ 1848#elif defined(BFIN) 1849 if (upeek(tcp, PT_R0, &r0) < 0) 1850 return -1; 1851#elif defined(I386) 1852 /* already done by get_regs */ 1853#elif defined(X86_64) || defined(X32) 1854 /* already done by get_regs */ 1855#elif defined(IA64) 1856# define IA64_PSR_IS ((long)1 << 34) 1857 long psr; 1858 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 1859 ia32 = (psr & IA64_PSR_IS) != 0; 1860 if (upeek(tcp, PT_R8, &r8) < 0) 1861 return -1; 1862 if (upeek(tcp, PT_R10, &r10) < 0) 1863 return -1; 1864#elif defined(AARCH64) 1865/* FIXME: uh, why do we do it on syscall *exit*? We did it on entry already... */ 1866 /* We are in 64-bit mode (personality 1) if register struct is aarch64_regs, 1867 * else it's personality 0. 1868 */ 1869 update_personality(tcp, aarch64_io.iov_len == sizeof(aarch64_regs)); 1870#elif defined(ARM) 1871 /* already done by get_regs */ 1872#elif defined(M68K) 1873 if (upeek(tcp, 4*PT_D0, &d0) < 0) 1874 return -1; 1875#elif defined(LINUX_MIPSN32) 1876 unsigned long long regs[38]; 1877 1878 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1879 return -1; 1880 a3 = regs[REG_A3]; 1881 r2 = regs[REG_V0]; 1882#elif defined(MIPS) 1883 if (upeek(tcp, REG_A3, &a3) < 0) 1884 return -1; 1885 if (upeek(tcp, REG_V0, &r2) < 0) 1886 return -1; 1887#elif defined(ALPHA) 1888 if (upeek(tcp, REG_A3, &a3) < 0) 1889 return -1; 1890 if (upeek(tcp, REG_R0, &r0) < 0) 1891 return -1; 1892#elif defined(SPARC) || defined(SPARC64) 1893 /* already done by get_regs */ 1894#elif defined(HPPA) 1895 if (upeek(tcp, PT_GR28, &r28) < 0) 1896 return -1; 1897#elif defined(SH) 1898 /* new syscall ABI returns result in R0 */ 1899 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1900 return -1; 1901#elif defined(SH64) 1902 /* ABI defines result returned in r9 */ 1903 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1904 return -1; 1905#elif defined(CRISV10) || defined(CRISV32) 1906 if (upeek(tcp, 4*PT_R10, &r10) < 0) 1907 return -1; 1908#elif defined(TILE) 1909 /* already done by get_regs */ 1910#elif defined(MICROBLAZE) 1911 if (upeek(tcp, 3 * 4, &r3) < 0) 1912 return -1; 1913#endif 1914 return 1; 1915} 1916 1917/* Called at each syscall exit */ 1918static void 1919syscall_fixup_on_sysexit(struct tcb *tcp) 1920{ 1921#if defined(S390) || defined(S390X) 1922 if (syscall_mode != -ENOSYS) 1923 syscall_mode = tcp->scno; 1924 if ((tcp->flags & TCB_WAITEXECVE) 1925 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) { 1926 /* 1927 * Return from execve. 1928 * Fake a return value of zero. We leave the TCB_WAITEXECVE 1929 * flag set for the post-execve SIGTRAP to see and reset. 1930 */ 1931 gpr2 = 0; 1932 } 1933#endif 1934} 1935 1936/* 1937 * Check the syscall return value register value for whether it is 1938 * a negated errno code indicating an error, or a success return value. 1939 */ 1940static inline int 1941is_negated_errno(unsigned long int val) 1942{ 1943 unsigned long int max = -(long int) nerrnos; 1944#if SUPPORTED_PERSONALITIES > 1 1945 if (current_wordsize < sizeof(val)) { 1946 val = (unsigned int) val; 1947 max = (unsigned int) max; 1948 } 1949#endif 1950 return val > max; 1951} 1952 1953/* Returns: 1954 * 1: ok, continue in trace_syscall_exiting(). 1955 * -1: error, trace_syscall_exiting() should print error indicator 1956 * ("????" etc) and bail out. 1957 */ 1958static int 1959get_error(struct tcb *tcp) 1960{ 1961 int u_error = 0; 1962 int check_errno = 1; 1963 if (SCNO_IN_RANGE(tcp->scno) && 1964 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) { 1965 check_errno = 0; 1966 } 1967#if defined(S390) || defined(S390X) 1968 if (check_errno && is_negated_errno(gpr2)) { 1969 tcp->u_rval = -1; 1970 u_error = -gpr2; 1971 } 1972 else { 1973 tcp->u_rval = gpr2; 1974 } 1975#elif defined(I386) 1976 if (check_errno && is_negated_errno(i386_regs.eax)) { 1977 tcp->u_rval = -1; 1978 u_error = -i386_regs.eax; 1979 } 1980 else { 1981 tcp->u_rval = i386_regs.eax; 1982 } 1983#elif defined(X86_64) || defined(X32) 1984 if (check_errno && is_negated_errno(x86_64_regs.rax)) { 1985 tcp->u_rval = -1; 1986 u_error = -x86_64_regs.rax; 1987 } 1988 else { 1989 tcp->u_rval = x86_64_regs.rax; 1990# if defined(X32) 1991 tcp->u_lrval = x86_64_regs.rax; 1992# endif 1993 } 1994#elif defined(IA64) 1995 if (ia32) { 1996 int err; 1997 1998 err = (int)r8; 1999 if (check_errno && is_negated_errno(err)) { 2000 tcp->u_rval = -1; 2001 u_error = -err; 2002 } 2003 else { 2004 tcp->u_rval = err; 2005 } 2006 } else { 2007 if (check_errno && r10) { 2008 tcp->u_rval = -1; 2009 u_error = r8; 2010 } else { 2011 tcp->u_rval = r8; 2012 } 2013 } 2014#elif defined(MIPS) 2015 if (check_errno && a3) { 2016 tcp->u_rval = -1; 2017 u_error = r2; 2018 } else { 2019 tcp->u_rval = r2; 2020# if defined(LINUX_MIPSN32) 2021 tcp->u_lrval = r2; 2022# endif 2023 } 2024#elif defined(POWERPC) 2025 if (check_errno && is_negated_errno(ppc_result)) { 2026 tcp->u_rval = -1; 2027 u_error = -ppc_result; 2028 } 2029 else { 2030 tcp->u_rval = ppc_result; 2031 } 2032#elif defined(M68K) 2033 if (check_errno && is_negated_errno(d0)) { 2034 tcp->u_rval = -1; 2035 u_error = -d0; 2036 } 2037 else { 2038 tcp->u_rval = d0; 2039 } 2040#elif defined(ARM) || defined(AARCH64) 2041# if defined(AARCH64) 2042 if (tcp->currpers == 1) { 2043 if (check_errno && is_negated_errno(aarch64_regs.regs[0])) { 2044 tcp->u_rval = -1; 2045 u_error = -aarch64_regs.regs[0]; 2046 } 2047 else { 2048 tcp->u_rval = aarch64_regs.regs[0]; 2049 } 2050 } 2051 else 2052# endif /* AARCH64 */ 2053 { 2054 if (check_errno && is_negated_errno(regs.ARM_r0)) { 2055 tcp->u_rval = -1; 2056 u_error = -regs.ARM_r0; 2057 } 2058 else { 2059 tcp->u_rval = regs.ARM_r0; 2060 } 2061 } 2062#elif defined(AVR32) 2063 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) { 2064 tcp->u_rval = -1; 2065 u_error = -regs.r12; 2066 } 2067 else { 2068 tcp->u_rval = regs.r12; 2069 } 2070#elif defined(BFIN) 2071 if (check_errno && is_negated_errno(r0)) { 2072 tcp->u_rval = -1; 2073 u_error = -r0; 2074 } else { 2075 tcp->u_rval = r0; 2076 } 2077#elif defined(ALPHA) 2078 if (check_errno && a3) { 2079 tcp->u_rval = -1; 2080 u_error = r0; 2081 } 2082 else { 2083 tcp->u_rval = r0; 2084 } 2085#elif defined(SPARC) 2086 if (check_errno && regs.psr & PSR_C) { 2087 tcp->u_rval = -1; 2088 u_error = regs.u_regs[U_REG_O0]; 2089 } 2090 else { 2091 tcp->u_rval = regs.u_regs[U_REG_O0]; 2092 } 2093#elif defined(SPARC64) 2094 if (check_errno && regs.tstate & 0x1100000000UL) { 2095 tcp->u_rval = -1; 2096 u_error = regs.u_regs[U_REG_O0]; 2097 } 2098 else { 2099 tcp->u_rval = regs.u_regs[U_REG_O0]; 2100 } 2101#elif defined(HPPA) 2102 if (check_errno && is_negated_errno(r28)) { 2103 tcp->u_rval = -1; 2104 u_error = -r28; 2105 } 2106 else { 2107 tcp->u_rval = r28; 2108 } 2109#elif defined(SH) 2110 if (check_errno && is_negated_errno(r0)) { 2111 tcp->u_rval = -1; 2112 u_error = -r0; 2113 } 2114 else { 2115 tcp->u_rval = r0; 2116 } 2117#elif defined(SH64) 2118 if (check_errno && is_negated_errno(r9)) { 2119 tcp->u_rval = -1; 2120 u_error = -r9; 2121 } 2122 else { 2123 tcp->u_rval = r9; 2124 } 2125#elif defined(CRISV10) || defined(CRISV32) 2126 if (check_errno && r10 && (unsigned) -r10 < nerrnos) { 2127 tcp->u_rval = -1; 2128 u_error = -r10; 2129 } 2130 else { 2131 tcp->u_rval = r10; 2132 } 2133#elif defined(TILE) 2134 /* 2135 * The standard tile calling convention returns the value (or negative 2136 * errno) in r0, and zero (or positive errno) in r1. 2137 * Until at least kernel 3.8, however, the r1 value is not reflected 2138 * in ptregs at this point, so we use r0 here. 2139 */ 2140 if (check_errno && is_negated_errno(tile_regs.regs[0])) { 2141 tcp->u_rval = -1; 2142 u_error = -tile_regs.regs[0]; 2143 } else { 2144 tcp->u_rval = tile_regs.regs[0]; 2145 } 2146#elif defined(MICROBLAZE) 2147 if (check_errno && is_negated_errno(r3)) { 2148 tcp->u_rval = -1; 2149 u_error = -r3; 2150 } 2151 else { 2152 tcp->u_rval = r3; 2153 } 2154#endif 2155 tcp->u_error = u_error; 2156 return 1; 2157} 2158 2159static void 2160dumpio(struct tcb *tcp) 2161{ 2162 if (syserror(tcp)) 2163 return; 2164 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS) 2165 return; 2166 if (!SCNO_IN_RANGE(tcp->scno)) 2167 return; 2168 if (sysent[tcp->scno].sys_func == printargs) 2169 return; 2170 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) { 2171 if (sysent[tcp->scno].sys_func == sys_read || 2172 sysent[tcp->scno].sys_func == sys_pread || 2173 sysent[tcp->scno].sys_func == sys_recv || 2174 sysent[tcp->scno].sys_func == sys_recvfrom) 2175 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval); 2176 else if (sysent[tcp->scno].sys_func == sys_readv) 2177 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 2178 return; 2179 } 2180 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) { 2181 if (sysent[tcp->scno].sys_func == sys_write || 2182 sysent[tcp->scno].sys_func == sys_pwrite || 2183 sysent[tcp->scno].sys_func == sys_send || 2184 sysent[tcp->scno].sys_func == sys_sendto) 2185 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 2186 else if (sysent[tcp->scno].sys_func == sys_writev) 2187 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 2188 return; 2189 } 2190} 2191 2192static int 2193trace_syscall_exiting(struct tcb *tcp) 2194{ 2195 int sys_res; 2196 struct timeval tv; 2197 int res; 2198 long u_error; 2199 2200 /* Measure the exit time as early as possible to avoid errors. */ 2201 if (Tflag || cflag) 2202 gettimeofday(&tv, NULL); 2203 2204#if SUPPORTED_PERSONALITIES > 1 2205 update_personality(tcp, tcp->currpers); 2206#endif 2207 res = (get_regs_error ? -1 : get_syscall_result(tcp)); 2208 if (res == 1) { 2209 syscall_fixup_on_sysexit(tcp); /* never fails */ 2210 res = get_error(tcp); /* returns 1 or -1 */ 2211 if (res == 1) { 2212 if (need_fork_exec_workarounds) 2213 syscall_fixup_for_fork_exec(tcp); 2214 if (filtered(tcp)) { 2215 goto ret; 2216 } 2217 } 2218 } 2219 2220 if (cflag) { 2221 struct timeval t = tv; 2222 count_syscall(tcp, &t); 2223 if (cflag == CFLAG_ONLY_STATS) { 2224 goto ret; 2225 } 2226 } 2227 2228 /* If not in -ff mode, and printing_tcp != tcp, 2229 * then the log currently does not end with output 2230 * of _our syscall entry_, but with something else. 2231 * We need to say which syscall's return is this. 2232 * 2233 * Forced reprinting via TCB_REPRINT is used only by 2234 * "strace -ff -oLOG test/threaded_execve" corner case. 2235 * It's the only case when -ff mode needs reprinting. 2236 */ 2237 if ((followfork < 2 && printing_tcp != tcp) || (tcp->flags & TCB_REPRINT)) { 2238 tcp->flags &= ~TCB_REPRINT; 2239 printleader(tcp); 2240 if (!SCNO_IN_RANGE(tcp->scno)) 2241 tprintf("<... syscall_%lu resumed> ", tcp->scno); 2242 else 2243 tprintf("<... %s resumed> ", sysent[tcp->scno].sys_name); 2244 } 2245 printing_tcp = tcp; 2246 2247 if (res != 1) { 2248 /* There was error in one of prior ptrace ops */ 2249 tprints(") "); 2250 tabto(); 2251 tprints("= ? <unavailable>\n"); 2252 line_ended(); 2253 tcp->flags &= ~TCB_INSYSCALL; 2254 return res; 2255 } 2256 2257 sys_res = 0; 2258 if (!SCNO_IN_RANGE(tcp->scno) 2259 || (qual_flags[tcp->scno] & QUAL_RAW)) { 2260 /* sys_res = printargs(tcp); - but it's nop on sysexit */ 2261 } else { 2262 /* FIXME: not_failing_only (IOW, option -z) is broken: 2263 * failure of syscall is known only after syscall return. 2264 * Thus we end up with something like this on, say, ENOENT: 2265 * open("doesnt_exist", O_RDONLY <unfinished ...> 2266 * {next syscall decode} 2267 * whereas the intended result is that open(...) line 2268 * is not shown at all. 2269 */ 2270 if (not_failing_only && tcp->u_error) 2271 goto ret; /* ignore failed syscalls */ 2272 sys_res = (*sysent[tcp->scno].sys_func)(tcp); 2273 } 2274 2275 tprints(") "); 2276 tabto(); 2277 u_error = tcp->u_error; 2278 if (!SCNO_IN_RANGE(tcp->scno) || 2279 qual_flags[tcp->scno] & QUAL_RAW) { 2280 if (u_error) 2281 tprintf("= -1 (errno %ld)", u_error); 2282 else 2283 tprintf("= %#lx", tcp->u_rval); 2284 } 2285 else if (!(sys_res & RVAL_NONE) && u_error) { 2286 switch (u_error) { 2287 /* Blocked signals do not interrupt any syscalls. 2288 * In this case syscalls don't return ERESTARTfoo codes. 2289 * 2290 * Deadly signals set to SIG_DFL interrupt syscalls 2291 * and kill the process regardless of which of the codes below 2292 * is returned by the interrupted syscall. 2293 * In some cases, kernel forces a kernel-generated deadly 2294 * signal to be unblocked and set to SIG_DFL (and thus cause 2295 * death) if it is blocked or SIG_IGNed: for example, SIGSEGV 2296 * or SIGILL. (The alternative is to leave process spinning 2297 * forever on the faulty instruction - not useful). 2298 * 2299 * SIG_IGNed signals and non-deadly signals set to SIG_DFL 2300 * (for example, SIGCHLD, SIGWINCH) interrupt syscalls, 2301 * but kernel will always restart them. 2302 */ 2303 case ERESTARTSYS: 2304 /* Most common type of signal-interrupted syscall exit code. 2305 * The system call will be restarted with the same arguments 2306 * if SA_RESTART is set; otherwise, it will fail with EINTR. 2307 */ 2308 tprints("= ? ERESTARTSYS (To be restarted if SA_RESTART is set)"); 2309 break; 2310 case ERESTARTNOINTR: 2311 /* Rare. For example, fork() returns this if interrupted. 2312 * SA_RESTART is ignored (assumed set): the restart is unconditional. 2313 */ 2314 tprints("= ? ERESTARTNOINTR (To be restarted)"); 2315 break; 2316 case ERESTARTNOHAND: 2317 /* pause(), rt_sigsuspend() etc use this code. 2318 * SA_RESTART is ignored (assumed not set): 2319 * syscall won't restart (will return EINTR instead) 2320 * even after signal with SA_RESTART set. 2321 * However, after SIG_IGN or SIG_DFL signal it will. 2322 */ 2323 tprints("= ? ERESTARTNOHAND (Interrupted by signal)"); 2324 break; 2325 case ERESTART_RESTARTBLOCK: 2326 /* Syscalls like nanosleep(), poll() which can't be 2327 * restarted with their original arguments use this 2328 * code. Kernel will execute restart_syscall() instead, 2329 * which changes arguments before restarting syscall. 2330 * SA_RESTART is ignored (assumed not set) similarly 2331 * to ERESTARTNOHAND. (Kernel can't honor SA_RESTART 2332 * since restart data is saved in "restart block" 2333 * in task struct, and if signal handler uses a syscall 2334 * which in turn saves another such restart block, 2335 * old data is lost and restart becomes impossible) 2336 */ 2337 tprints("= ? ERESTART_RESTARTBLOCK (Interrupted by signal)"); 2338 break; 2339 default: 2340 if (u_error < 0) 2341 tprintf("= -1 E??? (errno %ld)", u_error); 2342 else if (u_error < nerrnos) 2343 tprintf("= -1 %s (%s)", errnoent[u_error], 2344 strerror(u_error)); 2345 else 2346 tprintf("= -1 ERRNO_%ld (%s)", u_error, 2347 strerror(u_error)); 2348 break; 2349 } 2350 if ((sys_res & RVAL_STR) && tcp->auxstr) 2351 tprintf(" (%s)", tcp->auxstr); 2352 } 2353 else { 2354 if (sys_res & RVAL_NONE) 2355 tprints("= ?"); 2356 else { 2357 switch (sys_res & RVAL_MASK) { 2358 case RVAL_HEX: 2359 tprintf("= %#lx", tcp->u_rval); 2360 break; 2361 case RVAL_OCTAL: 2362 tprintf("= %#lo", tcp->u_rval); 2363 break; 2364 case RVAL_UDECIMAL: 2365 tprintf("= %lu", tcp->u_rval); 2366 break; 2367 case RVAL_DECIMAL: 2368 tprintf("= %ld", tcp->u_rval); 2369 break; 2370#if defined(LINUX_MIPSN32) || defined(X32) 2371 /* 2372 case RVAL_LHEX: 2373 tprintf("= %#llx", tcp->u_lrval); 2374 break; 2375 case RVAL_LOCTAL: 2376 tprintf("= %#llo", tcp->u_lrval); 2377 break; 2378 */ 2379 case RVAL_LUDECIMAL: 2380 tprintf("= %llu", tcp->u_lrval); 2381 break; 2382 /* 2383 case RVAL_LDECIMAL: 2384 tprintf("= %lld", tcp->u_lrval); 2385 break; 2386 */ 2387#endif 2388 default: 2389 fprintf(stderr, 2390 "invalid rval format\n"); 2391 break; 2392 } 2393 } 2394 if ((sys_res & RVAL_STR) && tcp->auxstr) 2395 tprintf(" (%s)", tcp->auxstr); 2396 } 2397 if (Tflag) { 2398 tv_sub(&tv, &tv, &tcp->etime); 2399 tprintf(" <%ld.%06ld>", 2400 (long) tv.tv_sec, (long) tv.tv_usec); 2401 } 2402 tprints("\n"); 2403 dumpio(tcp); 2404 line_ended(); 2405 2406 ret: 2407 tcp->flags &= ~TCB_INSYSCALL; 2408 return 0; 2409} 2410 2411int 2412trace_syscall(struct tcb *tcp) 2413{ 2414 return exiting(tcp) ? 2415 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp); 2416} 2417