syscall.c revision b7a6dae9fb15cd9f71d72861097c6c0e8608e88e
11ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell/* 21ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl> 31ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl> 41ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com> 51ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl> 61ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 71ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Linux for s390 port by D.J. Barrow 81ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com> 91ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * All rights reserved. 101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * 111ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * Redistribution and use in source and binary forms, with or without 121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * modification, are permitted provided that the following conditions 131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * are met: 141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * 1. Redistributions of source code must retain the above copyright 151ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * notice, this list of conditions and the following disclaimer. 161ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * 2. Redistributions in binary form must reproduce the above copyright 171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * notice, this list of conditions and the following disclaimer in the 181ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * documentation and/or other materials provided with the distribution. 191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * 3. The name of the author may not be used to endorse or promote products 201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * derived from this software without specific prior written permission. 211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * 221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 241ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 251ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 261ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 271ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 281ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 291ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 311ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell */ 331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "defs.h" 351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include <sys/user.h> 361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include <sys/param.h> 371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifdef HAVE_SYS_REG_H 391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include <sys/reg.h> 401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# ifndef PTRACE_PEEKUSR 411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define PTRACE_PEEKUSR PTRACE_PEEKUSER 421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#elif defined(HAVE_LINUX_PTRACE_H) 441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef PTRACE_SYSCALL 451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# ifdef HAVE_STRUCT_IA64_FPREG 461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define ia64_fpreg XXX_ia64_fpreg 471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# ifdef HAVE_STRUCT_PT_ALL_USER_REGS 491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define pt_all_user_regs XXX_pt_all_user_regs 501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include <linux/ptrace.h> 521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef ia64_fpreg 531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef pt_all_user_regs 541ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if defined(SPARC64) 571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef PTRACE_GETREGS 581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define PTRACE_GETREGS PTRACE_GETREGS64 591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef PTRACE_SETREGS 601ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define PTRACE_SETREGS PTRACE_SETREGS64 611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 631ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if defined(IA64) 641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include <asm/ptrace_offsets.h> 651ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include <asm/rse.h> 661ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 671ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 681ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifndef ERESTARTSYS 691ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define ERESTARTSYS 512 701ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 711ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifndef ERESTARTNOINTR 721ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define ERESTARTNOINTR 513 731ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 741ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifndef ERESTARTNOHAND 751ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define ERESTARTNOHAND 514 /* restart if no handler */ 76f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#endif 771ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifndef ERESTART_RESTARTBLOCK 781ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */ 791ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 801ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 811ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifndef NSIG 821ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# warning: NSIG is not defined, using 32 831ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define NSIG 32 841ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 851ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifdef ARM 861ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell/* Ugh. Is this really correct? ARM has no RT signals?! */ 871ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# undef NSIG 881ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# define NSIG 32 891ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 901ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 911ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "syscall.h" 921ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 931ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell/* Define these shorthand notations to simplify the syscallent files. */ 941ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TD TRACE_DESC 951ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TF TRACE_FILE 961ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TI TRACE_IPC 971ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TN TRACE_NETWORK 981ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TP TRACE_PROCESS 991ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define TS TRACE_SIGNAL 1001ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define NF SYSCALL_NEVER_FAILS 1011ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#define MA MAX_ARGS 1021ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1031ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct sysent sysent0[] = { 1041ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "syscallent.h" 1051ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1061ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1071ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 2 1081ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct sysent sysent1[] = { 1091ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "syscallent1.h" 1101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1111ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 1121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 3 1141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct sysent sysent2[] = { 1151ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "syscallent2.h" 1161ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 1181ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell/* Now undef them since short defines cause wicked namespace pollution. */ 1201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#undef TD 1211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#undef TF 1221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#undef TI 1231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#undef TN 124f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#undef TP 125f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#undef TS 126f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#undef NF 127f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#undef MA 128f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell 129f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell/* 1301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * `ioctlent.h' may be generated from `ioctlent.raw' by the auxiliary 1311ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * program `ioctlsort', such that the list is sorted by the `code' field. 1321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * This has the side-effect of resolving the _IO.. macros into 1331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * plain integers, eliminating the need to include here everything 1341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell * in "/usr/include". 1351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell */ 1361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const errnoent0[] = { 1381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "errnoent.h" 1391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const signalent0[] = { 1411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "signalent.h" 1421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct ioctlent ioctlent0[] = { 1441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#include "ioctlent.h" 1451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsyscalls0 = ARRAY_SIZE(sysent0) }; 1471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nerrnos0 = ARRAY_SIZE(errnoent0) }; 1481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsignals0 = ARRAY_SIZE(signalent0) }; 1491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nioctlents0 = ARRAY_SIZE(ioctlent0) }; 1501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint qual_flags0[MAX_QUALS]; 1511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 2 1531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const errnoent1[] = { 1541ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "errnoent1.h" 1551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const signalent1[] = { 1571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "signalent1.h" 1581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct ioctlent ioctlent1[] = { 1601ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "ioctlent1.h" 1611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsyscalls1 = ARRAY_SIZE(sysent1) }; 1631ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nerrnos1 = ARRAY_SIZE(errnoent1) }; 1641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsignals1 = ARRAY_SIZE(signalent1) }; 1651ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nioctlents1 = ARRAY_SIZE(ioctlent1) }; 1661ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint qual_flags1[MAX_QUALS]; 1671ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 1681ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1691ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 3 1701ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const errnoent2[] = { 1711ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "errnoent2.h" 1721ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1731ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const char *const signalent2[] = { 1741ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "signalent2.h" 1751ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1761ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct ioctlent ioctlent2[] = { 1771ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# include "ioctlent2.h" 1781ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 1791ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsyscalls2 = ARRAY_SIZE(sysent2) }; 1801ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nerrnos2 = ARRAY_SIZE(errnoent2) }; 1811ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nsignals2 = ARRAY_SIZE(signalent2) }; 1821ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellenum { nioctlents2 = ARRAY_SIZE(ioctlent2) }; 1831ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint qual_flags2[MAX_QUALS]; 1841ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 1851ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1861ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellconst struct sysent *sysent = sysent0; 1871ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellconst char *const *errnoent = errnoent0; 1881ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellconst char *const *signalent = signalent0; 1891ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellconst struct ioctlent *ioctlent = ioctlent0; 1901ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellunsigned nsyscalls = nsyscalls0; 1911ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellunsigned nerrnos = nerrnos0; 1921ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellunsigned nsignals = nsignals0; 1931ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellunsigned nioctlents = nioctlents0; 1941ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint *qual_flags = qual_flags0; 1951ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1961ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES > 1 1971ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint current_personality; 1981ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 1991ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellconst int personality_wordsize[SUPPORTED_PERSONALITIES] = { 2001ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell PERSONALITY0_WORDSIZE, 2011ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell PERSONALITY1_WORDSIZE, 2021ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# if SUPPORTED_PERSONALITIES > 2 2031ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell PERSONALITY2_WORDSIZE, 2041ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 2051ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 2061ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2071ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellvoid 2081ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellset_personality(int personality) 2091ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 2101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell switch (personality) { 2111ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell case 0: 2121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell errnoent = errnoent0; 2131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nerrnos = nerrnos0; 2141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell sysent = sysent0; 2151ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsyscalls = nsyscalls0; 2161ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell ioctlent = ioctlent0; 2171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nioctlents = nioctlents0; 2181ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell signalent = signalent0; 2191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsignals = nsignals0; 2201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags = qual_flags0; 2211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell break; 2221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell case 1: 2241ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell errnoent = errnoent1; 2251ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nerrnos = nerrnos1; 2261ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell sysent = sysent1; 2271ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsyscalls = nsyscalls1; 2281ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell ioctlent = ioctlent1; 2291ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nioctlents = nioctlents1; 2301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell signalent = signalent1; 2311ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsignals = nsignals1; 2321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags = qual_flags1; 2331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell break; 2341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# if SUPPORTED_PERSONALITIES >= 3 2361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell case 2: 2371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell errnoent = errnoent2; 2381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nerrnos = nerrnos2; 2391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell sysent = sysent2; 2401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsyscalls = nsyscalls2; 2411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell ioctlent = ioctlent2; 2421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nioctlents = nioctlents2; 2431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell signalent = signalent2; 2441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell nsignals = nsignals2; 2451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags = qual_flags2; 2461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell break; 2471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 2481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 2491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell current_personality = personality; 2511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 2521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic void 2541ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellupdate_personality(struct tcb *tcp, int personality) 2551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 2561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (personality == current_personality) 2571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 2581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell set_personality(personality); 2591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2601ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (personality == tcp->currpers) 2611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 2621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->currpers = personality; 2631ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# if defined(POWERPC64) || defined(X86_64) 2651ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (!qflag) { 2661ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell static const char *const names[] = {"64 bit", "32 bit"}; 2671ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n", 2681ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->pid, names[personality]); 2691ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 2701ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell# endif 2711ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 2721ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 2731ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2741ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic int qual_syscall(), qual_signal(), qual_fault(), qual_desc(); 2751ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 2761ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic const struct qual_options { 2771ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int bitflag; 2781ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell const char *option_name; 2791ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int (*qualify)(const char *, int, int); 2801ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell const char *argument_name; 2811ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} qual_options[] = { 2821ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_TRACE, "trace", qual_syscall, "system call" }, 2831ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_TRACE, "t", qual_syscall, "system call" }, 2841ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_ABBREV, "abbrev", qual_syscall, "system call" }, 2851ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_ABBREV, "a", qual_syscall, "system call" }, 2861ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_VERBOSE, "verbose", qual_syscall, "system call" }, 2871ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_VERBOSE, "v", qual_syscall, "system call" }, 2881ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_RAW, "raw", qual_syscall, "system call" }, 2891ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_RAW, "x", qual_syscall, "system call" }, 2901ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_SIGNAL, "signal", qual_signal, "signal" }, 2911ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_SIGNAL, "signals", qual_signal, "signal" }, 2921ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_SIGNAL, "s", qual_signal, "signal" }, 2931ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_FAULT, "fault", qual_fault, "fault" }, 2941ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_FAULT, "faults", qual_fault, "fault" }, 2951ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_FAULT, "m", qual_fault, "fault" }, 2961ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_READ, "read", qual_desc, "descriptor" }, 2971ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_READ, "reads", qual_desc, "descriptor" }, 2981ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_READ, "r", qual_desc, "descriptor" }, 2991ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_WRITE, "write", qual_desc, "descriptor" }, 3001ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_WRITE, "writes", qual_desc, "descriptor" }, 3011ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { QUAL_WRITE, "w", qual_desc, "descriptor" }, 3021ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell { 0, NULL, NULL, NULL }, 3031ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell}; 3041ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3051ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic void 3061ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqualify_one(int n, int bitflag, int not, int pers) 3071ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 3081ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (pers == 0 || pers < 0) { 3091ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (not) 3101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags0[n] &= ~bitflag; 311f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell else 3121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags0[n] |= bitflag; 3131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3151ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 2 3161ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (pers == 1 || pers < 0) { 3171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (not) 3181ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags1[n] &= ~bitflag; 3191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell else 3201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags1[n] |= bitflag; 3211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 3231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3241ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 3 3251ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (pers == 2 || pers < 0) { 3261ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (not) 3271ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags2[n] &= ~bitflag; 3281ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell else 3291ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qual_flags2[n] |= bitflag; 3301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3311ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 3321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 3331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic int 3351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqual_syscall(const char *s, int bitflag, int not) 3361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 3371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int i; 3381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int rc = -1; 3391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (isdigit((unsigned char)*s)) { 3411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int i = atoi(s); 3421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (i < 0 || i >= MAX_QUALS) 3431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 3441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, bitflag, not, -1); 3451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return 0; 3461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls0; i++) 3481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, sysent0[i].sys_name) == 0) { 3491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, bitflag, not, 0); 3501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell rc = 0; 3511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 2 3541ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls1; i++) 3551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, sysent1[i].sys_name) == 0) { 3561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, bitflag, not, 1); 3571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell rc = 0; 3581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 3601ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 3 3621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls2; i++) 3631ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, sysent2[i].sys_name) == 0) { 3641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, bitflag, not, 2); 365f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell rc = 0; 366f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell } 367f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell#endif 3681ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3691ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return rc; 3701ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 3711ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3721ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic int 3731ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqual_signal(const char *s, int bitflag, int not) 3741ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 3751ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int i; 3761ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell char buf[32]; 3771ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3781ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (isdigit((unsigned char)*s)) { 3791ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int signo = atoi(s); 3801ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (signo < 0 || signo >= MAX_QUALS) 3811ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 3821ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(signo, bitflag, not, -1); 3831ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return 0; 3841ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 3851ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strlen(s) >= sizeof buf) 3861ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 3871ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell strcpy(buf, s); 3881ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell s = buf; 3891ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strncasecmp(s, "SIG", 3) == 0) 3901ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell s += 3; 3911ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i <= NSIG; i++) 3921ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcasecmp(s, signame(i) + 3) == 0) { 3931ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, bitflag, not, -1); 3941ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return 0; 395f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell } 3961ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 3971ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 3981ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 3991ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic int 4001ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqual_fault(const char *s, int bitflag, int not) 4011ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 4021ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 4031ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 4041ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4051ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic int 4061ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqual_desc(const char *s, int bitflag, int not) 4071ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 4081ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (isdigit((unsigned char)*s)) { 4091ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int desc = atoi(s); 4101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (desc < 0 || desc >= MAX_QUALS) 4111ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 4121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(desc, bitflag, not, -1); 4131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return 0; 4141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4151ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 4161ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 4171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 418f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powellstatic int 4191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powelllookup_class(const char *s) 4201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 4211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "file") == 0) 4221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_FILE; 4231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "ipc") == 0) 4241ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_IPC; 4251ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "network") == 0) 4261ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_NETWORK; 4271ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "process") == 0) 4281ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_PROCESS; 4291ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "signal") == 0) 4301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_SIGNAL; 431f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell if (strcmp(s, "desc") == 0) 4321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return TRACE_DESC; 4331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return -1; 4341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 4351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellvoid 4371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellqualify(const char *s) 4381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 4391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell const struct qual_options *opt; 4401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int not; 4411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell char *copy; 4421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell const char *p; 4431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int i, n; 4441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell opt = &qual_options[0]; 4461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; (p = qual_options[i].option_name); i++) { 4471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell n = strlen(p); 4481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strncmp(s, p, n) == 0 && s[n] == '=') { 4491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell opt = &qual_options[i]; 4501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell s += n + 1; 4511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell break; 4521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 454f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell not = 0; 4551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (*s == '!') { 4561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell not = 1; 4571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell s++; 4581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (strcmp(s, "none") == 0) { 460f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell not = 1 - not; 4611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell s = "all"; 4621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 463f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell if (strcmp(s, "all") == 0) { 4641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < MAX_QUALS; i++) { 4651ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, opt->bitflag, not, -1); 4661ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4671ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 4681ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4691ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < MAX_QUALS; i++) { 4701ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, opt->bitflag, !not, -1); 4711ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4721ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell copy = strdup(s); 4731ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (!copy) 4741ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell die_out_of_memory(); 4751ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) { 4761ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) { 4771ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls0; i++) 4781ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (sysent0[i].sys_flags & n) 4791ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, opt->bitflag, not, 0); 4801ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4811ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 2 4821ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls1; i++) 4831ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (sysent1[i].sys_flags & n) 4841ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, opt->bitflag, not, 1); 4851ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 4861ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4871ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#if SUPPORTED_PERSONALITIES >= 3 4881ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < nsyscalls2; i++) 4891ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (sysent2[i].sys_flags & n) 4901ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell qualify_one(i, opt->bitflag, not, 2); 4911ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 4921ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 4931ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell continue; 4941ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4951ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (opt->qualify(p, opt->bitflag, not)) { 4961ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell error_msg_and_die("invalid %s '%s'", 4971ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell opt->argument_name, p); 4981ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 4991ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 5001ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell free(copy); 5011ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 5021ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 5031ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5041ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifdef SYS_socket_subcall 5051ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic void 5061ce805e30800bf2852fa5421b7277a18e089ee31Adam Powelldecode_socket_subcall(struct tcb *tcp) 5071ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 5081ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell unsigned long addr; 5091ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell unsigned int i, size; 5101ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5111ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls) 5121ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 5131ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5141ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->scno = SYS_socket_subcall + tcp->u_arg[0]; 515f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell addr = tcp->u_arg[1]; 516f48af3312a4f63d8ce232fe7476932c0201774d9Adam Powell tcp->u_nargs = sysent[tcp->scno].nargs; 5171ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell size = current_wordsize; 5181ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < tcp->u_nargs; ++i) { 5191ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (size == sizeof(int)) { 5201ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell unsigned int arg; 5211ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (umove(tcp, addr, &arg) < 0) 5221ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell arg = 0; 5231ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->u_arg[i] = arg; 5241ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 5251ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell else { 5261ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell unsigned long arg; 5271ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (umove(tcp, addr, &arg) < 0) 5281ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell arg = 0; 5291ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->u_arg[i] = arg; 5301ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 5311ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell addr += size; 5321ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 5331ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 5341ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 5351ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5361ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#ifdef SYS_ipc_subcall 5371ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellstatic void 5381ce805e30800bf2852fa5421b7277a18e089ee31Adam Powelldecode_ipc_subcall(struct tcb *tcp) 5391ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 5401ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell unsigned int i; 5411ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5421ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_ipc_nsubcalls) 5431ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return; 5441ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5451ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->scno = SYS_ipc_subcall + tcp->u_arg[0]; 5461ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->u_nargs = sysent[tcp->scno].nargs; 5471ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < tcp->u_nargs; i++) 5481ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tcp->u_arg[i] = tcp->u_arg[i + 1]; 5491ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 5501ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell#endif 5511ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5521ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint 5531ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellprintargs(struct tcb *tcp) 5541ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell{ 5551ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell if (entering(tcp)) { 5561ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell int i; 5571ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5581ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell for (i = 0; i < tcp->u_nargs; i++) 5591ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]); 5601ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell } 5611ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell return 0; 5621ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell} 5631ce805e30800bf2852fa5421b7277a18e089ee31Adam Powell 5641ce805e30800bf2852fa5421b7277a18e089ee31Adam Powellint 565printargs_lu(struct tcb *tcp) 566{ 567 if (entering(tcp)) { 568 int i; 569 570 for (i = 0; i < tcp->u_nargs; i++) 571 tprintf("%s%lu", i ? ", " : "", tcp->u_arg[i]); 572 } 573 return 0; 574} 575 576int 577printargs_ld(struct tcb *tcp) 578{ 579 if (entering(tcp)) { 580 int i; 581 582 for (i = 0; i < tcp->u_nargs; i++) 583 tprintf("%s%ld", i ? ", " : "", tcp->u_arg[i]); 584 } 585 return 0; 586} 587 588long 589getrval2(struct tcb *tcp) 590{ 591 long val = -1; 592 593#if defined(SPARC) || defined(SPARC64) 594 struct pt_regs regs; 595 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 596 return -1; 597 val = regs.u_regs[U_REG_O1]; 598#elif defined(SH) 599 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0) 600 return -1; 601#elif defined(IA64) 602 if (upeek(tcp, PT_R9, &val) < 0) 603 return -1; 604#endif 605 606 return val; 607} 608 609int 610is_restart_error(struct tcb *tcp) 611{ 612 switch (tcp->u_error) { 613 case ERESTARTSYS: 614 case ERESTARTNOINTR: 615 case ERESTARTNOHAND: 616 case ERESTART_RESTARTBLOCK: 617 return 1; 618 default: 619 break; 620 } 621 return 0; 622} 623 624#if defined(I386) 625struct pt_regs i386_regs; 626#elif defined(X86_64) 627/* 628 * On 32 bits, pt_regs and user_regs_struct are the same, 629 * but on 64 bits, user_regs_struct has six more fields: 630 * fs_base, gs_base, ds, es, fs, gs. 631 * PTRACE_GETREGS fills them too, so struct pt_regs would overflow. 632 */ 633static struct user_regs_struct x86_64_regs; 634#elif defined(IA64) 635long r8, r10, psr; /* TODO: make static? */ 636long ia32 = 0; /* not static */ 637#elif defined(POWERPC) 638static long result; 639#elif defined(M68K) 640static long d0; 641#elif defined(BFIN) 642static long r0; 643#elif defined(ARM) 644static struct pt_regs regs; 645#elif defined(ALPHA) 646static long r0; 647static long a3; 648#elif defined(AVR32) 649static struct pt_regs regs; 650#elif defined(SPARC) || defined(SPARC64) 651static struct pt_regs regs; 652static unsigned long trap; 653#elif defined(LINUX_MIPSN32) 654static long long a3; 655static long long r2; 656#elif defined(MIPS) 657static long a3; 658static long r2; 659#elif defined(S390) || defined(S390X) 660static long gpr2; 661static long pc; 662static long syscall_mode; 663#elif defined(HPPA) 664static long r28; 665#elif defined(SH) 666static long r0; 667#elif defined(SH64) 668static long r9; 669#elif defined(CRISV10) || defined(CRISV32) 670static long r10; 671#elif defined(MICROBLAZE) 672static long r3; 673#endif 674 675/* Returns: 676 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 677 * 1: ok, continue in trace_syscall(). 678 * other: error, trace_syscall() should print error indicator 679 * ("????" etc) and bail out. 680 */ 681static int 682get_scno(struct tcb *tcp) 683{ 684 long scno = 0; 685 686#if defined(S390) || defined(S390X) 687 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0) 688 return -1; 689 690 if (syscall_mode != -ENOSYS) { 691 /* 692 * Since kernel version 2.5.44 the scno gets passed in gpr2. 693 */ 694 scno = syscall_mode; 695 } else { 696 /* 697 * Old style of "passing" the scno via the SVC instruction. 698 */ 699 long opcode, offset_reg, tmp; 700 void *svc_addr; 701 static const int gpr_offset[16] = { 702 PT_GPR0, PT_GPR1, PT_ORIGGPR2, PT_GPR3, 703 PT_GPR4, PT_GPR5, PT_GPR6, PT_GPR7, 704 PT_GPR8, PT_GPR9, PT_GPR10, PT_GPR11, 705 PT_GPR12, PT_GPR13, PT_GPR14, PT_GPR15 706 }; 707 708 if (upeek(tcp, PT_PSWADDR, &pc) < 0) 709 return -1; 710 errno = 0; 711 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0); 712 if (errno) { 713 perror("peektext(pc-oneword)"); 714 return -1; 715 } 716 717 /* 718 * We have to check if the SVC got executed directly or via an 719 * EXECUTE instruction. In case of EXECUTE it is necessary to do 720 * instruction decoding to derive the system call number. 721 * Unfortunately the opcode sizes of EXECUTE and SVC are differently, 722 * so that this doesn't work if a SVC opcode is part of an EXECUTE 723 * opcode. Since there is no way to find out the opcode size this 724 * is the best we can do... 725 */ 726 if ((opcode & 0xff00) == 0x0a00) { 727 /* SVC opcode */ 728 scno = opcode & 0xff; 729 } 730 else { 731 /* SVC got executed by EXECUTE instruction */ 732 733 /* 734 * Do instruction decoding of EXECUTE. If you really want to 735 * understand this, read the Principles of Operations. 736 */ 737 svc_addr = (void *) (opcode & 0xfff); 738 739 tmp = 0; 740 offset_reg = (opcode & 0x000f0000) >> 16; 741 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 742 return -1; 743 svc_addr += tmp; 744 745 tmp = 0; 746 offset_reg = (opcode & 0x0000f000) >> 12; 747 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 748 return -1; 749 svc_addr += tmp; 750 751 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0); 752 if (errno) 753 return -1; 754# if defined(S390X) 755 scno >>= 48; 756# else 757 scno >>= 16; 758# endif 759 tmp = 0; 760 offset_reg = (opcode & 0x00f00000) >> 20; 761 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0)) 762 return -1; 763 764 scno = (scno | tmp) & 0xff; 765 } 766 } 767#elif defined(POWERPC) 768 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0) 769 return -1; 770# ifdef POWERPC64 771 /* TODO: speed up strace by not doing this at every syscall. 772 * We only need to do it after execve. 773 */ 774 int currpers; 775 long val; 776 777 /* Check for 64/32 bit mode. */ 778 if (upeek(tcp, sizeof(unsigned long)*PT_MSR, &val) < 0) 779 return -1; 780 /* SF is bit 0 of MSR */ 781 if (val < 0) 782 currpers = 0; 783 else 784 currpers = 1; 785 update_personality(tcp, currpers); 786# endif 787#elif defined(AVR32) 788 /* Read complete register set in one go. */ 789 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0) 790 return -1; 791 scno = regs.r8; 792#elif defined(BFIN) 793 if (upeek(tcp, PT_ORIG_P0, &scno)) 794 return -1; 795#elif defined(I386) 796 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &i386_regs) < 0) 797 return -1; 798 scno = i386_regs.orig_eax; 799#elif defined(X86_64) 800 int currpers; 801 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &x86_64_regs) < 0) 802 return -1; 803 scno = x86_64_regs.orig_rax; 804 805 /* Check CS register value. On x86-64 linux it is: 806 * 0x33 for long mode (64 bit) 807 * 0x23 for compatibility mode (32 bit) 808 */ 809 switch (x86_64_regs.cs) { 810 case 0x23: currpers = 1; break; 811 case 0x33: currpers = 0; break; 812 default: 813 fprintf(stderr, "Unknown value CS=0x%08X while " 814 "detecting personality of process " 815 "PID=%d\n", (int)x86_64_regs.cs, tcp->pid); 816 currpers = current_personality; 817 break; 818 } 819# if 0 820 /* This version analyzes the opcode of a syscall instruction. 821 * (int 0x80 on i386 vs. syscall on x86-64) 822 * It works, but is too complicated. 823 */ 824 unsigned long val, rip, i; 825 826 rip = x86_64_regs.rip; 827 828 /* sizeof(syscall) == sizeof(int 0x80) == 2 */ 829 rip -= 2; 830 errno = 0; 831 832 call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0); 833 if (errno) 834 fprintf(stderr, "ptrace_peektext failed: %s\n", 835 strerror(errno)); 836 switch (call & 0xffff) { 837 /* x86-64: syscall = 0x0f 0x05 */ 838 case 0x050f: currpers = 0; break; 839 /* i386: int 0x80 = 0xcd 0x80 */ 840 case 0x80cd: currpers = 1; break; 841 default: 842 currpers = current_personality; 843 fprintf(stderr, 844 "Unknown syscall opcode (0x%04X) while " 845 "detecting personality of process " 846 "PID=%d\n", (int)call, tcp->pid); 847 break; 848 } 849# endif 850 update_personality(tcp, currpers); 851#elif defined(IA64) 852# define IA64_PSR_IS ((long)1 << 34) 853 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 854 ia32 = (psr & IA64_PSR_IS) != 0; 855 if (ia32) { 856 if (upeek(tcp, PT_R1, &scno) < 0) 857 return -1; 858 } else { 859 if (upeek(tcp, PT_R15, &scno) < 0) 860 return -1; 861 } 862#elif defined(ARM) 863 /* Read complete register set in one go. */ 864 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1) 865 return -1; 866 867 /* 868 * We only need to grab the syscall number on syscall entry. 869 */ 870 if (regs.ARM_ip == 0) { 871 /* 872 * Note: we only deal with only 32-bit CPUs here. 873 */ 874 if (regs.ARM_cpsr & 0x20) { 875 /* 876 * Get the Thumb-mode system call number 877 */ 878 scno = regs.ARM_r7; 879 } else { 880 /* 881 * Get the ARM-mode system call number 882 */ 883 errno = 0; 884 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(regs.ARM_pc - 4), NULL); 885 if (errno) 886 return -1; 887 888 /* Handle the EABI syscall convention. We do not 889 bother converting structures between the two 890 ABIs, but basic functionality should work even 891 if strace and the traced program have different 892 ABIs. */ 893 if (scno == 0xef000000) { 894 scno = regs.ARM_r7; 895 } else { 896 if ((scno & 0x0ff00000) != 0x0f900000) { 897 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n", 898 scno); 899 return -1; 900 } 901 902 /* 903 * Fixup the syscall number 904 */ 905 scno &= 0x000fffff; 906 } 907 } 908 if (scno & 0x0f0000) { 909 /* 910 * Handle ARM specific syscall 911 */ 912 update_personality(tcp, 1); 913 scno &= 0x0000ffff; 914 } else 915 update_personality(tcp, 0); 916 917 } else { 918 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid); 919 tcp->flags |= TCB_INSYSCALL; 920 } 921#elif defined(M68K) 922 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0) 923 return -1; 924#elif defined(LINUX_MIPSN32) 925 unsigned long long regs[38]; 926 927 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 928 return -1; 929 a3 = regs[REG_A3]; 930 r2 = regs[REG_V0]; 931 932 scno = r2; 933 if (!SCNO_IN_RANGE(scno)) { 934 if (a3 == 0 || a3 == -1) { 935 if (debug_flag) 936 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 937 return 0; 938 } 939 } 940#elif defined(MIPS) 941 if (upeek(tcp, REG_A3, &a3) < 0) 942 return -1; 943 if (upeek(tcp, REG_V0, &scno) < 0) 944 return -1; 945 946 if (!SCNO_IN_RANGE(scno)) { 947 if (a3 == 0 || a3 == -1) { 948 if (debug_flag) 949 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno); 950 return 0; 951 } 952 } 953#elif defined(ALPHA) 954 if (upeek(tcp, REG_A3, &a3) < 0) 955 return -1; 956 if (upeek(tcp, REG_R0, &scno) < 0) 957 return -1; 958 959 /* 960 * Do some sanity checks to figure out if it's 961 * really a syscall entry 962 */ 963 if (!SCNO_IN_RANGE(scno)) { 964 if (a3 == 0 || a3 == -1) { 965 if (debug_flag) 966 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno); 967 return 0; 968 } 969 } 970#elif defined(SPARC) || defined(SPARC64) 971 /* Everything we need is in the current register set. */ 972 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 973 return -1; 974 975 /* Disassemble the syscall trap. */ 976 /* Retrieve the syscall trap instruction. */ 977 errno = 0; 978# if defined(SPARC64) 979 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0); 980 trap >>= 32; 981# else 982 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0); 983# endif 984 if (errno) 985 return -1; 986 987 /* Disassemble the trap to see what personality to use. */ 988 switch (trap) { 989 case 0x91d02010: 990 /* Linux/SPARC syscall trap. */ 991 update_personality(tcp, 0); 992 break; 993 case 0x91d0206d: 994 /* Linux/SPARC64 syscall trap. */ 995 update_personality(tcp, 2); 996 break; 997 case 0x91d02000: 998 /* SunOS syscall trap. (pers 1) */ 999 fprintf(stderr, "syscall: SunOS no support\n"); 1000 return -1; 1001 case 0x91d02008: 1002 /* Solaris 2.x syscall trap. (per 2) */ 1003 update_personality(tcp, 1); 1004 break; 1005 case 0x91d02009: 1006 /* NetBSD/FreeBSD syscall trap. */ 1007 fprintf(stderr, "syscall: NetBSD/FreeBSD not supported\n"); 1008 return -1; 1009 case 0x91d02027: 1010 /* Solaris 2.x gettimeofday */ 1011 update_personality(tcp, 1); 1012 break; 1013 default: 1014# if defined(SPARC64) 1015 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc); 1016# else 1017 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc); 1018# endif 1019 return -1; 1020 } 1021 1022 /* Extract the system call number from the registers. */ 1023 if (trap == 0x91d02027) 1024 scno = 156; 1025 else 1026 scno = regs.u_regs[U_REG_G1]; 1027 if (scno == 0) { 1028 scno = regs.u_regs[U_REG_O0]; 1029 memmove(®s.u_regs[U_REG_O0], ®s.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0])); 1030 } 1031#elif defined(HPPA) 1032 if (upeek(tcp, PT_GR20, &scno) < 0) 1033 return -1; 1034#elif defined(SH) 1035 /* 1036 * In the new syscall ABI, the system call number is in R3. 1037 */ 1038 if (upeek(tcp, 4*(REG_REG0+3), &scno) < 0) 1039 return -1; 1040 1041 if (scno < 0) { 1042 /* Odd as it may seem, a glibc bug has been known to cause 1043 glibc to issue bogus negative syscall numbers. So for 1044 our purposes, make strace print what it *should* have been */ 1045 long correct_scno = (scno & 0xff); 1046 if (debug_flag) 1047 fprintf(stderr, 1048 "Detected glibc bug: bogus system call" 1049 " number = %ld, correcting to %ld\n", 1050 scno, 1051 correct_scno); 1052 scno = correct_scno; 1053 } 1054#elif defined(SH64) 1055 if (upeek(tcp, REG_SYSCALL, &scno) < 0) 1056 return -1; 1057 scno &= 0xFFFF; 1058#elif defined(CRISV10) || defined(CRISV32) 1059 if (upeek(tcp, 4*PT_R9, &scno) < 0) 1060 return -1; 1061#elif defined(TILE) 1062 if (upeek(tcp, PTREGS_OFFSET_REG(10), &scno) < 0) 1063 return -1; 1064#elif defined(MICROBLAZE) 1065 if (upeek(tcp, 0, &scno) < 0) 1066 return -1; 1067#endif 1068 1069#if defined(SH) 1070 /* new syscall ABI returns result in R0 */ 1071 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1072 return -1; 1073#elif defined(SH64) 1074 /* ABI defines result returned in r9 */ 1075 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1076 return -1; 1077#endif 1078 1079 tcp->scno = scno; 1080 return 1; 1081} 1082 1083/* Called at each syscall entry. 1084 * Returns: 1085 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 1086 * 1: ok, continue in trace_syscall(). 1087 * other: error, trace_syscall() should print error indicator 1088 * ("????" etc) and bail out. 1089 */ 1090static int 1091syscall_fixup_on_sysenter(struct tcb *tcp) 1092{ 1093 /* A common case of "not a syscall entry" is post-execve SIGTRAP */ 1094#if defined(I386) 1095 if (i386_regs.eax != -ENOSYS) { 1096 if (debug_flag) 1097 fprintf(stderr, "not a syscall entry (eax = %ld)\n", i386_regs.eax); 1098 return 0; 1099 } 1100#elif defined(X86_64) 1101 { 1102 long rax = x86_64_regs.rax; 1103 if (current_personality == 1) 1104 rax = (int)rax; /* sign extend from 32 bits */ 1105 if (rax != -ENOSYS) { 1106 if (debug_flag) 1107 fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax); 1108 return 0; 1109 } 1110 } 1111#elif defined(S390) || defined(S390X) 1112 /* TODO: we already fetched PT_GPR2 in get_scno 1113 * and stored it in syscall_mode, reuse it here 1114 * instead of re-fetching? 1115 */ 1116 if (upeek(tcp, PT_GPR2, &gpr2) < 0) 1117 return -1; 1118 if (syscall_mode != -ENOSYS) 1119 syscall_mode = tcp->scno; 1120 if (gpr2 != syscall_mode) { 1121 if (debug_flag) 1122 fprintf(stderr, "not a syscall entry (gpr2 = %ld)\n", gpr2); 1123 return 0; 1124 } 1125#elif defined(M68K) 1126 /* TODO? Eliminate upeek's in arches below like we did in x86 */ 1127 if (upeek(tcp, 4*PT_D0, &d0) < 0) 1128 return -1; 1129 if (d0 != -ENOSYS) { 1130 if (debug_flag) 1131 fprintf(stderr, "not a syscall entry (d0 = %ld)\n", d0); 1132 return 0; 1133 } 1134#elif defined(IA64) 1135 if (upeek(tcp, PT_R10, &r10) < 0) 1136 return -1; 1137 if (upeek(tcp, PT_R8, &r8) < 0) 1138 return -1; 1139 if (ia32 && r8 != -ENOSYS) { 1140 if (debug_flag) 1141 fprintf(stderr, "not a syscall entry (r8 = %ld)\n", r8); 1142 return 0; 1143 } 1144#elif defined(CRISV10) || defined(CRISV32) 1145 if (upeek(tcp, 4*PT_R10, &r10) < 0) 1146 return -1; 1147 if (r10 != -ENOSYS) { 1148 if (debug_flag) 1149 fprintf(stderr, "not a syscall entry (r10 = %ld)\n", r10); 1150 return 0; 1151 } 1152#elif defined(MICROBLAZE) 1153 if (upeek(tcp, 3 * 4, &r3) < 0) 1154 return -1; 1155 if (r3 != -ENOSYS) { 1156 if (debug_flag) 1157 fprintf(stderr, "not a syscall entry (r3 = %ld)\n", r3); 1158 return 0; 1159 } 1160#endif 1161 return 1; 1162} 1163 1164static void 1165internal_fork(struct tcb *tcp) 1166{ 1167#if defined S390 || defined S390X || defined CRISV10 || defined CRISV32 1168# define ARG_FLAGS 1 1169#else 1170# define ARG_FLAGS 0 1171#endif 1172#ifndef CLONE_UNTRACED 1173# define CLONE_UNTRACED 0x00800000 1174#endif 1175 if ((ptrace_setoptions 1176 & (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK)) 1177 == (PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK)) 1178 return; 1179 1180 if (!followfork) 1181 return; 1182 1183 if (entering(tcp)) { 1184 /* 1185 * We won't see the new child if clone is called with 1186 * CLONE_UNTRACED, so we keep the same logic with that option 1187 * and don't trace it. 1188 */ 1189 if ((sysent[tcp->scno].sys_func == sys_clone) && 1190 (tcp->u_arg[ARG_FLAGS] & CLONE_UNTRACED)) 1191 return; 1192 setbpt(tcp); 1193 } else { 1194 if (tcp->flags & TCB_BPTSET) 1195 clearbpt(tcp); 1196 } 1197} 1198 1199#if defined(TCB_WAITEXECVE) 1200static void 1201internal_exec(struct tcb *tcp) 1202{ 1203 /* Maybe we have post-execve SIGTRAP suppressed? */ 1204 if (ptrace_setoptions & PTRACE_O_TRACEEXEC) 1205 return; /* yes, no need to do anything */ 1206 1207 if (exiting(tcp) && syserror(tcp)) 1208 /* Error in execve, no post-execve SIGTRAP expected */ 1209 tcp->flags &= ~TCB_WAITEXECVE; 1210 else 1211 tcp->flags |= TCB_WAITEXECVE; 1212} 1213#endif 1214 1215static void 1216internal_syscall(struct tcb *tcp) 1217{ 1218 /* 1219 * We must always trace a few critical system calls in order to 1220 * correctly support following forks in the presence of tracing 1221 * qualifiers. 1222 */ 1223 int (*func)(); 1224 1225 if (!SCNO_IN_RANGE(tcp->scno)) 1226 return; 1227 1228 func = sysent[tcp->scno].sys_func; 1229 1230 if ( sys_fork == func 1231 || sys_vfork == func 1232 || sys_clone == func 1233 ) { 1234 internal_fork(tcp); 1235 return; 1236 } 1237 1238#if defined(TCB_WAITEXECVE) 1239 if ( sys_execve == func 1240# if defined(SPARC) || defined(SPARC64) 1241 || sys_execv == func 1242# endif 1243 ) { 1244 internal_exec(tcp); 1245 return; 1246 } 1247#endif 1248} 1249 1250static int 1251syscall_enter(struct tcb *tcp) 1252{ 1253 int i, nargs; 1254 1255 if (SCNO_IN_RANGE(tcp->scno)) 1256 nargs = tcp->u_nargs = sysent[tcp->scno].nargs; 1257 else 1258 nargs = tcp->u_nargs = MAX_ARGS; 1259 1260#if defined(S390) || defined(S390X) 1261 for (i = 0; i < nargs; ++i) 1262 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0) 1263 return -1; 1264#elif defined(ALPHA) 1265 for (i = 0; i < nargs; ++i) 1266 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0) 1267 return -1; 1268#elif defined(IA64) 1269 if (!ia32) { 1270 unsigned long *out0, cfm, sof, sol; 1271 long rbs_end; 1272 /* be backwards compatible with kernel < 2.4.4... */ 1273# ifndef PT_RBS_END 1274# define PT_RBS_END PT_AR_BSP 1275# endif 1276 1277 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0) 1278 return -1; 1279 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0) 1280 return -1; 1281 1282 sof = (cfm >> 0) & 0x7f; 1283 sol = (cfm >> 7) & 0x7f; 1284 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol); 1285 1286 for (i = 0; i < nargs; ++i) { 1287 if (umoven(tcp, (unsigned long) ia64_rse_skip_regs(out0, i), 1288 sizeof(long), (char *) &tcp->u_arg[i]) < 0) 1289 return -1; 1290 } 1291 } else { 1292 static const int argreg[MAX_ARGS] = { PT_R11 /* EBX = out0 */, 1293 PT_R9 /* ECX = out1 */, 1294 PT_R10 /* EDX = out2 */, 1295 PT_R14 /* ESI = out3 */, 1296 PT_R15 /* EDI = out4 */, 1297 PT_R13 /* EBP = out5 */}; 1298 1299 for (i = 0; i < nargs; ++i) { 1300 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 1301 return -1; 1302 /* truncate away IVE sign-extension */ 1303 tcp->u_arg[i] &= 0xffffffff; 1304 } 1305 } 1306#elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64) 1307 /* N32 and N64 both use up to six registers. */ 1308 unsigned long long regs[38]; 1309 1310 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1311 return -1; 1312 1313 for (i = 0; i < nargs; ++i) { 1314 tcp->u_arg[i] = regs[REG_A0 + i]; 1315# if defined(LINUX_MIPSN32) 1316 tcp->ext_arg[i] = regs[REG_A0 + i]; 1317# endif 1318 } 1319#elif defined(MIPS) 1320 if (nargs > 4) { 1321 long sp; 1322 1323 if (upeek(tcp, REG_SP, &sp) < 0) 1324 return -1; 1325 for (i = 0; i < 4; ++i) 1326 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 1327 return -1; 1328 umoven(tcp, sp + 16, (nargs - 4) * sizeof(tcp->u_arg[0]), 1329 (char *)(tcp->u_arg + 4)); 1330 } else { 1331 for (i = 0; i < nargs; ++i) 1332 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0) 1333 return -1; 1334 } 1335#elif defined(POWERPC) 1336# ifndef PT_ORIG_R3 1337# define PT_ORIG_R3 34 1338# endif 1339 for (i = 0; i < nargs; ++i) { 1340 if (upeek(tcp, (i==0) ? 1341 (sizeof(unsigned long) * PT_ORIG_R3) : 1342 ((i+PT_R3) * sizeof(unsigned long)), 1343 &tcp->u_arg[i]) < 0) 1344 return -1; 1345 } 1346#elif defined(SPARC) || defined(SPARC64) 1347 for (i = 0; i < nargs; ++i) 1348 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i]; 1349#elif defined(HPPA) 1350 for (i = 0; i < nargs; ++i) 1351 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0) 1352 return -1; 1353#elif defined(ARM) 1354 for (i = 0; i < nargs; ++i) 1355 tcp->u_arg[i] = regs.uregs[i]; 1356#elif defined(AVR32) 1357 (void)i; 1358 (void)nargs; 1359 tcp->u_arg[0] = regs.r12; 1360 tcp->u_arg[1] = regs.r11; 1361 tcp->u_arg[2] = regs.r10; 1362 tcp->u_arg[3] = regs.r9; 1363 tcp->u_arg[4] = regs.r5; 1364 tcp->u_arg[5] = regs.r3; 1365#elif defined(BFIN) 1366 static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 }; 1367 1368 for (i = 0; i < nargs; ++i) 1369 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0) 1370 return -1; 1371#elif defined(SH) 1372 static const int syscall_regs[MAX_ARGS] = { 1373 4 * (REG_REG0+4), 4 * (REG_REG0+5), 4 * (REG_REG0+6), 1374 4 * (REG_REG0+7), 4 * (REG_REG0 ), 4 * (REG_REG0+1) 1375 }; 1376 1377 for (i = 0; i < nargs; ++i) 1378 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0) 1379 return -1; 1380#elif defined(SH64) 1381 int i; 1382 /* Registers used by SH5 Linux system calls for parameters */ 1383 static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 }; 1384 1385 for (i = 0; i < nargs; ++i) 1386 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0) 1387 return -1; 1388#elif defined(X86_64) 1389 (void)i; 1390 (void)nargs; 1391 if (current_personality == 0) { /* x86-64 ABI */ 1392 tcp->u_arg[0] = x86_64_regs.rdi; 1393 tcp->u_arg[1] = x86_64_regs.rsi; 1394 tcp->u_arg[2] = x86_64_regs.rdx; 1395 tcp->u_arg[3] = x86_64_regs.r10; 1396 tcp->u_arg[4] = x86_64_regs.r8; 1397 tcp->u_arg[5] = x86_64_regs.r9; 1398 } else { /* i386 ABI */ 1399 /* Sign-extend lower 32 bits */ 1400 tcp->u_arg[0] = (long)(int)x86_64_regs.rbx; 1401 tcp->u_arg[1] = (long)(int)x86_64_regs.rcx; 1402 tcp->u_arg[2] = (long)(int)x86_64_regs.rdx; 1403 tcp->u_arg[3] = (long)(int)x86_64_regs.rsi; 1404 tcp->u_arg[4] = (long)(int)x86_64_regs.rdi; 1405 tcp->u_arg[5] = (long)(int)x86_64_regs.rbp; 1406 } 1407#elif defined(MICROBLAZE) 1408 for (i = 0; i < nargs; ++i) 1409 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0) 1410 return -1; 1411#elif defined(CRISV10) || defined(CRISV32) 1412 static const int crisregs[MAX_ARGS] = { 1413 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12, 1414 4*PT_R13 , 4*PT_MOF, 4*PT_SRP 1415 }; 1416 1417 for (i = 0; i < nargs; ++i) 1418 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0) 1419 return -1; 1420#elif defined(TILE) 1421 for (i = 0; i < nargs; ++i) 1422 if (upeek(tcp, PTREGS_OFFSET_REG(i), &tcp->u_arg[i]) < 0) 1423 return -1; 1424#elif defined(M68K) 1425 for (i = 0; i < nargs; ++i) 1426 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0) 1427 return -1; 1428#elif defined(I386) 1429 (void)i; 1430 (void)nargs; 1431 tcp->u_arg[0] = i386_regs.ebx; 1432 tcp->u_arg[1] = i386_regs.ecx; 1433 tcp->u_arg[2] = i386_regs.edx; 1434 tcp->u_arg[3] = i386_regs.esi; 1435 tcp->u_arg[4] = i386_regs.edi; 1436 tcp->u_arg[5] = i386_regs.ebp; 1437#else /* Other architecture (32bits specific) */ 1438 for (i = 0; i < nargs; ++i) 1439 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0) 1440 return -1; 1441#endif 1442 return 1; 1443} 1444 1445static int 1446trace_syscall_entering(struct tcb *tcp) 1447{ 1448 int res, scno_good; 1449 1450#if defined TCB_WAITEXECVE 1451 if (tcp->flags & TCB_WAITEXECVE) { 1452 /* This is the post-execve SIGTRAP. */ 1453 tcp->flags &= ~TCB_WAITEXECVE; 1454 return 0; 1455 } 1456#endif 1457 1458 scno_good = res = get_scno(tcp); 1459 if (res == 0) 1460 return res; 1461 if (res == 1) 1462 res = syscall_fixup_on_sysenter(tcp); 1463 if (res == 0) 1464 return res; 1465 if (res == 1) 1466 res = syscall_enter(tcp); 1467 if (res == 0) 1468 return res; 1469 1470 if (res != 1) { 1471 printleader(tcp); 1472 tcp->flags &= ~TCB_REPRINT; 1473 if (scno_good != 1) 1474 tprints("????" /* anti-trigraph gap */ "("); 1475 else if (!SCNO_IN_RANGE(tcp->scno)) 1476 tprintf("syscall_%lu(", tcp->scno); 1477 else 1478 tprintf("%s(", sysent[tcp->scno].sys_name); 1479 /* 1480 * " <unavailable>" will be added later by the code which 1481 * detects ptrace errors. 1482 */ 1483 goto ret; 1484 } 1485 1486#if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall) 1487 while (SCNO_IN_RANGE(tcp->scno)) { 1488# ifdef SYS_socket_subcall 1489 if (sysent[tcp->scno].sys_func == sys_socketcall) { 1490 decode_socket_subcall(tcp); 1491 break; 1492 } 1493# endif 1494# ifdef SYS_ipc_subcall 1495 if (sysent[tcp->scno].sys_func == sys_ipc) { 1496 decode_ipc_subcall(tcp); 1497 break; 1498 } 1499# endif 1500 break; 1501 } 1502#endif /* SYS_socket_subcall || SYS_ipc_subcall */ 1503 1504 internal_syscall(tcp); 1505 1506 if ((SCNO_IN_RANGE(tcp->scno) && 1507 !(qual_flags[tcp->scno] & QUAL_TRACE)) || 1508 (tracing_paths && !pathtrace_match(tcp))) { 1509 tcp->flags |= TCB_INSYSCALL | TCB_FILTERED; 1510 return 0; 1511 } 1512 1513 tcp->flags &= ~TCB_FILTERED; 1514 1515 if (cflag == CFLAG_ONLY_STATS) { 1516 res = 0; 1517 goto ret; 1518 } 1519 1520 printleader(tcp); 1521 tcp->flags &= ~TCB_REPRINT; 1522 if (!SCNO_IN_RANGE(tcp->scno)) 1523 tprintf("syscall_%lu(", tcp->scno); 1524 else 1525 tprintf("%s(", sysent[tcp->scno].sys_name); 1526 if (!SCNO_IN_RANGE(tcp->scno) || 1527 ((qual_flags[tcp->scno] & QUAL_RAW) && 1528 sysent[tcp->scno].sys_func != sys_exit)) 1529 res = printargs(tcp); 1530 else 1531 res = (*sysent[tcp->scno].sys_func)(tcp); 1532 1533 if (fflush(tcp->outf) == EOF) 1534 return -1; 1535 ret: 1536 tcp->flags |= TCB_INSYSCALL; 1537 /* Measure the entrance time as late as possible to avoid errors. */ 1538 if (Tflag || cflag) 1539 gettimeofday(&tcp->etime, NULL); 1540 return res; 1541} 1542 1543/* Returns: 1544 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 1545 * 1: ok, continue in trace_syscall(). 1546 * other: error, trace_syscall() should print error indicator 1547 * ("????" etc) and bail out. 1548 */ 1549static int 1550get_syscall_result(struct tcb *tcp) 1551{ 1552#if defined(S390) || defined(S390X) 1553 if (upeek(tcp, PT_GPR2, &gpr2) < 0) 1554 return -1; 1555#elif defined(POWERPC) 1556# define SO_MASK 0x10000000 1557 { 1558 long flags; 1559 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0) 1560 return -1; 1561 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &result) < 0) 1562 return -1; 1563 if (flags & SO_MASK) 1564 result = -result; 1565 } 1566#elif defined(AVR32) 1567 /* Read complete register set in one go. */ 1568 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, ®s) < 0) 1569 return -1; 1570#elif defined(BFIN) 1571 if (upeek(tcp, PT_R0, &r0) < 0) 1572 return -1; 1573#elif defined(I386) 1574 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &i386_regs) < 0) 1575 return -1; 1576#elif defined(X86_64) 1577 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &x86_64_regs) < 0) 1578 return -1; 1579#elif defined(IA64) 1580# define IA64_PSR_IS ((long)1 << 34) 1581 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0) 1582 ia32 = (psr & IA64_PSR_IS) != 0; 1583 if (upeek(tcp, PT_R8, &r8) < 0) 1584 return -1; 1585 if (upeek(tcp, PT_R10, &r10) < 0) 1586 return -1; 1587#elif defined(ARM) 1588 /* Read complete register set in one go. */ 1589 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (void *)®s) == -1) 1590 return -1; 1591#elif defined(M68K) 1592 if (upeek(tcp, 4*PT_D0, &d0) < 0) 1593 return -1; 1594#elif defined(LINUX_MIPSN32) 1595 unsigned long long regs[38]; 1596 1597 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) ®s) < 0) 1598 return -1; 1599 a3 = regs[REG_A3]; 1600 r2 = regs[REG_V0]; 1601#elif defined(MIPS) 1602 if (upeek(tcp, REG_A3, &a3) < 0) 1603 return -1; 1604 if (upeek(tcp, REG_V0, &r2) < 0) 1605 return -1; 1606#elif defined(ALPHA) 1607 if (upeek(tcp, REG_A3, &a3) < 0) 1608 return -1; 1609 if (upeek(tcp, REG_R0, &r0) < 0) 1610 return -1; 1611#elif defined(SPARC) || defined(SPARC64) 1612 /* Everything we need is in the current register set. */ 1613 if (ptrace(PTRACE_GETREGS, tcp->pid, (char *)®s, 0) < 0) 1614 return -1; 1615#elif defined(HPPA) 1616 if (upeek(tcp, PT_GR28, &r28) < 0) 1617 return -1; 1618#elif defined(SH) 1619#elif defined(SH64) 1620#elif defined(CRISV10) || defined(CRISV32) 1621 if (upeek(tcp, 4*PT_R10, &r10) < 0) 1622 return -1; 1623#elif defined(TILE) 1624#elif defined(MICROBLAZE) 1625 if (upeek(tcp, 3 * 4, &r3) < 0) 1626 return -1; 1627#endif 1628 1629#if defined(SH) 1630 /* new syscall ABI returns result in R0 */ 1631 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0) 1632 return -1; 1633#elif defined(SH64) 1634 /* ABI defines result returned in r9 */ 1635 if (upeek(tcp, REG_GENERAL(9), (long *)&r9) < 0) 1636 return -1; 1637#endif 1638 1639 return 1; 1640} 1641 1642/* Called at each syscall exit. 1643 * Returns: 1644 * 0: "ignore this ptrace stop", bail out of trace_syscall() silently. 1645 * 1: ok, continue in trace_syscall(). 1646 * other: error, trace_syscall() should print error indicator 1647 * ("????" etc) and bail out. 1648 */ 1649static int 1650syscall_fixup_on_sysexit(struct tcb *tcp) 1651{ 1652#if defined(S390) || defined(S390X) 1653 if (syscall_mode != -ENOSYS) 1654 syscall_mode = tcp->scno; 1655 if ((tcp->flags & TCB_WAITEXECVE) 1656 && (gpr2 == -ENOSYS || gpr2 == tcp->scno)) { 1657 /* 1658 * Return from execve. 1659 * Fake a return value of zero. We leave the TCB_WAITEXECVE 1660 * flag set for the post-execve SIGTRAP to see and reset. 1661 */ 1662 gpr2 = 0; 1663 } 1664#endif 1665 return 1; 1666} 1667 1668/* 1669 * Check the syscall return value register value for whether it is 1670 * a negated errno code indicating an error, or a success return value. 1671 */ 1672static inline int 1673is_negated_errno(unsigned long int val) 1674{ 1675 unsigned long int max = -(long int) nerrnos; 1676#if SUPPORTED_PERSONALITIES > 1 1677 if (current_wordsize < sizeof(val)) { 1678 val = (unsigned int) val; 1679 max = (unsigned int) max; 1680 } 1681#endif 1682 return val > max; 1683} 1684 1685static int 1686get_error(struct tcb *tcp) 1687{ 1688 int u_error = 0; 1689 int check_errno = 1; 1690 if (SCNO_IN_RANGE(tcp->scno) && 1691 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) { 1692 check_errno = 0; 1693 } 1694#if defined(S390) || defined(S390X) 1695 if (check_errno && is_negated_errno(gpr2)) { 1696 tcp->u_rval = -1; 1697 u_error = -gpr2; 1698 } 1699 else { 1700 tcp->u_rval = gpr2; 1701 } 1702#elif defined(I386) 1703 if (check_errno && is_negated_errno(i386_regs.eax)) { 1704 tcp->u_rval = -1; 1705 u_error = -i386_regs.eax; 1706 } 1707 else { 1708 tcp->u_rval = i386_regs.eax; 1709 } 1710#elif defined(X86_64) 1711 if (check_errno && is_negated_errno(x86_64_regs.rax)) { 1712 tcp->u_rval = -1; 1713 u_error = -x86_64_regs.rax; 1714 } 1715 else { 1716 tcp->u_rval = x86_64_regs.rax; 1717 } 1718#elif defined(IA64) 1719 if (ia32) { 1720 int err; 1721 1722 err = (int)r8; 1723 if (check_errno && is_negated_errno(err)) { 1724 tcp->u_rval = -1; 1725 u_error = -err; 1726 } 1727 else { 1728 tcp->u_rval = err; 1729 } 1730 } else { 1731 if (check_errno && r10) { 1732 tcp->u_rval = -1; 1733 u_error = r8; 1734 } else { 1735 tcp->u_rval = r8; 1736 } 1737 } 1738#elif defined(MIPS) 1739 if (check_errno && a3) { 1740 tcp->u_rval = -1; 1741 u_error = r2; 1742 } else { 1743 tcp->u_rval = r2; 1744 } 1745#elif defined(POWERPC) 1746 if (check_errno && is_negated_errno(result)) { 1747 tcp->u_rval = -1; 1748 u_error = -result; 1749 } 1750 else { 1751 tcp->u_rval = result; 1752 } 1753#elif defined(M68K) 1754 if (check_errno && is_negated_errno(d0)) { 1755 tcp->u_rval = -1; 1756 u_error = -d0; 1757 } 1758 else { 1759 tcp->u_rval = d0; 1760 } 1761#elif defined(ARM) 1762 if (check_errno && is_negated_errno(regs.ARM_r0)) { 1763 tcp->u_rval = -1; 1764 u_error = -regs.ARM_r0; 1765 } 1766 else { 1767 tcp->u_rval = regs.ARM_r0; 1768 } 1769#elif defined(AVR32) 1770 if (check_errno && regs.r12 && (unsigned) -regs.r12 < nerrnos) { 1771 tcp->u_rval = -1; 1772 u_error = -regs.r12; 1773 } 1774 else { 1775 tcp->u_rval = regs.r12; 1776 } 1777#elif defined(BFIN) 1778 if (check_errno && is_negated_errno(r0)) { 1779 tcp->u_rval = -1; 1780 u_error = -r0; 1781 } else { 1782 tcp->u_rval = r0; 1783 } 1784#elif defined(ALPHA) 1785 if (check_errno && a3) { 1786 tcp->u_rval = -1; 1787 u_error = r0; 1788 } 1789 else { 1790 tcp->u_rval = r0; 1791 } 1792#elif defined(SPARC) 1793 if (check_errno && regs.psr & PSR_C) { 1794 tcp->u_rval = -1; 1795 u_error = regs.u_regs[U_REG_O0]; 1796 } 1797 else { 1798 tcp->u_rval = regs.u_regs[U_REG_O0]; 1799 } 1800#elif defined(SPARC64) 1801 if (check_errno && regs.tstate & 0x1100000000UL) { 1802 tcp->u_rval = -1; 1803 u_error = regs.u_regs[U_REG_O0]; 1804 } 1805 else { 1806 tcp->u_rval = regs.u_regs[U_REG_O0]; 1807 } 1808#elif defined(HPPA) 1809 if (check_errno && is_negated_errno(r28)) { 1810 tcp->u_rval = -1; 1811 u_error = -r28; 1812 } 1813 else { 1814 tcp->u_rval = r28; 1815 } 1816#elif defined(SH) 1817 if (check_errno && is_negated_errno(r0)) { 1818 tcp->u_rval = -1; 1819 u_error = -r0; 1820 } 1821 else { 1822 tcp->u_rval = r0; 1823 } 1824#elif defined(SH64) 1825 if (check_errno && is_negated_errno(r9)) { 1826 tcp->u_rval = -1; 1827 u_error = -r9; 1828 } 1829 else { 1830 tcp->u_rval = r9; 1831 } 1832#elif defined(CRISV10) || defined(CRISV32) 1833 if (check_errno && r10 && (unsigned) -r10 < nerrnos) { 1834 tcp->u_rval = -1; 1835 u_error = -r10; 1836 } 1837 else { 1838 tcp->u_rval = r10; 1839 } 1840#elif defined(TILE) 1841 long rval; 1842 if (upeek(tcp, PTREGS_OFFSET_REG(0), &rval) < 0) 1843 return -1; 1844 if (check_errno && rval < 0 && rval > -nerrnos) { 1845 tcp->u_rval = -1; 1846 u_error = -rval; 1847 } 1848 else { 1849 tcp->u_rval = rval; 1850 } 1851#elif defined(MICROBLAZE) 1852 if (check_errno && is_negated_errno(r3)) { 1853 tcp->u_rval = -1; 1854 u_error = -r3; 1855 } 1856 else { 1857 tcp->u_rval = r3; 1858 } 1859#endif 1860 tcp->u_error = u_error; 1861 return 1; 1862} 1863 1864static void 1865dumpio(struct tcb *tcp) 1866{ 1867 if (syserror(tcp)) 1868 return; 1869 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= MAX_QUALS) 1870 return; 1871 if (!SCNO_IN_RANGE(tcp->scno)) 1872 return; 1873 if (sysent[tcp->scno].sys_func == printargs) 1874 return; 1875 if (qual_flags[tcp->u_arg[0]] & QUAL_READ) { 1876 if (sysent[tcp->scno].sys_func == sys_read || 1877 sysent[tcp->scno].sys_func == sys_pread || 1878 sysent[tcp->scno].sys_func == sys_recv || 1879 sysent[tcp->scno].sys_func == sys_recvfrom) 1880 dumpstr(tcp, tcp->u_arg[1], tcp->u_rval); 1881 else if (sysent[tcp->scno].sys_func == sys_readv) 1882 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 1883 return; 1884 } 1885 if (qual_flags[tcp->u_arg[0]] & QUAL_WRITE) { 1886 if (sysent[tcp->scno].sys_func == sys_write || 1887 sysent[tcp->scno].sys_func == sys_pwrite || 1888 sysent[tcp->scno].sys_func == sys_send || 1889 sysent[tcp->scno].sys_func == sys_sendto) 1890 dumpstr(tcp, tcp->u_arg[1], tcp->u_arg[2]); 1891 else if (sysent[tcp->scno].sys_func == sys_writev) 1892 dumpiov(tcp, tcp->u_arg[2], tcp->u_arg[1]); 1893 return; 1894 } 1895} 1896 1897static int 1898trace_syscall_exiting(struct tcb *tcp) 1899{ 1900 int sys_res; 1901 struct timeval tv; 1902 int res; 1903 long u_error; 1904 1905 /* Measure the exit time as early as possible to avoid errors. */ 1906 if (Tflag || cflag) 1907 gettimeofday(&tv, NULL); 1908 1909#if SUPPORTED_PERSONALITIES > 1 1910 update_personality(tcp, tcp->currpers); 1911#endif 1912 res = get_syscall_result(tcp); 1913 if (res == 0) 1914 return res; 1915 if (res == 1) 1916 res = syscall_fixup_on_sysexit(tcp); 1917 if (res == 0) 1918 return res; 1919 if (res == 1) 1920 res = get_error(tcp); 1921 if (res == 0) 1922 return res; 1923 if (res == 1) 1924 internal_syscall(tcp); 1925 1926 if (res == 1 && filtered(tcp)) { 1927 goto ret; 1928 } 1929 1930 /* TODO: TCB_REPRINT is probably not necessary: 1931 * we can determine whether reprinting is needed 1932 * by examining printing_tcp. Something like: 1933 * if not in -ff mode, and printing_tcp != tcp, 1934 * then the log is not currenlty ends with *our* 1935 * syscall entry output, but with something else, 1936 * and we need to reprint. 1937 * If we'd implement this, printing_tcp = tcp 1938 * assignments in code below can be made more logical. 1939 */ 1940 1941 if (tcp->flags & TCB_REPRINT) { 1942 printleader(tcp); 1943 if (!SCNO_IN_RANGE(tcp->scno)) 1944 tprintf("<... syscall_%lu resumed> ", tcp->scno); 1945 else 1946 tprintf("<... %s resumed> ", sysent[tcp->scno].sys_name); 1947 } 1948 1949 if (cflag) { 1950 struct timeval t = tv; 1951 count_syscall(tcp, &t); 1952 if (cflag == CFLAG_ONLY_STATS) { 1953 goto ret; 1954 } 1955 } 1956 1957 if (res != 1) { 1958 printing_tcp = tcp; 1959 tprints(") "); 1960 tabto(); 1961 tprints("= ? <unavailable>\n"); 1962 line_ended(); 1963 tcp->flags &= ~TCB_INSYSCALL; 1964 return res; 1965 } 1966 1967 if (!SCNO_IN_RANGE(tcp->scno) 1968 || (qual_flags[tcp->scno] & QUAL_RAW)) { 1969 printing_tcp = tcp; 1970 sys_res = printargs(tcp); 1971 } else { 1972 /* FIXME: not_failing_only (IOW, option -z) is broken: 1973 * failure of syscall is known only after syscall return. 1974 * Thus we end up with something like this on, say, ENOENT: 1975 * open("doesnt_exist", O_RDONLY <unfinished ...> 1976 * {next syscall decode} 1977 * whereas the intended result is that open(...) line 1978 * is not shown at all. 1979 */ 1980 if (not_failing_only && tcp->u_error) 1981 goto ret; /* ignore failed syscalls */ 1982 printing_tcp = tcp; 1983 sys_res = (*sysent[tcp->scno].sys_func)(tcp); 1984 } 1985 1986 tprints(") "); 1987 tabto(); 1988 u_error = tcp->u_error; 1989 if (!SCNO_IN_RANGE(tcp->scno) || 1990 qual_flags[tcp->scno] & QUAL_RAW) { 1991 if (u_error) 1992 tprintf("= -1 (errno %ld)", u_error); 1993 else 1994 tprintf("= %#lx", tcp->u_rval); 1995 } 1996 else if (!(sys_res & RVAL_NONE) && u_error) { 1997 switch (u_error) { 1998 /* Blocked signals do not interrupt any syscalls. 1999 * In this case syscalls don't return ERESTARTfoo codes. 2000 * 2001 * Deadly signals set to SIG_DFL interrupt syscalls 2002 * and kill the process regardless of which of the codes below 2003 * is returned by the interrupted syscall. 2004 * In some cases, kernel forces a kernel-generated deadly 2005 * signal to be unblocked and set to SIG_DFL (and thus cause 2006 * death) if it is blocked or SIG_IGNed: for example, SIGSEGV 2007 * or SIGILL. (The alternative is to leave process spinning 2008 * forever on the faulty instruction - not useful). 2009 * 2010 * SIG_IGNed signals and non-deadly signals set to SIG_DFL 2011 * (for example, SIGCHLD, SIGWINCH) interrupt syscalls, 2012 * but kernel will always restart them. 2013 */ 2014 case ERESTARTSYS: 2015 /* Most common type of signal-interrupted syscall exit code. 2016 * The system call will be restarted with the same arguments 2017 * if SA_RESTART is set; otherwise, it will fail with EINTR. 2018 */ 2019 tprints("= ? ERESTARTSYS (To be restarted if SA_RESTART is set)"); 2020 break; 2021 case ERESTARTNOINTR: 2022 /* Rare. For example, fork() returns this if interrupted. 2023 * SA_RESTART is ignored (assumed set): the restart is unconditional. 2024 */ 2025 tprints("= ? ERESTARTNOINTR (To be restarted)"); 2026 break; 2027 case ERESTARTNOHAND: 2028 /* pause(), rt_sigsuspend() etc use this code. 2029 * SA_RESTART is ignored (assumed not set): 2030 * syscall won't restart (will return EINTR instead) 2031 * even after signal with SA_RESTART set. 2032 * However, after SIG_IGN or SIG_DFL signal it will. 2033 */ 2034 tprints("= ? ERESTARTNOHAND (Interrupted by signal)"); 2035 break; 2036 case ERESTART_RESTARTBLOCK: 2037 /* Syscalls like nanosleep(), poll() which can't be 2038 * restarted with their original arguments use this 2039 * code. Kernel will execute restart_syscall() instead, 2040 * which changes arguments before restarting syscall. 2041 * SA_RESTART is ignored (assumed not set) similarly 2042 * to ERESTARTNOHAND. (Kernel can't honor SA_RESTART 2043 * since restart data is saved in "restart block" 2044 * in task struct, and if signal handler uses a syscall 2045 * which in turn saves another such restart block, 2046 * old data is lost and restart becomes impossible) 2047 */ 2048 tprints("= ? ERESTART_RESTARTBLOCK (Interrupted by signal)"); 2049 break; 2050 default: 2051 if (u_error < 0) 2052 tprintf("= -1 E??? (errno %ld)", u_error); 2053 else if (u_error < nerrnos) 2054 tprintf("= -1 %s (%s)", errnoent[u_error], 2055 strerror(u_error)); 2056 else 2057 tprintf("= -1 ERRNO_%ld (%s)", u_error, 2058 strerror(u_error)); 2059 break; 2060 } 2061 if ((sys_res & RVAL_STR) && tcp->auxstr) 2062 tprintf(" (%s)", tcp->auxstr); 2063 } 2064 else { 2065 if (sys_res & RVAL_NONE) 2066 tprints("= ?"); 2067 else { 2068 switch (sys_res & RVAL_MASK) { 2069 case RVAL_HEX: 2070 tprintf("= %#lx", tcp->u_rval); 2071 break; 2072 case RVAL_OCTAL: 2073 tprintf("= %#lo", tcp->u_rval); 2074 break; 2075 case RVAL_UDECIMAL: 2076 tprintf("= %lu", tcp->u_rval); 2077 break; 2078 case RVAL_DECIMAL: 2079 tprintf("= %ld", tcp->u_rval); 2080 break; 2081 default: 2082 fprintf(stderr, 2083 "invalid rval format\n"); 2084 break; 2085 } 2086 } 2087 if ((sys_res & RVAL_STR) && tcp->auxstr) 2088 tprintf(" (%s)", tcp->auxstr); 2089 } 2090 if (Tflag) { 2091 tv_sub(&tv, &tv, &tcp->etime); 2092 tprintf(" <%ld.%06ld>", 2093 (long) tv.tv_sec, (long) tv.tv_usec); 2094 } 2095 tprints("\n"); 2096 dumpio(tcp); 2097 line_ended(); 2098 2099 ret: 2100 tcp->flags &= ~TCB_INSYSCALL; 2101 return 0; 2102} 2103 2104int 2105trace_syscall(struct tcb *tcp) 2106{ 2107 return exiting(tcp) ? 2108 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp); 2109} 2110