blob: 3385c24249615d5efee6ee8c04623723bb0c28e9 [file] [log] [blame]
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001/*
2 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
Wichert Akkerman4dc8a2a1999-12-23 14:20:14 +00005 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
6 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
7 * Linux for s390 port by D.J. Barrow
8 * <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00009 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. The name of the author may not be used to endorse or promote products
20 * derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000032 */
33
34#include "defs.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000035#include <sys/user.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000036#include <sys/param.h>
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000037
Wichert Akkerman15dea971999-10-06 13:06:34 +000038#ifdef HAVE_SYS_REG_H
Denys Vlasenko523635f2012-02-25 02:44:25 +010039# include <sys/reg.h>
40# ifndef PTRACE_PEEKUSR
41# define PTRACE_PEEKUSR PTRACE_PEEKUSER
42# endif
Wichert Akkermanfaf72222000-02-19 23:59:03 +000043#elif defined(HAVE_LINUX_PTRACE_H)
Denys Vlasenko523635f2012-02-25 02:44:25 +010044# undef PTRACE_SYSCALL
Roland McGrathce9f0742004-03-01 21:29:22 +000045# ifdef HAVE_STRUCT_IA64_FPREG
46# define ia64_fpreg XXX_ia64_fpreg
47# endif
48# ifdef HAVE_STRUCT_PT_ALL_USER_REGS
49# define pt_all_user_regs XXX_pt_all_user_regs
50# endif
Denys Vlasenko523635f2012-02-25 02:44:25 +010051# include <linux/ptrace.h>
Roland McGrathce9f0742004-03-01 21:29:22 +000052# undef ia64_fpreg
53# undef pt_all_user_regs
Wichert Akkerman15dea971999-10-06 13:06:34 +000054#endif
55
Denys Vlasenko84703742012-02-25 02:38:52 +010056#if defined(SPARC64)
Roland McGrath6d1a65c2004-07-12 07:44:08 +000057# undef PTRACE_GETREGS
58# define PTRACE_GETREGS PTRACE_GETREGS64
59# undef PTRACE_SETREGS
60# define PTRACE_SETREGS PTRACE_SETREGS64
Denys Vlasenko84703742012-02-25 02:38:52 +010061#endif
Roland McGrath6d1a65c2004-07-12 07:44:08 +000062
Denys Vlasenko84703742012-02-25 02:38:52 +010063#if defined(IA64)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +000064# include <asm/ptrace_offsets.h>
65# include <asm/rse.h>
66#endif
67
Steve McIntyred8d3bd32012-10-24 17:58:16 +010068#if defined(AARCH64)
69# include <asm/ptrace.h>
70# include <sys/uio.h>
71# include <elf.h>
72#endif
73
Chris Metcalf0b99a8a2013-02-05 17:48:33 +010074#if defined(TILE)
75# ifndef PT_FLAGS_COMPAT
76# define PT_FLAGS_COMPAT 0x10000 /* from Linux 3.8 on */
77# endif
78#endif
79
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000080#ifndef ERESTARTSYS
Denys Vlasenko523635f2012-02-25 02:44:25 +010081# define ERESTARTSYS 512
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000082#endif
Denys Vlasenko3da96932012-03-17 03:17:15 +010083#ifndef ERESTARTNOINTR
Denys Vlasenko523635f2012-02-25 02:44:25 +010084# define ERESTARTNOINTR 513
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000085#endif
Denys Vlasenko3da96932012-03-17 03:17:15 +010086#ifndef ERESTARTNOHAND
87# define ERESTARTNOHAND 514 /* restart if no handler */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000088#endif
Denys Vlasenko3da96932012-03-17 03:17:15 +010089#ifndef ERESTART_RESTARTBLOCK
Denys Vlasenko523635f2012-02-25 02:44:25 +010090# define ERESTART_RESTARTBLOCK 516 /* restart by calling sys_restart_syscall */
Roland McGrath9c555e72003-07-09 09:47:59 +000091#endif
Denys Vlasenko523635f2012-02-25 02:44:25 +010092
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000093#ifndef NSIG
Denys Vlasenko523635f2012-02-25 02:44:25 +010094# warning: NSIG is not defined, using 32
95# define NSIG 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000096#endif
97#ifdef ARM
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020098/* Ugh. Is this really correct? ARM has no RT signals?! */
Denys Vlasenko523635f2012-02-25 02:44:25 +010099# undef NSIG
100# define NSIG 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000101#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000102
103#include "syscall.h"
104
105/* Define these shorthand notations to simplify the syscallent files. */
Roland McGrath2fe7b132005-07-05 03:25:35 +0000106#define TD TRACE_DESC
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000107#define TF TRACE_FILE
108#define TI TRACE_IPC
109#define TN TRACE_NETWORK
110#define TP TRACE_PROCESS
111#define TS TRACE_SIGNAL
Namhyung Kim96792962012-10-24 11:41:57 +0900112#define TM TRACE_MEMORY
Dmitry V. Levin50a218d2011-01-18 17:36:20 +0000113#define NF SYSCALL_NEVER_FAILS
Denys Vlasenkoac1ce772011-08-23 13:24:17 +0200114#define MA MAX_ARGS
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000115
Roland McGrathee36ce12004-09-04 03:53:10 +0000116static const struct sysent sysent0[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000117#include "syscallent.h"
118};
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000119
120#if SUPPORTED_PERSONALITIES >= 2
Roland McGrathee36ce12004-09-04 03:53:10 +0000121static const struct sysent sysent1[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100122# include "syscallent1.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000123};
Denys Vlasenko39fca622011-08-20 02:12:33 +0200124#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000125
126#if SUPPORTED_PERSONALITIES >= 3
Roland McGrathee36ce12004-09-04 03:53:10 +0000127static const struct sysent sysent2[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100128# include "syscallent2.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000129};
Denys Vlasenko39fca622011-08-20 02:12:33 +0200130#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000131
132/* Now undef them since short defines cause wicked namespace pollution. */
Roland McGrath2fe7b132005-07-05 03:25:35 +0000133#undef TD
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000134#undef TF
135#undef TI
136#undef TN
137#undef TP
138#undef TS
Namhyung Kim96792962012-10-24 11:41:57 +0900139#undef TM
Dmitry V. Levin50a218d2011-01-18 17:36:20 +0000140#undef NF
Denys Vlasenkoac1ce772011-08-23 13:24:17 +0200141#undef MA
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000142
Denys Vlasenko39fca622011-08-20 02:12:33 +0200143/*
144 * `ioctlent.h' may be generated from `ioctlent.raw' by the auxiliary
145 * program `ioctlsort', such that the list is sorted by the `code' field.
146 * This has the side-effect of resolving the _IO.. macros into
147 * plain integers, eliminating the need to include here everything
148 * in "/usr/include".
149 */
150
Roland McGrathee36ce12004-09-04 03:53:10 +0000151static const char *const errnoent0[] = {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000152#include "errnoent.h"
153};
Denys Vlasenko39fca622011-08-20 02:12:33 +0200154static const char *const signalent0[] = {
155#include "signalent.h"
156};
157static const struct ioctlent ioctlent0[] = {
158#include "ioctlent.h"
159};
160enum { nsyscalls0 = ARRAY_SIZE(sysent0) };
161enum { nerrnos0 = ARRAY_SIZE(errnoent0) };
162enum { nsignals0 = ARRAY_SIZE(signalent0) };
163enum { nioctlents0 = ARRAY_SIZE(ioctlent0) };
164int qual_flags0[MAX_QUALS];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000165
166#if SUPPORTED_PERSONALITIES >= 2
Roland McGrathee36ce12004-09-04 03:53:10 +0000167static const char *const errnoent1[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100168# include "errnoent1.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000169};
Denys Vlasenko39fca622011-08-20 02:12:33 +0200170static const char *const signalent1[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100171# include "signalent1.h"
Denys Vlasenko39fca622011-08-20 02:12:33 +0200172};
173static const struct ioctlent ioctlent1[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100174# include "ioctlent1.h"
Denys Vlasenko39fca622011-08-20 02:12:33 +0200175};
176enum { nsyscalls1 = ARRAY_SIZE(sysent1) };
177enum { nerrnos1 = ARRAY_SIZE(errnoent1) };
178enum { nsignals1 = ARRAY_SIZE(signalent1) };
179enum { nioctlents1 = ARRAY_SIZE(ioctlent1) };
180int qual_flags1[MAX_QUALS];
181#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000182
183#if SUPPORTED_PERSONALITIES >= 3
Roland McGrathee36ce12004-09-04 03:53:10 +0000184static const char *const errnoent2[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100185# include "errnoent2.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000186};
Denys Vlasenko39fca622011-08-20 02:12:33 +0200187static const char *const signalent2[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100188# include "signalent2.h"
Denys Vlasenko39fca622011-08-20 02:12:33 +0200189};
190static const struct ioctlent ioctlent2[] = {
Denys Vlasenko523635f2012-02-25 02:44:25 +0100191# include "ioctlent2.h"
Denys Vlasenko39fca622011-08-20 02:12:33 +0200192};
193enum { nsyscalls2 = ARRAY_SIZE(sysent2) };
194enum { nerrnos2 = ARRAY_SIZE(errnoent2) };
195enum { nsignals2 = ARRAY_SIZE(signalent2) };
196enum { nioctlents2 = ARRAY_SIZE(ioctlent2) };
197int qual_flags2[MAX_QUALS];
198#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000199
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100200const struct sysent *sysent = sysent0;
201const char *const *errnoent = errnoent0;
202const char *const *signalent = signalent0;
203const struct ioctlent *ioctlent = ioctlent0;
204unsigned nsyscalls = nsyscalls0;
205unsigned nerrnos = nerrnos0;
206unsigned nsignals = nsignals0;
207unsigned nioctlents = nioctlents0;
208int *qual_flags = qual_flags0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000209
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100210#if SUPPORTED_PERSONALITIES > 1
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000211int current_personality;
212
Roland McGrath4b2dcca2006-01-12 10:18:53 +0000213const int personality_wordsize[SUPPORTED_PERSONALITIES] = {
214 PERSONALITY0_WORDSIZE,
Roland McGrath4b2dcca2006-01-12 10:18:53 +0000215 PERSONALITY1_WORDSIZE,
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100216# if SUPPORTED_PERSONALITIES > 2
Roland McGrath4b2dcca2006-01-12 10:18:53 +0000217 PERSONALITY2_WORDSIZE,
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100218# endif
Denys Vlasenko5c774b22011-08-20 01:50:09 +0200219};
Roland McGrath4b2dcca2006-01-12 10:18:53 +0000220
Denys Vlasenko5c774b22011-08-20 01:50:09 +0200221void
Dmitry V. Levin3abe8b22006-12-20 22:37:21 +0000222set_personality(int personality)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000223{
224 switch (personality) {
225 case 0:
226 errnoent = errnoent0;
227 nerrnos = nerrnos0;
228 sysent = sysent0;
229 nsyscalls = nsyscalls0;
230 ioctlent = ioctlent0;
231 nioctlents = nioctlents0;
232 signalent = signalent0;
233 nsignals = nsignals0;
Roland McGrath138c6a32006-01-12 09:50:49 +0000234 qual_flags = qual_flags0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000235 break;
236
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000237 case 1:
238 errnoent = errnoent1;
239 nerrnos = nerrnos1;
240 sysent = sysent1;
241 nsyscalls = nsyscalls1;
242 ioctlent = ioctlent1;
243 nioctlents = nioctlents1;
244 signalent = signalent1;
245 nsignals = nsignals1;
Roland McGrath138c6a32006-01-12 09:50:49 +0000246 qual_flags = qual_flags1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000247 break;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000248
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100249# if SUPPORTED_PERSONALITIES >= 3
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000250 case 2:
251 errnoent = errnoent2;
252 nerrnos = nerrnos2;
253 sysent = sysent2;
254 nsyscalls = nsyscalls2;
255 ioctlent = ioctlent2;
256 nioctlents = nioctlents2;
257 signalent = signalent2;
258 nsignals = nsignals2;
Roland McGrath138c6a32006-01-12 09:50:49 +0000259 qual_flags = qual_flags2;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000260 break;
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100261# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000262 }
263
264 current_personality = personality;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000265}
266
Dmitry V. Levina5a839a2011-12-23 00:50:49 +0000267static void
268update_personality(struct tcb *tcp, int personality)
269{
270 if (personality == current_personality)
271 return;
272 set_personality(personality);
273
274 if (personality == tcp->currpers)
275 return;
276 tcp->currpers = personality;
277
H.J. Lu35be5812012-04-16 13:00:01 +0200278# if defined(POWERPC64)
Dmitry V. Levina5a839a2011-12-23 00:50:49 +0000279 if (!qflag) {
280 static const char *const names[] = {"64 bit", "32 bit"};
281 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
282 tcp->pid, names[personality]);
283 }
H.J. Lu35be5812012-04-16 13:00:01 +0200284# elif defined(X86_64)
285 if (!qflag) {
286 static const char *const names[] = {"64 bit", "32 bit", "x32"};
287 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
288 tcp->pid, names[personality]);
289 }
H.J. Lu085e4282012-04-17 11:05:04 -0700290# elif defined(X32)
291 if (!qflag) {
292 static const char *const names[] = {"x32", "32 bit"};
293 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
294 tcp->pid, names[personality]);
295 }
Steve McIntyre890a5ca2012-11-10 11:24:48 +0000296# elif defined(AARCH64)
297 if (!qflag) {
298 static const char *const names[] = {"32-bit ARM", "AArch64"};
299 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
300 tcp->pid, names[personality]);
301 }
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100302# elif defined(TILE)
303 if (!qflag) {
304 static const char *const names[] = {"64-bit", "32-bit"};
305 fprintf(stderr, "[ Process PID=%d runs in %s mode. ]\n",
306 tcp->pid, names[personality]);
307 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100308# endif
Dmitry V. Levina5a839a2011-12-23 00:50:49 +0000309}
310#endif
Roland McGrathe10e62a2004-09-04 04:20:43 +0000311
Roland McGrath9797ceb2002-12-30 10:23:00 +0000312static int qual_syscall(), qual_signal(), qual_fault(), qual_desc();
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000313
Roland McGrathe10e62a2004-09-04 04:20:43 +0000314static const struct qual_options {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000315 int bitflag;
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000316 const char *option_name;
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000317 int (*qualify)(const char *, int, int);
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000318 const char *argument_name;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000319} qual_options[] = {
Roland McGrath9797ceb2002-12-30 10:23:00 +0000320 { QUAL_TRACE, "trace", qual_syscall, "system call" },
321 { QUAL_TRACE, "t", qual_syscall, "system call" },
322 { QUAL_ABBREV, "abbrev", qual_syscall, "system call" },
323 { QUAL_ABBREV, "a", qual_syscall, "system call" },
324 { QUAL_VERBOSE, "verbose", qual_syscall, "system call" },
325 { QUAL_VERBOSE, "v", qual_syscall, "system call" },
326 { QUAL_RAW, "raw", qual_syscall, "system call" },
327 { QUAL_RAW, "x", qual_syscall, "system call" },
328 { QUAL_SIGNAL, "signal", qual_signal, "signal" },
329 { QUAL_SIGNAL, "signals", qual_signal, "signal" },
330 { QUAL_SIGNAL, "s", qual_signal, "signal" },
331 { QUAL_FAULT, "fault", qual_fault, "fault" },
332 { QUAL_FAULT, "faults", qual_fault, "fault" },
333 { QUAL_FAULT, "m", qual_fault, "fault" },
334 { QUAL_READ, "read", qual_desc, "descriptor" },
335 { QUAL_READ, "reads", qual_desc, "descriptor" },
336 { QUAL_READ, "r", qual_desc, "descriptor" },
337 { QUAL_WRITE, "write", qual_desc, "descriptor" },
338 { QUAL_WRITE, "writes", qual_desc, "descriptor" },
339 { QUAL_WRITE, "w", qual_desc, "descriptor" },
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000340 { 0, NULL, NULL, NULL },
341};
342
Roland McGrath9797ceb2002-12-30 10:23:00 +0000343static void
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000344qualify_one(int n, int bitflag, int not, int pers)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000345{
Roland McGrath138c6a32006-01-12 09:50:49 +0000346 if (pers == 0 || pers < 0) {
347 if (not)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000348 qual_flags0[n] &= ~bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000349 else
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000350 qual_flags0[n] |= bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000351 }
352
353#if SUPPORTED_PERSONALITIES >= 2
354 if (pers == 1 || pers < 0) {
355 if (not)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000356 qual_flags1[n] &= ~bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000357 else
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000358 qual_flags1[n] |= bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000359 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100360#endif
Roland McGrath138c6a32006-01-12 09:50:49 +0000361
362#if SUPPORTED_PERSONALITIES >= 3
363 if (pers == 2 || pers < 0) {
364 if (not)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000365 qual_flags2[n] &= ~bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000366 else
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000367 qual_flags2[n] |= bitflag;
Roland McGrath138c6a32006-01-12 09:50:49 +0000368 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100369#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000370}
371
372static int
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000373qual_syscall(const char *s, int bitflag, int not)
Roland McGrath9797ceb2002-12-30 10:23:00 +0000374{
375 int i;
Roland McGrathfe6b3522005-02-02 04:40:11 +0000376 int rc = -1;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000377
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +0100378 if (*s >= '0' && *s <= '9') {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000379 int i = string_to_uint(s);
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000380 if (i < 0 || i >= MAX_QUALS)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000381 return -1;
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000382 qualify_one(i, bitflag, not, -1);
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000383 return 0;
Roland McGrath48a035f2006-01-12 09:45:56 +0000384 }
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000385 for (i = 0; i < nsyscalls0; i++)
Dmitry V. Levin4372cc92012-03-26 14:14:50 +0000386 if (sysent0[i].sys_name &&
387 strcmp(s, sysent0[i].sys_name) == 0) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000388 qualify_one(i, bitflag, not, 0);
Roland McGrathfe6b3522005-02-02 04:40:11 +0000389 rc = 0;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000390 }
Roland McGrath138c6a32006-01-12 09:50:49 +0000391
392#if SUPPORTED_PERSONALITIES >= 2
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000393 for (i = 0; i < nsyscalls1; i++)
Dmitry V. Levin4372cc92012-03-26 14:14:50 +0000394 if (sysent1[i].sys_name &&
395 strcmp(s, sysent1[i].sys_name) == 0) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000396 qualify_one(i, bitflag, not, 1);
Roland McGrath138c6a32006-01-12 09:50:49 +0000397 rc = 0;
398 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100399#endif
Roland McGrath138c6a32006-01-12 09:50:49 +0000400
401#if SUPPORTED_PERSONALITIES >= 3
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000402 for (i = 0; i < nsyscalls2; i++)
Dmitry V. Levin4372cc92012-03-26 14:14:50 +0000403 if (sysent2[i].sys_name &&
404 strcmp(s, sysent2[i].sys_name) == 0) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000405 qualify_one(i, bitflag, not, 2);
Roland McGrath138c6a32006-01-12 09:50:49 +0000406 rc = 0;
407 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100408#endif
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000409
Roland McGrathfe6b3522005-02-02 04:40:11 +0000410 return rc;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000411}
412
413static int
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000414qual_signal(const char *s, int bitflag, int not)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000415{
416 int i;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000417
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +0100418 if (*s >= '0' && *s <= '9') {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000419 int signo = string_to_uint(s);
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000420 if (signo < 0 || signo >= MAX_QUALS)
421 return -1;
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000422 qualify_one(signo, bitflag, not, -1);
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000423 return 0;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000424 }
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000425 if (strncasecmp(s, "SIG", 3) == 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000426 s += 3;
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +0100427 for (i = 0; i <= NSIG; i++) {
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000428 if (strcasecmp(s, signame(i) + 3) == 0) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000429 qualify_one(i, bitflag, not, -1);
Roland McGrath76421df2005-02-02 03:51:18 +0000430 return 0;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000431 }
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +0100432 }
Roland McGrath76421df2005-02-02 03:51:18 +0000433 return -1;
Roland McGrath9797ceb2002-12-30 10:23:00 +0000434}
435
436static int
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000437qual_fault(const char *s, int bitflag, int not)
Roland McGrath9797ceb2002-12-30 10:23:00 +0000438{
439 return -1;
440}
441
442static int
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000443qual_desc(const char *s, int bitflag, int not)
Roland McGrath9797ceb2002-12-30 10:23:00 +0000444{
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +0100445 if (*s >= '0' && *s <= '9') {
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000446 int desc = string_to_uint(s);
Roland McGrathfe6b3522005-02-02 04:40:11 +0000447 if (desc < 0 || desc >= MAX_QUALS)
448 return -1;
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000449 qualify_one(desc, bitflag, not, -1);
Roland McGrath2b619022003-04-10 18:58:20 +0000450 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000451 }
452 return -1;
453}
454
455static int
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000456lookup_class(const char *s)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000457{
458 if (strcmp(s, "file") == 0)
459 return TRACE_FILE;
460 if (strcmp(s, "ipc") == 0)
461 return TRACE_IPC;
462 if (strcmp(s, "network") == 0)
463 return TRACE_NETWORK;
464 if (strcmp(s, "process") == 0)
465 return TRACE_PROCESS;
466 if (strcmp(s, "signal") == 0)
467 return TRACE_SIGNAL;
Roland McGrath2fe7b132005-07-05 03:25:35 +0000468 if (strcmp(s, "desc") == 0)
469 return TRACE_DESC;
Namhyung Kim96792962012-10-24 11:41:57 +0900470 if (strcmp(s, "memory") == 0)
471 return TRACE_MEMORY;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000472 return -1;
473}
474
475void
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000476qualify(const char *s)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000477{
Roland McGrathe10e62a2004-09-04 04:20:43 +0000478 const struct qual_options *opt;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000479 int not;
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000480 char *copy;
481 const char *p;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000482 int i, n;
483
484 opt = &qual_options[0];
485 for (i = 0; (p = qual_options[i].option_name); i++) {
486 n = strlen(p);
487 if (strncmp(s, p, n) == 0 && s[n] == '=') {
488 opt = &qual_options[i];
489 s += n + 1;
490 break;
491 }
492 }
493 not = 0;
494 if (*s == '!') {
495 not = 1;
496 s++;
497 }
498 if (strcmp(s, "none") == 0) {
499 not = 1 - not;
500 s = "all";
501 }
502 if (strcmp(s, "all") == 0) {
503 for (i = 0; i < MAX_QUALS; i++) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000504 qualify_one(i, opt->bitflag, not, -1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000505 }
506 return;
507 }
508 for (i = 0; i < MAX_QUALS; i++) {
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000509 qualify_one(i, opt->bitflag, !not, -1);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000510 }
Denys Vlasenko5d645812011-08-20 12:48:18 +0200511 copy = strdup(s);
Denys Vlasenko1d46ba52011-08-31 14:00:02 +0200512 if (!copy)
513 die_out_of_memory();
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000514 for (p = strtok(copy, ","); p; p = strtok(NULL, ",")) {
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000515 if (opt->bitflag == QUAL_TRACE && (n = lookup_class(p)) > 0) {
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000516 for (i = 0; i < nsyscalls0; i++)
Roland McGrath138c6a32006-01-12 09:50:49 +0000517 if (sysent0[i].sys_flags & n)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000518 qualify_one(i, opt->bitflag, not, 0);
Roland McGrath138c6a32006-01-12 09:50:49 +0000519
520#if SUPPORTED_PERSONALITIES >= 2
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000521 for (i = 0; i < nsyscalls1; i++)
Roland McGrath138c6a32006-01-12 09:50:49 +0000522 if (sysent1[i].sys_flags & n)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000523 qualify_one(i, opt->bitflag, not, 1);
Denys Vlasenko523635f2012-02-25 02:44:25 +0100524#endif
Roland McGrath138c6a32006-01-12 09:50:49 +0000525
526#if SUPPORTED_PERSONALITIES >= 3
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000527 for (i = 0; i < nsyscalls2; i++)
Roland McGrath138c6a32006-01-12 09:50:49 +0000528 if (sysent2[i].sys_flags & n)
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000529 qualify_one(i, opt->bitflag, not, 2);
Denys Vlasenko523635f2012-02-25 02:44:25 +0100530#endif
Dmitry V. Levinc18c7032007-08-22 21:43:30 +0000531
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000532 continue;
533 }
Dmitry V. Levin35d05722010-09-15 16:18:20 +0000534 if (opt->qualify(p, opt->bitflag, not)) {
Denys Vlasenko4c65c442012-03-08 11:54:10 +0100535 error_msg_and_die("invalid %s '%s'",
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000536 opt->argument_name, p);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000537 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000538 }
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000539 free(copy);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000540 return;
541}
542
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000543#ifdef SYS_socket_subcall
Roland McGratha4d48532005-06-08 20:45:28 +0000544static void
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000545decode_socket_subcall(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000546{
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000547 unsigned long addr;
548 unsigned int i, size;
Wichert Akkermanbf79f2e2000-09-01 21:03:06 +0000549
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000550 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_socket_nsubcalls)
551 return;
552
553 tcp->scno = SYS_socket_subcall + tcp->u_arg[0];
554 addr = tcp->u_arg[1];
555 tcp->u_nargs = sysent[tcp->scno].nargs;
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100556 size = current_wordsize;
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000557 for (i = 0; i < tcp->u_nargs; ++i) {
558 if (size == sizeof(int)) {
559 unsigned int arg;
560 if (umove(tcp, addr, &arg) < 0)
561 arg = 0;
562 tcp->u_arg[i] = arg;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000563 }
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000564 else {
565 unsigned long arg;
566 if (umove(tcp, addr, &arg) < 0)
567 arg = 0;
568 tcp->u_arg[i] = arg;
569 }
570 addr += size;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000571 }
572}
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000573#endif
Mike Frysinger3362e892012-03-15 01:09:19 -0400574
Dmitry V. Levin648c22c2012-03-15 22:08:55 +0000575#ifdef SYS_ipc_subcall
576static void
577decode_ipc_subcall(struct tcb *tcp)
578{
579 unsigned int i;
580
581 if (tcp->u_arg[0] < 0 || tcp->u_arg[0] >= SYS_ipc_nsubcalls)
582 return;
583
584 tcp->scno = SYS_ipc_subcall + tcp->u_arg[0];
585 tcp->u_nargs = sysent[tcp->scno].nargs;
586 for (i = 0; i < tcp->u_nargs; i++)
587 tcp->u_arg[i] = tcp->u_arg[i + 1];
588}
589#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000590
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200591int
592printargs(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000593{
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200594 if (entering(tcp)) {
595 int i;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000596
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200597 for (i = 0; i < tcp->u_nargs; i++)
598 tprintf("%s%#lx", i ? ", " : "", tcp->u_arg[i]);
599 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000600 return 0;
601}
602
Denys Vlasenko72879c62012-02-27 14:18:02 +0100603int
604printargs_lu(struct tcb *tcp)
605{
606 if (entering(tcp)) {
607 int i;
608
609 for (i = 0; i < tcp->u_nargs; i++)
610 tprintf("%s%lu", i ? ", " : "", tcp->u_arg[i]);
611 }
612 return 0;
613}
614
615int
616printargs_ld(struct tcb *tcp)
617{
618 if (entering(tcp)) {
619 int i;
620
621 for (i = 0; i < tcp->u_nargs; i++)
622 tprintf("%s%ld", i ? ", " : "", tcp->u_arg[i]);
623 }
624 return 0;
625}
626
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100627#if defined(SPARC) || defined(SPARC64) || defined(IA64) || defined(SH)
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200628long
629getrval2(struct tcb *tcp)
630{
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100631 long val;
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200632
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100633# if defined(SPARC) || defined(SPARC64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200634 val = regs.u_regs[U_REG_O1];
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100635# elif defined(SH)
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200636 if (upeek(tcp, 4*(REG_REG0+1), &val) < 0)
637 return -1;
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100638# elif defined(IA64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200639 if (upeek(tcp, PT_R9, &val) < 0)
640 return -1;
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100641# endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200642
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200643 return val;
644}
Denys Vlasenko1ebe08d2013-02-05 16:55:23 +0100645#endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200646
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200647int
648is_restart_error(struct tcb *tcp)
649{
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200650 switch (tcp->u_error) {
651 case ERESTARTSYS:
652 case ERESTARTNOINTR:
653 case ERESTARTNOHAND:
654 case ERESTART_RESTARTBLOCK:
655 return 1;
656 default:
657 break;
658 }
Denys Vlasenkoa6146922011-08-24 18:07:22 +0200659 return 0;
660}
661
Denys Vlasenko523635f2012-02-25 02:44:25 +0100662#if defined(I386)
Denys Vlasenkob11322f2012-01-10 16:40:35 +0100663struct pt_regs i386_regs;
H.J. Lu35be5812012-04-16 13:00:01 +0200664#elif defined(X86_64) || defined(X32)
Denys Vlasenkoe73a89d2012-01-18 11:07:24 +0100665/*
666 * On 32 bits, pt_regs and user_regs_struct are the same,
667 * but on 64 bits, user_regs_struct has six more fields:
668 * fs_base, gs_base, ds, es, fs, gs.
669 * PTRACE_GETREGS fills them too, so struct pt_regs would overflow.
670 */
671static struct user_regs_struct x86_64_regs;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100672#elif defined(IA64)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200673long ia32 = 0; /* not static */
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100674static long ia64_r8, ia64_r10;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100675#elif defined(POWERPC)
Denys Vlasenko46dc8b22012-03-21 00:07:25 +0100676static long ppc_result;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100677#elif defined(M68K)
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100678static long m68k_d0;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100679#elif defined(BFIN)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200680static long r0;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100681#elif defined(ARM)
Denys Vlasenko401374e2013-02-06 18:24:39 +0100682struct pt_regs arm_regs; /* not static */
Steve McIntyred8d3bd32012-10-24 17:58:16 +0100683#elif defined(AARCH64)
Steve McIntyre890a5ca2012-11-10 11:24:48 +0000684static struct user_pt_regs aarch64_regs;
Denys Vlasenko401374e2013-02-06 18:24:39 +0100685static struct arm_pt_regs arm_regs;
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100686static struct iovec aarch64_io = {
687 .iov_base = &aarch64_regs
688};
Denys Vlasenko523635f2012-02-25 02:44:25 +0100689#elif defined(ALPHA)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200690static long r0;
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100691static long alpha_a3;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100692#elif defined(AVR32)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200693static struct pt_regs regs;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100694#elif defined(SPARC) || defined(SPARC64)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100695struct pt_regs regs; /* not static */
Denys Vlasenko523635f2012-02-25 02:44:25 +0100696#elif defined(LINUX_MIPSN32)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200697static long long a3;
698static long long r2;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100699#elif defined(MIPS)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200700static long a3;
701static long r2;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100702#elif defined(S390) || defined(S390X)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200703static long gpr2;
704static long pc;
705static long syscall_mode;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100706#elif defined(HPPA)
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100707static long hppa_r28;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100708#elif defined(SH)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200709static long r0;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100710#elif defined(SH64)
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100711static long sh64_r9;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100712#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100713static long cris_r10;
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100714#elif defined(TILE)
715struct pt_regs tile_regs;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100716#elif defined(MICROBLAZE)
Denys Vlasenko89804ec2013-02-07 13:14:48 +0100717static long microblaze_r3;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100718#endif
Wichert Akkermanc7926982000-04-10 22:22:31 +0000719
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100720void
721printcall(struct tcb *tcp)
722{
723#define PRINTBADPC tprintf(sizeof(long) == 4 ? "[????????] " : \
724 sizeof(long) == 8 ? "[????????????????] " : \
725 NULL /* crash */)
726 if (get_regs_error) {
727 PRINTBADPC;
728 return;
729 }
730#if defined(I386)
731 tprintf("[%08lx] ", i386_regs.eip);
732#elif defined(S390) || defined(S390X)
733 long psw;
734 if (upeek(tcp, PT_PSWADDR, &psw) < 0) {
735 PRINTBADPC;
736 return;
737 }
738# ifdef S390
739 tprintf("[%08lx] ", psw);
740# elif S390X
Dmitry V. Levinddba73e2013-02-05 19:01:58 +0000741 tprintf("[%016lx] ", psw);
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100742# endif
743#elif defined(X86_64) || defined(X32)
Dmitry V. Levinddba73e2013-02-05 19:01:58 +0000744 tprintf("[%016lx] ", (unsigned long) x86_64_regs.rip);
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100745#elif defined(IA64)
746 long ip;
747
748 if (upeek(tcp, PT_B0, &ip) < 0) {
749 PRINTBADPC;
750 return;
751 }
752 tprintf("[%08lx] ", ip);
753#elif defined(POWERPC)
754 long pc;
755
756 if (upeek(tcp, sizeof(unsigned long)*PT_NIP, &pc) < 0) {
757 PRINTBADPC;
758 return;
759 }
760# ifdef POWERPC64
761 tprintf("[%016lx] ", pc);
762# else
763 tprintf("[%08lx] ", pc);
764# endif
765#elif defined(M68K)
766 long pc;
767
768 if (upeek(tcp, 4*PT_PC, &pc) < 0) {
769 tprints("[????????] ");
770 return;
771 }
772 tprintf("[%08lx] ", pc);
773#elif defined(ALPHA)
774 long pc;
775
776 if (upeek(tcp, REG_PC, &pc) < 0) {
777 tprints("[????????????????] ");
778 return;
779 }
780 tprintf("[%08lx] ", pc);
781#elif defined(SPARC)
782 tprintf("[%08lx] ", regs.pc);
783#elif defined(SPARC64)
784 tprintf("[%08lx] ", regs.tpc);
785#elif defined(HPPA)
786 long pc;
787
788 if (upeek(tcp, PT_IAOQ0, &pc) < 0) {
789 tprints("[????????] ");
790 return;
791 }
792 tprintf("[%08lx] ", pc);
793#elif defined(MIPS)
794 long pc;
795
796 if (upeek(tcp, REG_EPC, &pc) < 0) {
797 tprints("[????????] ");
798 return;
799 }
800 tprintf("[%08lx] ", pc);
801#elif defined(SH)
802 long pc;
803
804 if (upeek(tcp, 4*REG_PC, &pc) < 0) {
805 tprints("[????????] ");
806 return;
807 }
808 tprintf("[%08lx] ", pc);
809#elif defined(SH64)
810 long pc;
811
812 if (upeek(tcp, REG_PC, &pc) < 0) {
813 tprints("[????????????????] ");
814 return;
815 }
816 tprintf("[%08lx] ", pc);
817#elif defined(ARM)
Denys Vlasenko401374e2013-02-06 18:24:39 +0100818 tprintf("[%08lx] ", arm_regs.ARM_pc);
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100819/*#elif defined(AARCH64) ??? */
820#elif defined(AVR32)
821 tprintf("[%08lx] ", regs.pc);
822#elif defined(BFIN)
823 long pc;
824
825 if (upeek(tcp, PT_PC, &pc) < 0) {
826 PRINTBADPC;
827 return;
828 }
829 tprintf("[%08lx] ", pc);
830#elif defined(CRISV10)
831 long pc;
832
833 if (upeek(tcp, 4*PT_IRP, &pc) < 0) {
834 PRINTBADPC;
835 return;
836 }
837 tprintf("[%08lx] ", pc);
838#elif defined(CRISV32)
839 long pc;
840
841 if (upeek(tcp, 4*PT_ERP, &pc) < 0) {
842 PRINTBADPC;
843 return;
844 }
845 tprintf("[%08lx] ", pc);
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100846#elif defined(TILE)
847# ifdef _LP64
Chris Metcalfaf8dc6b2013-02-05 13:02:42 -0500848 tprintf("[%016lx] ", (unsigned long) tile_regs.pc);
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100849# else
Chris Metcalfaf8dc6b2013-02-05 13:02:42 -0500850 tprintf("[%08lx] ", (unsigned long) tile_regs.pc);
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100851# endif
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100852#endif /* architecture */
853}
854
855#ifndef get_regs
856long get_regs_error;
857void get_regs(pid_t pid)
858{
859# if defined(AVR32)
860 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, &regs);
861# elif defined(I386)
862 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &i386_regs);
863# elif defined(X86_64) || defined(X32)
864 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &x86_64_regs);
Denys Vlasenko401374e2013-02-06 18:24:39 +0100865# elif defined(ARM)
866 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (void *)&arm_regs);
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100867# elif defined(AARCH64)
868 /*aarch64_io.iov_base = &aarch64_regs; - already is */
869 aarch64_io.iov_len = sizeof(aarch64_regs);
870 get_regs_error = ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, (void *)&aarch64_io);
871 if (get_regs_error)
872 return;
873 switch (aarch64_io.iov_len) {
874 case sizeof(regs):
875 /* We are in 32-bit mode */
Denys Vlasenko401374e2013-02-06 18:24:39 +0100876 memcpy(&arm_regs, &aarch64_regs, sizeof(arm_regs));
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100877 break;
878 case sizeof(aarch64_regs):
879 /* We are in 64-bit mode */
880 /* Data is already in aarch64_regs */
881 break;
882 default:
883 get_regs_error = -1;
884 break;
885 }
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100886# elif defined(SPARC) || defined(SPARC64)
887 get_regs_error = ptrace(PTRACE_GETREGS, pid, (char *)&regs, 0);
Chris Metcalf0b99a8a2013-02-05 17:48:33 +0100888# elif defined(TILE)
Chris Metcalfaf8dc6b2013-02-05 13:02:42 -0500889 get_regs_error = ptrace(PTRACE_GETREGS, pid, NULL, (long) &tile_regs);
Denys Vlasenkoce7d9532013-02-05 16:36:13 +0100890# endif
891}
892#endif
893
Denys Vlasenkob88f9612011-08-21 18:03:23 +0200894/* Returns:
Denys Vlasenko907735a2012-03-21 00:23:16 +0100895 * 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
Denys Vlasenkob88f9612011-08-21 18:03:23 +0200898 * ("????" etc) and bail out.
899 */
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100900static int
Denys Vlasenko06602d92011-08-24 17:53:52 +0200901get_scno(struct tcb *tcp)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000902{
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000903 long scno = 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000904
Denys Vlasenko523635f2012-02-25 02:44:25 +0100905#if defined(S390) || defined(S390X)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000906 if (upeek(tcp, PT_GPR2, &syscall_mode) < 0)
Denys Vlasenkob63256e2011-06-07 12:13:24 +0200907 return -1;
Roland McGrath2f924ca2003-06-26 22:23:28 +0000908
909 if (syscall_mode != -ENOSYS) {
910 /*
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000911 * Since kernel version 2.5.44 the scno gets passed in gpr2.
Roland McGrath2f924ca2003-06-26 22:23:28 +0000912 */
913 scno = syscall_mode;
914 } else {
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +0000915 /*
Michal Ludvig882eda82002-11-11 12:50:47 +0000916 * Old style of "passing" the scno via the SVC instruction.
917 */
Michal Ludvig882eda82002-11-11 12:50:47 +0000918 long opcode, offset_reg, tmp;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +0200919 void *svc_addr;
Denys Vlasenko7c9ba8b2011-08-19 19:46:32 +0200920 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 };
Roland McGrath761b5d72002-12-15 23:58:31 +0000926
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000927 if (upeek(tcp, PT_PSWADDR, &pc) < 0)
Michal Ludvig882eda82002-11-11 12:50:47 +0000928 return -1;
Roland McGrath96dc5142003-01-20 10:23:04 +0000929 errno = 0;
Denys Vlasenkofb036672009-01-23 16:30:26 +0000930 opcode = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)(pc-sizeof(long)), 0);
Roland McGrath96dc5142003-01-20 10:23:04 +0000931 if (errno) {
Dmitry V. Levin9a71bcd2012-09-17 23:20:54 +0000932 perror_msg("%s", "peektext(pc-oneword)");
Michal Ludvig882eda82002-11-11 12:50:47 +0000933 return -1;
Roland McGrath96dc5142003-01-20 10:23:04 +0000934 }
Michal Ludvig882eda82002-11-11 12:50:47 +0000935
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 */
Michal Ludvig882eda82002-11-11 12:50:47 +0000945 if ((opcode & 0xff00) == 0x0a00) {
946 /* SVC opcode */
947 scno = opcode & 0xff;
Roland McGrath761b5d72002-12-15 23:58:31 +0000948 }
Michal Ludvig882eda82002-11-11 12:50:47 +0000949 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;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000960 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
Michal Ludvig882eda82002-11-11 12:50:47 +0000961 return -1;
962 svc_addr += tmp;
963
964 tmp = 0;
965 offset_reg = (opcode & 0x0000f000) >> 12;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000966 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
Michal Ludvig882eda82002-11-11 12:50:47 +0000967 return -1;
968 svc_addr += tmp;
969
Denys Vlasenkofb036672009-01-23 16:30:26 +0000970 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, svc_addr, 0);
Michal Ludvig882eda82002-11-11 12:50:47 +0000971 if (errno)
972 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100973# if defined(S390X)
Michal Ludvig882eda82002-11-11 12:50:47 +0000974 scno >>= 48;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100975# else
Michal Ludvig882eda82002-11-11 12:50:47 +0000976 scno >>= 16;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100977# endif
Michal Ludvig882eda82002-11-11 12:50:47 +0000978 tmp = 0;
979 offset_reg = (opcode & 0x00f00000) >> 20;
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000980 if (offset_reg && (upeek(tcp, gpr_offset[offset_reg], &tmp) < 0))
Michal Ludvig882eda82002-11-11 12:50:47 +0000981 return -1;
982
983 scno = (scno | tmp) & 0xff;
984 }
985 }
Denys Vlasenko523635f2012-02-25 02:44:25 +0100986#elif defined(POWERPC)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +0000987 if (upeek(tcp, sizeof(unsigned long)*PT_R0, &scno) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000988 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +0100989# ifdef POWERPC64
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +0200990 /* 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;
Andreas Schwabd69fa492010-07-12 21:39:57 +0200995
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +0200996 /* 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;
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001004 update_personality(tcp, currpers);
Denys Vlasenko523635f2012-02-25 02:44:25 +01001005# endif
1006#elif defined(AVR32)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001007 scno = regs.r8;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001008#elif defined(BFIN)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001009 if (upeek(tcp, PT_ORIG_P0, &scno))
Dmitry V. Levin87ea1f42008-11-10 22:21:41 +00001010 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001011#elif defined(I386)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001012 scno = i386_regs.orig_eax;
H.J. Lu35be5812012-04-16 13:00:01 +02001013#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
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001021 int currpers;
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001022 scno = x86_64_regs.orig_rax;
Michal Ludvig0e035502002-09-23 15:41:01 +00001023
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001024 /* Check CS register value. On x86-64 linux it is:
1025 * 0x33 for long mode (64 bit)
1026 * 0x23 for compatibility mode (32 bit)
H.J. Lu35be5812012-04-16 13:00:01 +02001027 * Check DS register value. On x86-64 linux it is:
1028 * 0x2b for x32 mode (x86-64 in 32 bit)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001029 */
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001030 switch (x86_64_regs.cs) {
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001031 case 0x23: currpers = 1; break;
H.J. Lu35be5812012-04-16 13:00:01 +02001032 case 0x33:
1033 if (x86_64_regs.ds == 0x2b) {
1034 currpers = 2;
1035 scno &= ~__X32_SYSCALL_MASK;
1036 } else
1037 currpers = 0;
1038 break;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001039 default:
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001040 fprintf(stderr, "Unknown value CS=0x%08X while "
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001041 "detecting personality of process "
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001042 "PID=%d\n", (int)x86_64_regs.cs, tcp->pid);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001043 currpers = current_personality;
1044 break;
1045 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001046# if 0
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001047 /* 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;
Michal Ludvig0e035502002-09-23 15:41:01 +00001052
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001053 rip = x86_64_regs.rip;
Roland McGrath761b5d72002-12-15 23:58:31 +00001054
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001055 /* sizeof(syscall) == sizeof(int 0x80) == 2 */
1056 rip -= 2;
1057 errno = 0;
Michal Ludvig0e035502002-09-23 15:41:01 +00001058
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001059 call = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)rip, (char *)0);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001060 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 "
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001073 "PID=%d\n", (int)call, tcp->pid);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001074 break;
1075 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001076# endif
H.J. Lu35be5812012-04-16 13:00:01 +02001077# ifdef X32
H.J. Lu085e4282012-04-17 11:05:04 -07001078 /* 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;
H.J. Lu35be5812012-04-16 13:00:01 +02001094 }
H.J. Lu35be5812012-04-16 13:00:01 +02001095# endif
H.J. Lu085e4282012-04-17 11:05:04 -07001096 update_personality(tcp, currpers);
Denys Vlasenko523635f2012-02-25 02:44:25 +01001097#elif defined(IA64)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001098# define IA64_PSR_IS ((long)1 << 34)
Denys Vlasenko4bdb6bb2013-02-06 18:09:31 +01001099 long psr;
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001100 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001101 ia32 = (psr & IA64_PSR_IS) != 0;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001102 if (ia32) {
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001103 if (upeek(tcp, PT_R1, &scno) < 0)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001104 return -1;
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001105 } else {
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001106 if (upeek(tcp, PT_R15, &scno) < 0)
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001107 return -1;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001108 }
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001109#elif defined(AARCH64)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001110 switch (aarch64_io.iov_len) {
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001111 case sizeof(aarch64_regs):
1112 /* We are in 64-bit mode */
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001113 scno = aarch64_regs.regs[8];
1114 update_personality(tcp, 1);
1115 break;
1116 case sizeof(regs):
1117 /* We are in 32-bit mode */
Denys Vlasenko401374e2013-02-06 18:24:39 +01001118 scno = arm_regs.uregs[7];
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001119 update_personality(tcp, 0);
1120 break;
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001121 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001122#elif defined(ARM)
Roland McGrath0f87c492003-06-03 23:29:04 +00001123 /*
1124 * We only need to grab the syscall number on syscall entry.
1125 */
Denys Vlasenko401374e2013-02-06 18:24:39 +01001126 if (arm_regs.ARM_ip == 0) {
Roland McGrath0f87c492003-06-03 23:29:04 +00001127 /*
Denys Vlasenko401374e2013-02-06 18:24:39 +01001128 * Note: we only deal with 32-bit CPUs here
Roland McGrath0f87c492003-06-03 23:29:04 +00001129 */
Denys Vlasenko401374e2013-02-06 18:24:39 +01001130 if (arm_regs.ARM_cpsr & 0x20) {
Roland McGrath0f87c492003-06-03 23:29:04 +00001131 /*
1132 * Get the Thumb-mode system call number
1133 */
Denys Vlasenko401374e2013-02-06 18:24:39 +01001134 scno = arm_regs.ARM_r7;
Roland McGrath0f87c492003-06-03 23:29:04 +00001135 } else {
1136 /*
1137 * Get the ARM-mode system call number
1138 */
1139 errno = 0;
Denys Vlasenko401374e2013-02-06 18:24:39 +01001140 scno = ptrace(PTRACE_PEEKTEXT, tcp->pid, (void *)(arm_regs.ARM_pc - 4), NULL);
Roland McGrath0f87c492003-06-03 23:29:04 +00001141 if (errno)
1142 return -1;
1143
Roland McGrathf691bd22006-04-25 07:34:41 +00001144 /* 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) {
Denys Vlasenko401374e2013-02-06 18:24:39 +01001150 scno = arm_regs.ARM_r7;
Roland McGrathf691bd22006-04-25 07:34:41 +00001151 } else {
1152 if ((scno & 0x0ff00000) != 0x0f900000) {
1153 fprintf(stderr, "syscall: unknown syscall trap 0x%08lx\n",
1154 scno);
1155 return -1;
1156 }
Roland McGrath0f87c492003-06-03 23:29:04 +00001157
Roland McGrathf691bd22006-04-25 07:34:41 +00001158 /*
1159 * Fixup the syscall number
1160 */
1161 scno &= 0x000fffff;
1162 }
Roland McGrath0f87c492003-06-03 23:29:04 +00001163 }
Roland McGrath56703312008-05-20 01:35:55 +00001164 if (scno & 0x0f0000) {
1165 /*
1166 * Handle ARM specific syscall
1167 */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001168 update_personality(tcp, 1);
Roland McGrath56703312008-05-20 01:35:55 +00001169 scno &= 0x0000ffff;
1170 } else
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001171 update_personality(tcp, 0);
Roland McGrath0f87c492003-06-03 23:29:04 +00001172
Roland McGrath0f87c492003-06-03 23:29:04 +00001173 } else {
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001174 fprintf(stderr, "pid %d stray syscall entry\n", tcp->pid);
1175 tcp->flags |= TCB_INSYSCALL;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001176 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001177#elif defined(M68K)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001178 if (upeek(tcp, 4*PT_ORIG_D0, &scno) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001179 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001180#elif defined(LINUX_MIPSN32)
Roland McGrath542c2c62008-05-20 01:11:56 +00001181 unsigned long long regs[38];
1182
Denys Vlasenkob63256e2011-06-07 12:13:24 +02001183 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
Roland McGrath542c2c62008-05-20 01:11:56 +00001184 return -1;
1185 a3 = regs[REG_A3];
1186 r2 = regs[REG_V0];
1187
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001188 scno = r2;
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001189 if (!SCNO_IN_RANGE(scno)) {
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001190 if (a3 == 0 || a3 == -1) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001191 if (debug_flag)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001192 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
Roland McGrath542c2c62008-05-20 01:11:56 +00001193 return 0;
1194 }
Roland McGrath542c2c62008-05-20 01:11:56 +00001195 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001196#elif defined(MIPS)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001197 if (upeek(tcp, REG_A3, &a3) < 0)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001198 return -1;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001199 if (upeek(tcp, REG_V0, &scno) < 0)
1200 return -1;
Wichert Akkermanf90da011999-10-31 21:15:38 +00001201
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001202 if (!SCNO_IN_RANGE(scno)) {
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001203 if (a3 == 0 || a3 == -1) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001204 if (debug_flag)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001205 fprintf(stderr, "stray syscall exit: v0 = %ld\n", scno);
Roland McGrath542c2c62008-05-20 01:11:56 +00001206 return 0;
1207 }
Wichert Akkermanf90da011999-10-31 21:15:38 +00001208 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001209#elif defined(ALPHA)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001210 if (upeek(tcp, REG_A3, &alpha_a3) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001211 return -1;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001212 if (upeek(tcp, REG_R0, &scno) < 0)
1213 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001214
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001215 /*
1216 * Do some sanity checks to figure out if it's
1217 * really a syscall entry
1218 */
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001219 if (!SCNO_IN_RANGE(scno)) {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001220 if (alpha_a3 == 0 || alpha_a3 == -1) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001221 if (debug_flag)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001222 fprintf(stderr, "stray syscall exit: r0 = %ld\n", scno);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001223 return 0;
1224 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001225 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001226#elif defined(SPARC) || defined(SPARC64)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001227 /* Disassemble the syscall trap. */
1228 /* Retrieve the syscall trap instruction. */
Denys Vlasenko46455822013-02-05 17:02:59 +01001229 unsigned long trap;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001230 errno = 0;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001231# if defined(SPARC64)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001232 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.tpc, 0);
1233 trap >>= 32;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001234# else
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001235 trap = ptrace(PTRACE_PEEKTEXT, tcp->pid, (char *)regs.pc, 0);
Denys Vlasenko523635f2012-02-25 02:44:25 +01001236# endif
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001237 if (errno)
Wichert Akkermanc1652e22001-03-27 12:17:16 +00001238 return -1;
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001239
1240 /* Disassemble the trap to see what personality to use. */
1241 switch (trap) {
1242 case 0x91d02010:
1243 /* Linux/SPARC syscall trap. */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001244 update_personality(tcp, 0);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001245 break;
1246 case 0x91d0206d:
1247 /* Linux/SPARC64 syscall trap. */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001248 update_personality(tcp, 2);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001249 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) */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001256 update_personality(tcp, 1);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001257 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 */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00001264 update_personality(tcp, 1);
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001265 break;
1266 default:
Denys Vlasenko523635f2012-02-25 02:44:25 +01001267# if defined(SPARC64)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001268 fprintf(stderr, "syscall: unknown syscall trap %08lx %016lx\n", trap, regs.tpc);
Denys Vlasenko523635f2012-02-25 02:44:25 +01001269# else
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001270 fprintf(stderr, "syscall: unknown syscall trap %08lx %08lx\n", trap, regs.pc);
Denys Vlasenko523635f2012-02-25 02:44:25 +01001271# endif
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001272 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(&regs.u_regs[U_REG_O0], &regs.u_regs[U_REG_O1], 7*sizeof(regs.u_regs[0]));
1283 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001284#elif defined(HPPA)
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001285 if (upeek(tcp, PT_GR20, &scno) < 0)
1286 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001287#elif defined(SH)
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001288 /*
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;
Wichert Akkermanccef6372002-05-01 16:39:22 +00001293
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001294 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);
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001299 if (debug_flag)
Denys Vlasenko5ae2b7c2009-02-27 20:32:52 +00001300 fprintf(stderr,
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001301 "Detected glibc bug: bogus system call"
1302 " number = %ld, correcting to %ld\n",
1303 scno,
1304 correct_scno);
1305 scno = correct_scno;
1306 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001307#elif defined(SH64)
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001308 if (upeek(tcp, REG_SYSCALL, &scno) < 0)
Roland McGrathe1e584b2003-06-02 19:18:58 +00001309 return -1;
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001310 scno &= 0xFFFF;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001311#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001312 if (upeek(tcp, 4*PT_R9, &scno) < 0)
1313 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001314#elif defined(TILE)
Chris Metcalf0b99a8a2013-02-05 17:48:33 +01001315 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 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001334#elif defined(MICROBLAZE)
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001335 if (upeek(tcp, 0, &scno) < 0)
1336 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001337#endif
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001338
Denys Vlasenko523635f2012-02-25 02:44:25 +01001339#if defined(SH)
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001340 /* new syscall ABI returns result in R0 */
1341 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1342 return -1;
Roland McGrathf5a47772003-06-26 22:40:42 +00001343#elif defined(SH64)
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001344 /* ABI defines result returned in r9 */
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001345 if (upeek(tcp, REG_GENERAL(9), (long *)&sh64_r9) < 0)
Denys Vlasenkoadedb512008-12-30 18:47:55 +00001346 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001347#endif
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001348
Denys Vlasenko8cd1acd2011-08-24 16:52:57 +02001349 tcp->scno = scno;
Pavel Machek4dc3b142000-02-01 17:58:41 +00001350 return 1;
1351}
1352
Denys Vlasenko20c41fd2011-08-25 10:23:00 +02001353/* Called at each syscall entry.
Denys Vlasenkobc161ec2009-01-02 18:02:45 +00001354 * Returns:
Denys Vlasenko907735a2012-03-21 00:23:16 +01001355 * 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
Denys Vlasenkobc161ec2009-01-02 18:02:45 +00001358 * ("????" etc) and bail out.
1359 */
Roland McGratha4d48532005-06-08 20:45:28 +00001360static int
Denys Vlasenko8b4454c2011-08-25 10:40:14 +02001361syscall_fixup_on_sysenter(struct tcb *tcp)
Pavel Machek4dc3b142000-02-01 17:58:41 +00001362{
Denys Vlasenkob88f9612011-08-21 18:03:23 +02001363 /* A common case of "not a syscall entry" is post-execve SIGTRAP */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001364#if defined(I386)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001365 if (i386_regs.eax != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001366 if (debug_flag)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001367 fprintf(stderr, "not a syscall entry (eax = %ld)\n", i386_regs.eax);
1368 return 0;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001369 }
H.J. Lu35be5812012-04-16 13:00:01 +02001370#elif defined(X86_64) || defined(X32)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001371 {
1372 long rax = x86_64_regs.rax;
Denys Vlasenko18beb982011-08-24 16:59:23 +02001373 if (current_personality == 1)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001374 rax = (int)rax; /* sign extend from 32 bits */
1375 if (rax != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001376 if (debug_flag)
Denys Vlasenko18beb982011-08-24 16:59:23 +02001377 fprintf(stderr, "not a syscall entry (rax = %ld)\n", rax);
1378 return 0;
1379 }
Michal Ludvig0e035502002-09-23 15:41:01 +00001380 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001381#elif defined(S390) || defined(S390X)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001382 /* 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 */
Denys Vlasenko932fc7d2008-12-16 18:18:40 +00001386 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
Wichert Akkerman12f75d12000-02-14 16:23:40 +00001387 return -1;
Michal Ludvig882eda82002-11-11 12:50:47 +00001388 if (syscall_mode != -ENOSYS)
1389 syscall_mode = tcp->scno;
Denys Vlasenkoece98792011-08-25 10:25:35 +02001390 if (gpr2 != syscall_mode) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001391 if (debug_flag)
Denys Vlasenkob88f9612011-08-21 18:03:23 +02001392 fprintf(stderr, "not a syscall entry (gpr2 = %ld)\n", gpr2);
Wichert Akkerman12f75d12000-02-14 16:23:40 +00001393 return 0;
1394 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001395#elif defined(M68K)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001396 /* TODO? Eliminate upeek's in arches below like we did in x86 */
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001397 if (upeek(tcp, 4*PT_D0, &m68k_d0) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001398 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001399 if (m68k_d0 != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001400 if (debug_flag)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001401 fprintf(stderr, "not a syscall entry (d0 = %ld)\n", m68k_d0);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001402 return 0;
1403 }
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001404#elif defined(IA64)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001405 if (upeek(tcp, PT_R10, &ia64_r10) < 0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001406 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001407 if (upeek(tcp, PT_R8, &ia64_r8) < 0)
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001408 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001409 if (ia32 && ia64_r8 != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001410 if (debug_flag)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001411 fprintf(stderr, "not a syscall entry (r8 = %ld)\n", ia64_r8);
Wichert Akkerman7b3346b2001-10-09 23:47:38 +00001412 return 0;
1413 }
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001414#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001415 if (upeek(tcp, 4*PT_R10, &cris_r10) < 0)
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001416 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001417 if (cris_r10 != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001418 if (debug_flag)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001419 fprintf(stderr, "not a syscall entry (r10 = %ld)\n", cris_r10);
Denys Vlasenkoea0e6e82009-02-25 17:08:40 +00001420 return 0;
1421 }
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001422#elif defined(MICROBLAZE)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001423 if (upeek(tcp, 3 * 4, &microblaze_r3) < 0)
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001424 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001425 if (microblaze_r3 != -ENOSYS) {
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001426 if (debug_flag)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001427 fprintf(stderr, "not a syscall entry (r3 = %ld)\n", microblaze_r3);
Edgar E. Iglesias939caba2010-07-06 14:21:07 +02001428 return 0;
1429 }
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001430#endif
Pavel Machek4dc3b142000-02-01 17:58:41 +00001431 return 1;
1432}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001433
Denys Vlasenko146b9442012-03-18 22:10:48 +01001434static 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
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001486syscall_fixup_for_fork_exec(struct tcb *tcp)
Roland McGrathc1e45922008-05-27 23:18:29 +00001487{
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001488 /*
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
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001495 if (!SCNO_IN_RANGE(tcp->scno))
Denys Vlasenko146b9442012-03-18 22:10:48 +01001496 return;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001497
1498 func = sysent[tcp->scno].sys_func;
1499
1500 if ( sys_fork == func
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001501 || sys_vfork == func
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001502 || sys_clone == func
Denys Vlasenko146b9442012-03-18 22:10:48 +01001503 ) {
1504 internal_fork(tcp);
1505 return;
1506 }
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001507
Denys Vlasenko84703742012-02-25 02:38:52 +01001508#if defined(TCB_WAITEXECVE)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001509 if ( sys_execve == func
Denys Vlasenko84703742012-02-25 02:38:52 +01001510# if defined(SPARC) || defined(SPARC64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001511 || sys_execv == func
Denys Vlasenkoa7949742011-08-21 17:26:55 +02001512# endif
Denys Vlasenko146b9442012-03-18 22:10:48 +01001513 ) {
1514 internal_exec(tcp);
1515 return;
1516 }
Roland McGrathc1e45922008-05-27 23:18:29 +00001517#endif
Pavel Machek4dc3b142000-02-01 17:58:41 +00001518}
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001519
Denys Vlasenkobb6bb5c2012-03-20 17:10:35 +01001520/* Return -1 on error or 1 on success (never 0!) */
Roland McGratha4d48532005-06-08 20:45:28 +00001521static int
Denys Vlasenkobb6bb5c2012-03-20 17:10:35 +01001522get_syscall_args(struct tcb *tcp)
Pavel Machek4dc3b142000-02-01 17:58:41 +00001523{
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001524 int i, nargs;
1525
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001526 if (SCNO_IN_RANGE(tcp->scno))
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001527 nargs = tcp->u_nargs = sysent[tcp->scno].nargs;
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001528 else
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001529 nargs = tcp->u_nargs = MAX_ARGS;
1530
Denys Vlasenko523635f2012-02-25 02:44:25 +01001531#if defined(S390) || defined(S390X)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001532 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001533 if (upeek(tcp, i==0 ? PT_ORIGGPR2 : PT_GPR2 + i*sizeof(long), &tcp->u_arg[i]) < 0)
1534 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001535#elif defined(ALPHA)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001536 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001537 if (upeek(tcp, REG_A0+i, &tcp->u_arg[i]) < 0)
1538 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001539#elif defined(IA64)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001540 if (!ia32) {
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001541 unsigned long *out0, cfm, sof, sol;
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001542 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
Wichert Akkerman8b1b40c2000-02-03 21:58:30 +00001547
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001548 if (upeek(tcp, PT_RBS_END, &rbs_end) < 0)
1549 return -1;
1550 if (upeek(tcp, PT_CFM, (long *) &cfm) < 0)
Roland McGrath542c2c62008-05-20 01:11:56 +00001551 return -1;
1552
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001553 sof = (cfm >> 0) & 0x7f;
1554 sol = (cfm >> 7) & 0x7f;
1555 out0 = ia64_rse_skip_regs((unsigned long *) rbs_end, -sof + sol);
1556
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001557 for (i = 0; i < nargs; ++i) {
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001558 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 {
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001563 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 */};
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001569
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001570 for (i = 0; i < nargs; ++i) {
1571 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
1572 return -1;
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001573 /* truncate away IVE sign-extension */
1574 tcp->u_arg[i] &= 0xffffffff;
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001575 }
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001576 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001577#elif defined(LINUX_MIPSN32) || defined(LINUX_MIPSN64)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001578 /* N32 and N64 both use up to six registers. */
1579 unsigned long long regs[38];
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001580
1581 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
1582 return -1;
1583
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001584 for (i = 0; i < nargs; ++i) {
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001585 tcp->u_arg[i] = regs[REG_A0 + i];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001586# if defined(LINUX_MIPSN32)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001587 tcp->ext_arg[i] = regs[REG_A0 + i];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001588# endif
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001589 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001590#elif defined(MIPS)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001591 if (nargs > 4) {
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001592 long sp;
1593
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001594 if (upeek(tcp, REG_SP, &sp) < 0)
1595 return -1;
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001596 for (i = 0; i < 4; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001597 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
1598 return -1;
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001599 umoven(tcp, sp + 16, (nargs - 4) * sizeof(tcp->u_arg[0]),
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001600 (char *)(tcp->u_arg + 4));
1601 } else {
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001602 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001603 if (upeek(tcp, REG_A0 + i, &tcp->u_arg[i]) < 0)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001604 return -1;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001605 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001606#elif defined(POWERPC)
1607# ifndef PT_ORIG_R3
1608# define PT_ORIG_R3 34
1609# endif
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001610 for (i = 0; i < nargs; ++i) {
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001611 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;
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00001616 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001617#elif defined(SPARC) || defined(SPARC64)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001618 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001619 tcp->u_arg[i] = regs.u_regs[U_REG_O0 + i];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001620#elif defined(HPPA)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001621 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001622 if (upeek(tcp, PT_GR26-4*i, &tcp->u_arg[i]) < 0)
1623 return -1;
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001624#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 */
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001631 for (i = 0; i < nargs; ++i)
Denys Vlasenko401374e2013-02-06 18:24:39 +01001632 tcp->u_arg[i] = arm_regs.uregs[i];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001633#elif defined(AVR32)
Denys Vlasenkob5b25892011-08-30 19:04:54 +02001634 (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;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001642#elif defined(BFIN)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001643 static const int argreg[MAX_ARGS] = { PT_R0, PT_R1, PT_R2, PT_R3, PT_R4, PT_R5 };
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001644
Denys Vlasenko4b887a52011-08-23 13:32:38 +02001645 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001646 if (upeek(tcp, argreg[i], &tcp->u_arg[i]) < 0)
1647 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001648#elif defined(SH)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001649 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)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001652 };
1653
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001654 for (i = 0; i < nargs; ++i)
Denys Vlasenko0b6c73c2011-06-23 22:22:34 +02001655 if (upeek(tcp, syscall_regs[i], &tcp->u_arg[i]) < 0)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001656 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001657#elif defined(SH64)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001658 int i;
1659 /* Registers used by SH5 Linux system calls for parameters */
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001660 static const int syscall_regs[MAX_ARGS] = { 2, 3, 4, 5, 6, 7 };
Roland McGrathe1e584b2003-06-02 19:18:58 +00001661
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001662 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001663 if (upeek(tcp, REG_GENERAL(syscall_regs[i]), &tcp->u_arg[i]) < 0)
1664 return -1;
H.J. Lu35be5812012-04-16 13:00:01 +02001665#elif defined(X86_64) || defined(X32)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001666 (void)i;
1667 (void)nargs;
H.J. Lu35be5812012-04-16 13:00:01 +02001668 if (current_personality != 1) { /* x86-64 or x32 ABI */
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001669 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;
H.J. Lu35be5812012-04-16 13:00:01 +02001675# 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
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001683 } 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 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001692#elif defined(MICROBLAZE)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001693 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001694 if (upeek(tcp, (5 + i) * 4, &tcp->u_arg[i]) < 0)
1695 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001696#elif defined(CRISV10) || defined(CRISV32)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001697 static const int crisregs[MAX_ARGS] = {
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001698 4*PT_ORIG_R10, 4*PT_R11, 4*PT_R12,
Denys Vlasenko0b6c73c2011-06-23 22:22:34 +02001699 4*PT_R13 , 4*PT_MOF, 4*PT_SRP
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001700 };
Roland McGrathe1e584b2003-06-02 19:18:58 +00001701
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001702 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001703 if (upeek(tcp, crisregs[i], &tcp->u_arg[i]) < 0)
1704 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001705#elif defined(TILE)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001706 for (i = 0; i < nargs; ++i)
Chris Metcalf0b99a8a2013-02-05 17:48:33 +01001707 tcp->u_arg[i] = tile_regs.regs[i];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001708#elif defined(M68K)
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001709 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001710 if (upeek(tcp, (i < 5 ? i : i + 2)*4, &tcp->u_arg[i]) < 0)
1711 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001712#elif defined(I386)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001713 (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;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001721#else /* Other architecture (32bits specific) */
Dmitry V. Levin5f731c42011-08-23 16:24:20 +00001722 for (i = 0; i < nargs; ++i)
Denys Vlasenkof5d099c2011-06-23 22:10:54 +02001723 if (upeek(tcp, i*4, &tcp->u_arg[i]) < 0)
1724 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001725#endif
Pavel Machek4dc3b142000-02-01 17:58:41 +00001726 return 1;
1727}
1728
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00001729static int
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001730trace_syscall_entering(struct tcb *tcp)
1731{
1732 int res, scno_good;
1733
Denys Vlasenko2ce12ed2011-08-24 17:25:32 +02001734#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
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001742 scno_good = res = (get_regs_error ? -1 : get_scno(tcp));
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001743 if (res == 0)
1744 return res;
Denys Vlasenko907735a2012-03-21 00:23:16 +01001745 if (res == 1) {
Denys Vlasenko8b4454c2011-08-25 10:40:14 +02001746 res = syscall_fixup_on_sysenter(tcp);
Denys Vlasenko907735a2012-03-21 00:23:16 +01001747 if (res == 0)
1748 return res;
1749 if (res == 1)
1750 res = get_syscall_args(tcp);
1751 }
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001752
1753 if (res != 1) {
1754 printleader(tcp);
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001755 if (scno_good != 1)
Denys Vlasenkob7a6dae2012-03-20 16:48:35 +01001756 tprints("????" /* anti-trigraph gap */ "(");
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001757 else if (!SCNO_IN_RANGE(tcp->scno))
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001758 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
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001768#if defined(SYS_socket_subcall) || defined(SYS_ipc_subcall)
1769 while (SCNO_IN_RANGE(tcp->scno)) {
Denys Vlasenko523635f2012-02-25 02:44:25 +01001770# ifdef SYS_socket_subcall
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001771 if (sysent[tcp->scno].sys_func == sys_socketcall) {
Dmitry V. Levin648c22c2012-03-15 22:08:55 +00001772 decode_socket_subcall(tcp);
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001773 break;
1774 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001775# endif
1776# ifdef SYS_ipc_subcall
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001777 if (sysent[tcp->scno].sys_func == sys_ipc) {
Dmitry V. Levin648c22c2012-03-15 22:08:55 +00001778 decode_ipc_subcall(tcp);
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001779 break;
1780 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001781# endif
Dmitry V. Levinb5e88d42012-02-20 17:02:38 +00001782 break;
1783 }
1784#endif /* SYS_socket_subcall || SYS_ipc_subcall */
1785
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01001786 if (need_fork_exec_workarounds)
1787 syscall_fixup_for_fork_exec(tcp);
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001788
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001789 if ((SCNO_IN_RANGE(tcp->scno) &&
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001790 !(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);
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001804 if (!SCNO_IN_RANGE(tcp->scno))
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001805 tprintf("syscall_%lu(", tcp->scno);
1806 else
1807 tprintf("%s(", sysent[tcp->scno].sys_name);
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001808 if (!SCNO_IN_RANGE(tcp->scno) ||
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001809 ((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
Dmitry V. Levinb742d8c2012-09-17 22:40:12 +00001815 fflush(tcp->outf);
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001816 ret:
1817 tcp->flags |= TCB_INSYSCALL;
1818 /* Measure the entrance time as late as possible to avoid errors. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01001819 if (Tflag || cflag)
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02001820 gettimeofday(&tcp->etime, NULL);
1821 return res;
1822}
1823
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001824/* Returns:
Denys Vlasenko907735a2012-03-21 00:23:16 +01001825 * 1: ok, continue in trace_syscall_exiting().
1826 * -1: error, trace_syscall_exiting() should print error indicator
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001827 * ("????" etc) and bail out.
1828 */
1829static int
1830get_syscall_result(struct tcb *tcp)
1831{
Denys Vlasenko523635f2012-02-25 02:44:25 +01001832#if defined(S390) || defined(S390X)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001833 if (upeek(tcp, PT_GPR2, &gpr2) < 0)
1834 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001835#elif defined(POWERPC)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001836# define SO_MASK 0x10000000
1837 {
1838 long flags;
1839 if (upeek(tcp, sizeof(unsigned long)*PT_CCR, &flags) < 0)
1840 return -1;
Denys Vlasenko46dc8b22012-03-21 00:07:25 +01001841 if (upeek(tcp, sizeof(unsigned long)*PT_R3, &ppc_result) < 0)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001842 return -1;
1843 if (flags & SO_MASK)
Denys Vlasenko46dc8b22012-03-21 00:07:25 +01001844 ppc_result = -ppc_result;
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001845 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001846#elif defined(AVR32)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001847 /* already done by get_regs */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001848#elif defined(BFIN)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001849 if (upeek(tcp, PT_R0, &r0) < 0)
1850 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001851#elif defined(I386)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001852 /* already done by get_regs */
H.J. Lu35be5812012-04-16 13:00:01 +02001853#elif defined(X86_64) || defined(X32)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001854 /* already done by get_regs */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001855#elif defined(IA64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001856# define IA64_PSR_IS ((long)1 << 34)
Denys Vlasenko4bdb6bb2013-02-06 18:09:31 +01001857 long psr;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001858 if (upeek(tcp, PT_CR_IPSR, &psr) >= 0)
1859 ia32 = (psr & IA64_PSR_IS) != 0;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001860 if (upeek(tcp, PT_R8, &ia64_r8) < 0)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001861 return -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001862 if (upeek(tcp, PT_R10, &ia64_r10) < 0)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001863 return -1;
Steve McIntyred8d3bd32012-10-24 17:58:16 +01001864#elif defined(AARCH64)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001865/* 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));
Steve McIntyre890a5ca2012-11-10 11:24:48 +00001870#elif defined(ARM)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001871 /* already done by get_regs */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001872#elif defined(M68K)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001873 if (upeek(tcp, 4*PT_D0, &m68k_d0) < 0)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001874 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001875#elif defined(LINUX_MIPSN32)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001876 unsigned long long regs[38];
1877
1878 if (ptrace(PTRACE_GETREGS, tcp->pid, NULL, (long) &regs) < 0)
1879 return -1;
1880 a3 = regs[REG_A3];
1881 r2 = regs[REG_V0];
Denys Vlasenko523635f2012-02-25 02:44:25 +01001882#elif defined(MIPS)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001883 if (upeek(tcp, REG_A3, &a3) < 0)
1884 return -1;
1885 if (upeek(tcp, REG_V0, &r2) < 0)
1886 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001887#elif defined(ALPHA)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001888 if (upeek(tcp, REG_A3, &a3) < 0)
1889 return -1;
1890 if (upeek(tcp, REG_R0, &r0) < 0)
1891 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001892#elif defined(SPARC) || defined(SPARC64)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001893 /* already done by get_regs */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001894#elif defined(HPPA)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001895 if (upeek(tcp, PT_GR28, &hppa_r28) < 0)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001896 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001897#elif defined(SH)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001898 /* new syscall ABI returns result in R0 */
1899 if (upeek(tcp, 4*REG_REG0, (long *)&r0) < 0)
1900 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001901#elif defined(SH64)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001902 /* ABI defines result returned in r9 */
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001903 if (upeek(tcp, REG_GENERAL(9), (long *)&sh64_r9) < 0)
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01001904 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001905#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001906 if (upeek(tcp, 4*PT_R10, &cris_r10) < 0)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001907 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001908#elif defined(TILE)
Chris Metcalf0b99a8a2013-02-05 17:48:33 +01001909 /* already done by get_regs */
Denys Vlasenko523635f2012-02-25 02:44:25 +01001910#elif defined(MICROBLAZE)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001911 if (upeek(tcp, 3 * 4, &microblaze_r3) < 0)
Denys Vlasenkof20bff62011-08-25 10:31:24 +02001912 return -1;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001913#endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001914 return 1;
1915}
1916
Denys Vlasenkobb6bb5c2012-03-20 17:10:35 +01001917/* Called at each syscall exit */
1918static void
Denys Vlasenko20c41fd2011-08-25 10:23:00 +02001919syscall_fixup_on_sysexit(struct tcb *tcp)
1920{
Denys Vlasenko523635f2012-02-25 02:44:25 +01001921#if defined(S390) || defined(S390X)
Denys Vlasenko20c41fd2011-08-25 10:23:00 +02001922 if (syscall_mode != -ENOSYS)
1923 syscall_mode = tcp->scno;
Denys Vlasenkoece98792011-08-25 10:25:35 +02001924 if ((tcp->flags & TCB_WAITEXECVE)
Denys Vlasenko20c41fd2011-08-25 10:23:00 +02001925 && (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 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001933#endif
Denys Vlasenko20c41fd2011-08-25 10:23:00 +02001934}
1935
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001936/*
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;
Denys Vlasenko523635f2012-02-25 02:44:25 +01001944#if SUPPORTED_PERSONALITIES > 1
Denys Vlasenko9fd4f962012-03-19 09:36:42 +01001945 if (current_wordsize < sizeof(val)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001946 val = (unsigned int) val;
1947 max = (unsigned int) max;
1948 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001949#endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001950 return val > max;
1951}
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001952
Denys Vlasenko907735a2012-03-21 00:23:16 +01001953/* 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 */
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001958static int
1959get_error(struct tcb *tcp)
1960{
1961 int u_error = 0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001962 int check_errno = 1;
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02001963 if (SCNO_IN_RANGE(tcp->scno) &&
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001964 sysent[tcp->scno].sys_flags & SYSCALL_NEVER_FAILS) {
1965 check_errno = 0;
1966 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001967#if defined(S390) || defined(S390X)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001968 if (check_errno && is_negated_errno(gpr2)) {
1969 tcp->u_rval = -1;
1970 u_error = -gpr2;
1971 }
1972 else {
1973 tcp->u_rval = gpr2;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001974 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001975#elif defined(I386)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001976 if (check_errno && is_negated_errno(i386_regs.eax)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001977 tcp->u_rval = -1;
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001978 u_error = -i386_regs.eax;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001979 }
1980 else {
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001981 tcp->u_rval = i386_regs.eax;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001982 }
H.J. Lu35be5812012-04-16 13:00:01 +02001983#elif defined(X86_64) || defined(X32)
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001984 if (check_errno && is_negated_errno(x86_64_regs.rax)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001985 tcp->u_rval = -1;
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001986 u_error = -x86_64_regs.rax;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001987 }
1988 else {
Denys Vlasenkoeb0e3e82011-08-30 18:53:49 +02001989 tcp->u_rval = x86_64_regs.rax;
H.J. Lu35be5812012-04-16 13:00:01 +02001990# if defined(X32)
1991 tcp->u_lrval = x86_64_regs.rax;
1992# endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001993 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01001994#elif defined(IA64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001995 if (ia32) {
1996 int err;
1997
Denys Vlasenko89804ec2013-02-07 13:14:48 +01001998 err = (int)ia64_r8;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02001999 if (check_errno && is_negated_errno(err)) {
2000 tcp->u_rval = -1;
2001 u_error = -err;
2002 }
2003 else {
2004 tcp->u_rval = err;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002005 }
2006 } else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002007 if (check_errno && ia64_r10) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002008 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002009 u_error = ia64_r8;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002010 } else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002011 tcp->u_rval = ia64_r8;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002012 }
2013 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002014#elif defined(MIPS)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002015 if (check_errno && a3) {
2016 tcp->u_rval = -1;
2017 u_error = r2;
2018 } else {
2019 tcp->u_rval = r2;
H.J. Ludd0130b2012-04-16 12:16:45 +02002020# if defined(LINUX_MIPSN32)
2021 tcp->u_lrval = r2;
2022# endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002023 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002024#elif defined(POWERPC)
Denys Vlasenko46dc8b22012-03-21 00:07:25 +01002025 if (check_errno && is_negated_errno(ppc_result)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002026 tcp->u_rval = -1;
Denys Vlasenko46dc8b22012-03-21 00:07:25 +01002027 u_error = -ppc_result;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002028 }
2029 else {
Denys Vlasenko46dc8b22012-03-21 00:07:25 +01002030 tcp->u_rval = ppc_result;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002031 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002032#elif defined(M68K)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002033 if (check_errno && is_negated_errno(m68k_d0)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002034 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002035 u_error = -m68k_d0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002036 }
2037 else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002038 tcp->u_rval = m68k_d0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002039 }
Steve McIntyre890a5ca2012-11-10 11:24:48 +00002040#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 }
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002050 }
Steve McIntyre890a5ca2012-11-10 11:24:48 +00002051 else
2052# endif /* AARCH64 */
2053 {
Denys Vlasenko401374e2013-02-06 18:24:39 +01002054 if (check_errno && is_negated_errno(arm_regs.ARM_r0)) {
Steve McIntyre890a5ca2012-11-10 11:24:48 +00002055 tcp->u_rval = -1;
Denys Vlasenko401374e2013-02-06 18:24:39 +01002056 u_error = -arm_regs.ARM_r0;
Steve McIntyre890a5ca2012-11-10 11:24:48 +00002057 }
2058 else {
Denys Vlasenko401374e2013-02-06 18:24:39 +01002059 tcp->u_rval = arm_regs.ARM_r0;
Steve McIntyre890a5ca2012-11-10 11:24:48 +00002060 }
Steve McIntyred8d3bd32012-10-24 17:58:16 +01002061 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002062#elif defined(AVR32)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002063 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;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002069 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002070#elif defined(BFIN)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002071 if (check_errno && is_negated_errno(r0)) {
2072 tcp->u_rval = -1;
2073 u_error = -r0;
2074 } else {
2075 tcp->u_rval = r0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002076 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002077#elif defined(ALPHA)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002078 if (check_errno && alpha_a3) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002079 tcp->u_rval = -1;
2080 u_error = r0;
2081 }
2082 else {
2083 tcp->u_rval = r0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002084 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002085#elif defined(SPARC)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002086 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];
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002092 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002093#elif defined(SPARC64)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002094 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];
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002100 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002101#elif defined(HPPA)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002102 if (check_errno && is_negated_errno(hppa_r28)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002103 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002104 u_error = -hppa_r28;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002105 }
2106 else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002107 tcp->u_rval = hppa_r28;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002108 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002109#elif defined(SH)
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002110 if (check_errno && is_negated_errno(r0)) {
2111 tcp->u_rval = -1;
2112 u_error = -r0;
2113 }
2114 else {
2115 tcp->u_rval = r0;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002116 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002117#elif defined(SH64)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002118 if (check_errno && is_negated_errno(sh64_r9)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002119 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002120 u_error = -sh64_r9;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002121 }
2122 else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002123 tcp->u_rval = sh64_r9;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002124 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002125#elif defined(CRISV10) || defined(CRISV32)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002126 if (check_errno && cris_r10 && (unsigned) -cris_r10 < nerrnos) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002127 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002128 u_error = -cris_r10;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002129 }
2130 else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002131 tcp->u_rval = cris_r10;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002132 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002133#elif defined(TILE)
Chris Metcalf0b99a8a2013-02-05 17:48:33 +01002134 /*
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])) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002141 tcp->u_rval = -1;
Chris Metcalf0b99a8a2013-02-05 17:48:33 +01002142 u_error = -tile_regs.regs[0];
2143 } else {
2144 tcp->u_rval = tile_regs.regs[0];
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002145 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002146#elif defined(MICROBLAZE)
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002147 if (check_errno && is_negated_errno(microblaze_r3)) {
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002148 tcp->u_rval = -1;
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002149 u_error = -microblaze_r3;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002150 }
2151 else {
Denys Vlasenko89804ec2013-02-07 13:14:48 +01002152 tcp->u_rval = microblaze_r3;
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002153 }
Denys Vlasenko523635f2012-02-25 02:44:25 +01002154#endif
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002155 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;
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02002166 if (!SCNO_IN_RANGE(tcp->scno))
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002167 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 ||
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002173 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 ||
Denys Vlasenkoa6146922011-08-24 18:07:22 +02002183 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
Denys Vlasenkoed4f4f02011-08-22 11:54:06 +02002192static int
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002193trace_syscall_exiting(struct tcb *tcp)
Pavel Machek4dc3b142000-02-01 17:58:41 +00002194{
2195 int sys_res;
2196 struct timeval tv;
Denys Vlasenko1a5b5a72011-08-25 00:29:56 +02002197 int res;
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002198 long u_error;
Pavel Machek4dc3b142000-02-01 17:58:41 +00002199
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002200 /* Measure the exit time as early as possible to avoid errors. */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002201 if (Tflag || cflag)
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002202 gettimeofday(&tv, NULL);
Pavel Machek4dc3b142000-02-01 17:58:41 +00002203
Dmitry V. Levina5a839a2011-12-23 00:50:49 +00002204#if SUPPORTED_PERSONALITIES > 1
2205 update_personality(tcp, tcp->currpers);
2206#endif
Denys Vlasenkoce7d9532013-02-05 16:36:13 +01002207 res = (get_regs_error ? -1 : get_syscall_result(tcp));
Denys Vlasenkobb6bb5c2012-03-20 17:10:35 +01002208 if (res == 1) {
2209 syscall_fixup_on_sysexit(tcp); /* never fails */
Denys Vlasenko907735a2012-03-21 00:23:16 +01002210 res = get_error(tcp); /* returns 1 or -1 */
2211 if (res == 1) {
Denys Vlasenko8d4ca0c2013-02-06 13:18:42 +01002212 if (need_fork_exec_workarounds)
2213 syscall_fixup_for_fork_exec(tcp);
Denys Vlasenko907735a2012-03-21 00:23:16 +01002214 if (filtered(tcp)) {
2215 goto ret;
2216 }
2217 }
Pavel Machek4dc3b142000-02-01 17:58:41 +00002218 }
2219
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002220 if (cflag) {
2221 struct timeval t = tv;
Denys Vlasenkoc95a88f2011-08-21 17:47:40 +02002222 count_syscall(tcp, &t);
Denys Vlasenko7b609d52011-06-22 14:32:43 +02002223 if (cflag == CFLAG_ONLY_STATS) {
Denys Vlasenko3b738812011-08-22 02:06:35 +02002224 goto ret;
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002225 }
2226 }
2227
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002228 /* 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
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002247 if (res != 1) {
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002248 /* There was error in one of prior ptrace ops */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002249 tprints(") ");
Denys Vlasenko102ec492011-08-25 01:27:59 +02002250 tabto();
Denys Vlasenko000b6012012-01-28 01:25:03 +01002251 tprints("= ? <unavailable>\n");
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002252 line_ended();
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002253 tcp->flags &= ~TCB_INSYSCALL;
2254 return res;
2255 }
2256
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002257 sys_res = 0;
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02002258 if (!SCNO_IN_RANGE(tcp->scno)
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002259 || (qual_flags[tcp->scno] & QUAL_RAW)) {
Denys Vlasenkoa44f9692012-03-21 11:06:20 +01002260 /* sys_res = printargs(tcp); - but it's nop on sysexit */
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002261 } else {
Denys Vlasenko3b738812011-08-22 02:06:35 +02002262 /* 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 */
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002270 if (not_failing_only && tcp->u_error)
Denys Vlasenko3b738812011-08-22 02:06:35 +02002271 goto ret; /* ignore failed syscalls */
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002272 sys_res = (*sysent[tcp->scno].sys_func)(tcp);
2273 }
2274
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002275 tprints(") ");
Denys Vlasenko102ec492011-08-25 01:27:59 +02002276 tabto();
Denys Vlasenko3b738812011-08-22 02:06:35 +02002277 u_error = tcp->u_error;
Denys Vlasenkocb6f0562011-08-25 01:13:43 +02002278 if (!SCNO_IN_RANGE(tcp->scno) ||
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002279 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) {
Denys Vlasenkofe585652012-01-12 11:26:34 +01002287 /* 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 */
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002303 case ERESTARTSYS:
Denys Vlasenkofe585652012-01-12 11:26:34 +01002304 /* 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)");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002309 break;
2310 case ERESTARTNOINTR:
Denys Vlasenkofe585652012-01-12 11:26:34 +01002311 /* Rare. For example, fork() returns this if interrupted.
2312 * SA_RESTART is ignored (assumed set): the restart is unconditional.
2313 */
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002314 tprints("= ? ERESTARTNOINTR (To be restarted)");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002315 break;
2316 case ERESTARTNOHAND:
Denys Vlasenkofe585652012-01-12 11:26:34 +01002317 /* 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)");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002324 break;
2325 case ERESTART_RESTARTBLOCK:
Denys Vlasenkofe585652012-01-12 11:26:34 +01002326 /* 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)");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002338 break;
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002339 default:
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002340 if (u_error < 0)
Denys Vlasenkoa7949742011-08-21 17:26:55 +02002341 tprintf("= -1 E??? (errno %ld)", u_error);
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002342 else if (u_error < nerrnos)
Denys Vlasenkoa7949742011-08-21 17:26:55 +02002343 tprintf("= -1 %s (%s)", errnoent[u_error],
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002344 strerror(u_error));
2345 else
Denys Vlasenkoa7949742011-08-21 17:26:55 +02002346 tprintf("= -1 ERRNO_%ld (%s)", u_error,
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002347 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)
Denys Vlasenko60fe8c12011-09-01 10:00:28 +02002355 tprints("= ?");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002356 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;
H.J. Ludd0130b2012-04-16 12:16:45 +02002370#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
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002388 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 }
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +01002397 if (Tflag) {
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002398 tv_sub(&tv, &tv, &tcp->etime);
2399 tprintf(" <%ld.%06ld>",
2400 (long) tv.tv_sec, (long) tv.tv_usec);
2401 }
Denys Vlasenko000b6012012-01-28 01:25:03 +01002402 tprints("\n");
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002403 dumpio(tcp);
Denys Vlasenko7de265d2012-03-13 11:44:31 +01002404 line_ended();
2405
Denys Vlasenko3b738812011-08-22 02:06:35 +02002406 ret:
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002407 tcp->flags &= ~TCB_INSYSCALL;
2408 return 0;
2409}
2410
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00002411int
Dmitry V. Levin7d7c9632010-03-29 17:51:02 +00002412trace_syscall(struct tcb *tcp)
2413{
2414 return exiting(tcp) ?
2415 trace_syscall_exiting(tcp) : trace_syscall_entering(tcp);
2416}