blob: 34261f2e650e09f1ee0b2846bf00a62e1d6621dd [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>
Elliott Hughesdc75b012017-07-05 13:54:44 -07005 * Copyright (c) 2001-2017 The strace developers.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +00006 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000029 */
30
Eugene Syromyatnikov18907922016-08-07 06:44:19 +030031#ifndef STRACE_DEFS_H
32#define STRACE_DEFS_H
33
Roland McGrath795edb12005-02-02 04:44:57 +000034#ifdef HAVE_CONFIG_H
Denys Vlasenko329655a2012-02-25 02:42:32 +010035# include "config.h"
Roland McGrath795edb12005-02-02 04:44:57 +000036#endif
Dmitry V. Levin2690fad2013-05-07 08:03:41 +000037
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010038#include <features.h>
Dmitry V. Levin39888f92016-08-28 00:03:14 +000039#include <stdbool.h>
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010040#include <stdint.h>
41#include <inttypes.h>
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010042#include <sys/types.h>
Dmitry V. Levin7082acc2016-10-04 00:13:09 +000043#include <stddef.h>
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010044#include <unistd.h>
45#include <stdlib.h>
46#include <stdio.h>
Denys Vlasenko5198ed42013-03-06 23:44:23 +010047/* Open-coding isprint(ch) et al proved more efficient than calling
48 * generalized libc interface. We don't *want* to do non-ASCII anyway.
49 */
50/* #include <ctype.h> */
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010051#include <string.h>
Denys Vlasenkoa6d91de2012-03-16 12:02:22 +010052#include <errno.h>
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +010053#include <time.h>
54#include <sys/time.h>
Roland McGrathe6d3a292003-01-14 09:46:18 +000055
Elliott Hughes77c3ff82017-09-08 17:11:00 -070056#include "error_prints.h"
Dmitry V. Levinf32126b2015-12-31 14:19:41 +000057#include "gcc_compat.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070058#include "kernel_types.h"
Elliott Hughesdc75b012017-07-05 13:54:44 -070059#include "macros.h"
60#include "mpers_type.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070061#include "string_to_uint.h"
62#include "supported_personalities.h"
Elliott Hughesd35df492017-02-15 15:19:05 -080063#include "sysent.h"
Elliott Hughes77c3ff82017-09-08 17:11:00 -070064#include "xmalloc.h"
Elvira Khabirova09294222015-08-04 01:47:02 +030065
Denys Vlasenko29898142012-03-15 15:02:49 +010066#ifndef HAVE_STRERROR
67const char *strerror(int);
68#endif
Denys Vlasenko29898142012-03-15 15:02:49 +010069#ifndef HAVE_STPCPY
70/* Some libc have stpcpy, some don't. Sigh...
71 * Roll our private implementation...
72 */
73#undef stpcpy
74#define stpcpy strace_stpcpy
75extern char *stpcpy(char *dst, const char *src);
76#endif
77
Mike Frysingerd648f292013-05-01 23:35:30 -040078/* macros */
79#ifndef MAX
80# define MAX(a, b) (((a) > (b)) ? (a) : (b))
81#endif
82#ifndef MIN
83# define MIN(a, b) (((a) < (b)) ? (a) : (b))
84#endif
85#define CLAMP(val, min, max) MIN(MAX(min, val), max)
86
Denys Vlasenkoe4cc7c52012-03-23 11:29:01 +010087/* Glibc has an efficient macro for sigemptyset
88 * (it just does one or two assignments of 0 to internal vector of longs).
89 */
90#if defined(__GLIBC__) && defined(__sigemptyset) && !defined(sigemptyset)
91# define sigemptyset __sigemptyset
92#endif
93
Denys Vlasenkod9560c12011-08-19 17:41:28 +020094/* Configuration section */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000095#ifndef DEFAULT_STRLEN
Denys Vlasenko041b3ee2011-08-18 12:48:56 +020096/* default maximum # of bytes printed in `printstr', change with -s switch */
Denys Vlasenko329655a2012-02-25 02:42:32 +010097# define DEFAULT_STRLEN 32
Wichert Akkerman76baf7c1999-02-19 00:21:36 +000098#endif
99#ifndef DEFAULT_ACOLUMN
Denys Vlasenko329655a2012-02-25 02:42:32 +0100100# define DEFAULT_ACOLUMN 40 /* default alignment column for results */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000101#endif
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100102/*
103 * Maximum number of args to a syscall.
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200104 *
Denys Vlasenkoaa925db2012-02-25 15:19:02 +0100105 * Make sure that all entries in all syscallent.h files have nargs <= MAX_ARGS!
Dmitry V. Levin2690fad2013-05-07 08:03:41 +0000106 * linux/<ARCH>/syscallent*.h:
Elliott Hughesdc75b012017-07-05 13:54:44 -0700107 * all have nargs <= 6 except mips o32 which has nargs <= 7.
Denys Vlasenkod9560c12011-08-19 17:41:28 +0200108 */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000109#ifndef MAX_ARGS
Dmitry V. Levin2690fad2013-05-07 08:03:41 +0000110# ifdef LINUX_MIPSO32
111# define MAX_ARGS 7
112# else
113# define MAX_ARGS 6
114# endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000115#endif
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100116/* default sorting method for call profiling */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000117#ifndef DEFAULT_SORTBY
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100118# define DEFAULT_SORTBY "time"
John Hughes58265892001-10-18 15:13:53 +0000119#endif
Denys Vlasenkod27809c2013-02-12 12:50:10 +0100120/*
121 * Experimental code using PTRACE_SEIZE can be enabled here.
Denys Vlasenko9472a272013-02-12 11:43:46 +0100122 * This needs Linux kernel 3.4.x or later to work.
123 */
124#define USE_SEIZE 1
Denys Vlasenko05f32512013-02-26 12:00:34 +0100125/* To force NOMMU build, set to 1 */
Denys Vlasenko5c9d8f42013-02-19 15:30:12 +0100126#define NOMMU_SYSTEM 0
127
Denys Vlasenko47932212013-06-30 23:53:49 +0200128#ifndef ERESTARTSYS
129# define ERESTARTSYS 512
130#endif
131#ifndef ERESTARTNOINTR
132# define ERESTARTNOINTR 513
133#endif
134#ifndef ERESTARTNOHAND
135# define ERESTARTNOHAND 514
136#endif
137#ifndef ERESTART_RESTARTBLOCK
138# define ERESTART_RESTARTBLOCK 516
139#endif
140
Elliott Hughesd35df492017-02-15 15:19:05 -0800141#define PERSONALITY0_WORDSIZE SIZEOF_LONG
142#define PERSONALITY0_KLONGSIZE SIZEOF_KERNEL_LONG_T
Dmitry V. Levin90a65a42016-08-08 21:11:47 +0000143#define PERSONALITY0_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
144#define PERSONALITY0_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
Elvira Khabirova09294222015-08-04 01:47:02 +0300145
Dmitry V. Levinabfc0a62016-08-08 21:52:05 +0000146#if SUPPORTED_PERSONALITIES > 1
Elliott Hughesd35df492017-02-15 15:19:05 -0800147# define PERSONALITY1_WORDSIZE 4
148# define PERSONALITY1_KLONGSIZE PERSONALITY1_WORDSIZE
Dmitry V. Levinabfc0a62016-08-08 21:52:05 +0000149#endif
150
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700151#if SUPPORTED_PERSONALITIES > 2
152# define PERSONALITY2_WORDSIZE 4
153# define PERSONALITY2_KLONGSIZE PERSONALITY0_KLONGSIZE
154#endif
155
Dmitry V. Levin90a65a42016-08-08 21:11:47 +0000156#if SUPPORTED_PERSONALITIES > 1 && defined HAVE_M32_MPERS
157# define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
158# define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
159# define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
160# define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
161#else
Elvira Khabirova09294222015-08-04 01:47:02 +0300162# define PERSONALITY1_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
Elvira Khabirova09294222015-08-04 01:47:02 +0300163# define PERSONALITY1_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
Elvira Khabirova09294222015-08-04 01:47:02 +0300164# define PERSONALITY1_INCLUDE_FUNCS "empty.h"
165#endif
Dmitry V. Levin90a65a42016-08-08 21:11:47 +0000166
167#if SUPPORTED_PERSONALITIES > 2 && defined HAVE_MX32_MPERS
168# define PERSONALITY2_INCLUDE_FUNCS "mx32_funcs.h"
169# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "mx32_printer_decls.h"
170# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "mx32_printer_defs.h"
171# define MPERS_mx32_IOCTL_MACROS "ioctl_redefs2.h"
172#else
173# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
174# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
Elvira Khabirova09294222015-08-04 01:47:02 +0300175# define PERSONALITY2_INCLUDE_FUNCS "empty.h"
176#endif
177
Denys Vlasenkoa9fe13c2013-02-22 13:26:10 +0100178typedef struct ioctlent {
Denys Vlasenko74ec14f2013-02-21 16:13:47 +0100179 const char *symbol;
Dmitry V. Levinc7afb482015-01-19 18:44:21 +0000180 unsigned int code;
Denys Vlasenkoa9fe13c2013-02-22 13:26:10 +0100181} struct_ioctlent;
Denys Vlasenko74ec14f2013-02-21 16:13:47 +0100182
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700183#define INJECT_F_SIGNAL 1
184#define INJECT_F_RETVAL 2
185
186struct inject_data {
187 uint16_t flags;
Elliott Hughesd35df492017-02-15 15:19:05 -0800188 uint16_t signo;
189 int rval;
190};
191
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700192struct inject_opts {
193 uint16_t first;
194 uint16_t step;
195 struct inject_data data;
196};
197
Elliott Hughesd35df492017-02-15 15:19:05 -0800198#define MAX_ERRNO_VALUE 4095
Dmitry V. Levinb0c51132016-06-17 16:12:13 +0000199
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000200/* Trace Control Block */
201struct tcb {
Denys Vlasenkod9ec1412011-08-20 01:39:05 +0200202 int flags; /* See below for TCB_ values */
Denys Vlasenkofadbf662013-06-26 14:14:29 +0200203 int pid; /* If 0, this tcb is free */
Denys Vlasenko74ec14f2013-02-21 16:13:47 +0100204 int qual_flg; /* qual_flags[scno] or DEFAULT_QUAL_FLAGS + RAW */
Dmitry V. Levinba63d8a2016-10-03 11:48:55 +0000205 unsigned long u_error; /* Error code */
Elliott Hughesd35df492017-02-15 15:19:05 -0800206 kernel_ulong_t scno; /* System call number */
207 kernel_ulong_t u_arg[MAX_ARGS]; /* System call arguments */
208 kernel_long_t u_rval; /* Return value */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +0000209#if SUPPORTED_PERSONALITIES > 1
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000210 unsigned int currpers; /* Personality at the time of scno update */
Dmitry V. Levina5a839a2011-12-23 00:50:49 +0000211#endif
Dmitry V. Levin204c2bc2015-07-08 14:10:56 +0000212 int sys_func_rval; /* Syscall entry parser's return value */
Andreas Schwabccdff482009-10-27 16:27:13 +0100213 int curcol; /* Output column for this process */
Denys Vlasenko92d443c2011-08-25 00:25:08 +0200214 FILE *outf; /* Output file for this process */
Wichert Akkerman43a74822000-06-27 17:33:32 +0000215 const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */
Patrik Jakobssona1546a92015-08-24 14:42:47 +0200216 void *_priv_data; /* Private data for syscall decoding functions */
217 void (*_free_priv_data)(void *); /* Callback for freeing priv_data */
Denys Vlasenkoa9fe13c2013-02-22 13:26:10 +0100218 const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */
Denys Vlasenko8497b622015-03-21 17:51:52 +0100219 const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */
Elliott Hughesd35df492017-02-15 15:19:05 -0800220 struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000221 struct timeval stime; /* System time usage as of last process wait */
222 struct timeval dtime; /* Delta for system time usage */
223 struct timeval etime; /* Syscall entry time */
Luca Clementi327064b2013-07-23 00:11:35 -0700224
225#ifdef USE_LIBUNWIND
Elliott Hughesdc75b012017-07-05 13:54:44 -0700226 struct UPT_info *libunwind_ui;
227 struct mmap_cache_t *mmap_cache;
Luca Clementi327064b2013-07-23 00:11:35 -0700228 unsigned int mmap_cache_size;
Masatake YAMATO9bc65612014-04-16 15:33:07 +0900229 unsigned int mmap_cache_generation;
Elliott Hughesdc75b012017-07-05 13:54:44 -0700230 struct queue_t *queue;
Luca Clementi327064b2013-07-23 00:11:35 -0700231#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000232};
233
234/* TCB flags */
Denys Vlasenko68269aa2012-03-15 13:02:31 +0100235/* We have attached to this process, but did not see it stopping yet */
Denys Vlasenkofadbf662013-06-26 14:14:29 +0200236#define TCB_STARTUP 0x01
237#define TCB_IGNORE_ONE_SIGSTOP 0x02 /* Next SIGSTOP is to be ignored */
Denys Vlasenkob88f9612011-08-21 18:03:23 +0200238/*
239 * Are we in system call entry or in syscall exit?
240 *
Elliott Hughesdc75b012017-07-05 13:54:44 -0700241 * This bit is set in syscall_entering_finish() and cleared in
242 * syscall_exiting_finish().
243 * Other stops which are possible directly after syscall entry (death, ptrace
244 * event stop) are handled without calling syscall_{entering,exiting}_*().
Denys Vlasenkob88f9612011-08-21 18:03:23 +0200245 *
Elliott Hughesdc75b012017-07-05 13:54:44 -0700246 * Use entering(tcp) / exiting(tcp) to check this bit to make code more
247 * readable.
Denys Vlasenkob88f9612011-08-21 18:03:23 +0200248 */
Denys Vlasenkofadbf662013-06-26 14:14:29 +0200249#define TCB_INSYSCALL 0x04
250#define TCB_ATTACHED 0x08 /* We attached to it already */
Dmitry V. Levin23ce9e42015-02-08 13:05:53 +0000251#define TCB_REPRINT 0x10 /* We should reprint this syscall on exit */
252#define TCB_FILTERED 0x20 /* This system call has been filtered out */
Elliott Hughesd35df492017-02-15 15:19:05 -0800253#define TCB_TAMPERED 0x40 /* A syscall has been tampered with */
254#define TCB_HIDE_LOG 0x80 /* We should hide everything (until execve) */
255#define TCB_SKIP_DETACH_ON_FIRST_EXEC 0x100 /* -b execve should skip detach on first execve */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000256
257/* qualifier flags */
Denys Vlasenko74ec14f2013-02-21 16:13:47 +0100258#define QUAL_TRACE 0x001 /* this system call should be traced */
259#define QUAL_ABBREV 0x002 /* abbreviate the structures of this syscall */
260#define QUAL_VERBOSE 0x004 /* decode the structures of this syscall */
261#define QUAL_RAW 0x008 /* print all args in hex for this syscall */
Elliott Hughesd35df492017-02-15 15:19:05 -0800262#define QUAL_INJECT 0x010 /* tamper with this system call on purpose */
Denys Vlasenko74ec14f2013-02-21 16:13:47 +0100263
264#define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000265
266#define entering(tcp) (!((tcp)->flags & TCB_INSYSCALL))
267#define exiting(tcp) ((tcp)->flags & TCB_INSYSCALL)
268#define syserror(tcp) ((tcp)->u_error != 0)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700269#define traced(tcp) ((tcp)->qual_flg & QUAL_TRACE)
Denys Vlasenko40d63b92013-02-22 13:23:38 +0100270#define verbose(tcp) ((tcp)->qual_flg & QUAL_VERBOSE)
271#define abbrev(tcp) ((tcp)->qual_flg & QUAL_ABBREV)
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700272#define raw(tcp) ((tcp)->qual_flg & QUAL_RAW)
273#define inject(tcp) ((tcp)->qual_flg & QUAL_INJECT)
Grant Edwards8a082772011-04-07 20:25:40 +0000274#define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
Elliott Hughesd35df492017-02-15 15:19:05 -0800275#define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG)
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000276
Dmitry V. Levin0e097042016-04-26 00:08:16 +0000277#include "xlat.h"
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000278
Dmitry V. Levine96aee72016-06-25 13:47:54 +0000279extern const struct xlat addrfams[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700280extern const struct xlat arp_hardware_types[];
Dmitry V. Levin43b110b2014-12-06 03:53:16 +0000281extern const struct xlat at_flags[];
Elliott Hughes39bac052017-05-25 16:56:11 -0700282extern const struct xlat clocknames[];
Dmitry V. Levina367db82015-11-19 18:13:53 +0000283extern const struct xlat dirent_types[];
Elliott Hughesdc75b012017-07-05 13:54:44 -0700284extern const struct xlat ethernet_protocols[];
Dmitry V. Levin43c8a5d2016-05-27 00:49:08 +0000285extern const struct xlat evdev_abs[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700286extern const struct xlat iffflags[];
Elliott Hughesdc75b012017-07-05 13:54:44 -0700287extern const struct xlat inet_protocols[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700288extern const struct xlat ip_type_of_services[];
Dmitry V. Levin95cce4f2016-06-27 00:02:55 +0000289extern const struct xlat msg_flags[];
Elliott Hughes39bac052017-05-25 16:56:11 -0700290extern const struct xlat netlink_protocols[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700291extern const struct xlat nl_route_types[];
Denys Vlasenkof535b542009-01-13 18:30:55 +0000292extern const struct xlat open_access_modes[];
Dmitry V. Levin43b110b2014-12-06 03:53:16 +0000293extern const struct xlat open_mode_flags[];
Elvira Khabirovac01ad062015-08-19 05:06:26 +0300294extern const struct xlat resource_flags[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700295extern const struct xlat routing_scopes[];
296extern const struct xlat routing_table_ids[];
297extern const struct xlat routing_types[];
Elliott Hughes39bac052017-05-25 16:56:11 -0700298extern const struct xlat setns_types[];
Elliott Hughesd35df492017-02-15 15:19:05 -0800299extern const struct xlat sg_io_info[];
Dmitry V. Levin95cce4f2016-06-27 00:02:55 +0000300extern const struct xlat socketlayers[];
Elliott Hughesdc75b012017-07-05 13:54:44 -0700301extern const struct xlat socktypes[];
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700302extern const struct xlat tcp_state_flags[];
303extern const struct xlat tcp_states[];
Denys Vlasenko86738a22013-02-17 14:31:55 +0100304extern const struct xlat whence_codes[];
Denys Vlasenkof535b542009-01-13 18:30:55 +0000305
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000306/* Format of syscall return values */
307#define RVAL_DECIMAL 000 /* decimal format */
308#define RVAL_HEX 001 /* hex format */
309#define RVAL_OCTAL 002 /* octal format */
310#define RVAL_UDECIMAL 003 /* unsigned decimal format */
Zubin Mithra64aa1b12014-06-04 08:30:41 +0530311#define RVAL_FD 010 /* file descriptor */
Elliott Hughesd35df492017-02-15 15:19:05 -0800312#define RVAL_MASK 013 /* mask for these values */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000313
Zubin Mithra64aa1b12014-06-04 08:30:41 +0530314#define RVAL_STR 020 /* Print `auxstr' field after return val */
315#define RVAL_NONE 040 /* Print nothing */
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000316
Dmitry V. Levin204c2bc2015-07-08 14:10:56 +0000317#define RVAL_DECODED 0100 /* syscall decoding finished */
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700318#define RVAL_IOCTL_DECODED 0200 /* ioctl sub-parser successfully decoded
319 the argument */
Dmitry V. Levin204c2bc2015-07-08 14:10:56 +0000320
Gabriel Laskar8b6046a2015-12-04 01:07:33 +0100321#define IOCTL_NUMBER_UNKNOWN 0
322#define IOCTL_NUMBER_HANDLED 1
323#define IOCTL_NUMBER_STOP_LOOKUP 010
324
Elvira Khabirovac01ad062015-08-19 05:06:26 +0300325#define indirect_ipccall(tcp) (tcp->s_ent->sys_flags & TRACE_INDIRECT_SUBCALL)
326
Dmitry V. Levin80f7db12014-12-13 21:49:01 +0000327#if defined(ARM) || defined(AARCH64) \
328 || defined(I386) || defined(X32) || defined(X86_64) \
Mike Frysingercc07f662015-02-26 02:15:33 -0500329 || defined(IA64) \
Dmitry V. Levin80f7db12014-12-13 21:49:01 +0000330 || defined(BFIN) \
331 || defined(M68K) \
332 || defined(MICROBLAZE) \
Richard W.M. Jonesd8f67352016-08-19 14:16:41 +0100333 || defined(RISCV) \
Dmitry V. Levin80f7db12014-12-13 21:49:01 +0000334 || defined(S390) \
335 || defined(SH) || defined(SH64) \
336 || defined(SPARC) || defined(SPARC64) \
337 /**/
338# define NEED_UID16_PARSERS 1
339#else
340# define NEED_UID16_PARSERS 0
341#endif
342
Fabien Siron802cc282016-06-17 16:29:53 +0000343enum sock_proto {
344 SOCK_PROTO_UNKNOWN,
345 SOCK_PROTO_UNIX,
346 SOCK_PROTO_TCP,
347 SOCK_PROTO_UDP,
348 SOCK_PROTO_TCPv6,
349 SOCK_PROTO_UDPv6,
350 SOCK_PROTO_NETLINK
351};
352extern enum sock_proto get_proto_by_name(const char *);
353
Fabien Siron2a54d8b2016-06-22 13:27:03 +0000354enum iov_decode {
355 IOV_DECODE_ADDR,
Fabien Siron2850f742016-07-06 15:49:22 +0000356 IOV_DECODE_STR,
357 IOV_DECODE_NETLINK
Fabien Siron2a54d8b2016-06-22 13:27:03 +0000358};
359
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +0000360typedef enum {
361 CFLAG_NONE = 0,
362 CFLAG_ONLY_STATS,
363 CFLAG_BOTH
364} cflag_t;
Dmitry V. Levine3a7ef52010-03-28 19:24:54 +0000365extern cflag_t cflag;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100366extern bool debug_flag;
367extern bool Tflag;
Anton Blancharda34dead2013-07-12 12:22:06 +0200368extern bool iflag;
Mark Hillse53bf232014-05-28 17:52:40 +0100369extern bool count_wallclock;
Daniel P. Berrange01997cf2013-05-13 11:30:55 +0100370extern unsigned int qflag;
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100371extern bool not_failing_only;
Dmitry V. Levin45e7b182014-08-08 23:38:26 +0000372extern unsigned int show_fd_path;
Denys Vlasenko38cfe7c2013-03-05 16:01:53 +0100373/* are we filtering traces based on paths? */
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700374extern struct path_set {
375 const char **paths_selected;
376 unsigned int num_selected;
377} global_path_set;
378#define tracing_paths (global_path_set.num_selected != 0)
Denys Vlasenkoeec8d5d2013-02-14 03:29:48 +0100379extern unsigned xflag;
380extern unsigned followfork;
Luca Clementi327064b2013-07-23 00:11:35 -0700381#ifdef USE_LIBUNWIND
382/* if this is true do the stack trace for every system call */
383extern bool stack_trace_enabled;
384#endif
Denys Vlasenkoeec8d5d2013-02-14 03:29:48 +0100385extern unsigned ptrace_setoptions;
386extern unsigned max_strlen;
387extern unsigned os_release;
388#undef KERNEL_VERSION
Elliott Hughesdc75b012017-07-05 13:54:44 -0700389#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
Denys Vlasenkoa50d2a82012-03-15 12:49:52 +0100390
Dmitry V. Levinbf2698a2016-07-03 22:15:45 +0000391extern int read_int_from_file(const char *, int *);
392
Dmitry V. Levin30145dd2010-09-06 22:08:24 +0000393extern void set_sortby(const char *);
Andreas Schwabe5355de2009-10-27 16:56:43 +0100394extern void set_overhead(int);
Denys Vlasenko5a2483b2013-07-01 12:49:14 +0200395extern void print_pc(struct tcb *);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700396
397extern int syscall_entering_decode(struct tcb *);
398extern int syscall_entering_trace(struct tcb *, unsigned int *);
399extern void syscall_entering_finish(struct tcb *, int);
400
401extern int syscall_exiting_decode(struct tcb *, struct timeval *);
402extern int syscall_exiting_trace(struct tcb *, struct timeval, int);
403extern void syscall_exiting_finish(struct tcb *);
404
Dmitry V. Levinac5133d2014-05-29 18:10:00 +0000405extern void count_syscall(struct tcb *, const struct timeval *);
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100406extern void call_summary(FILE *);
407
Dmitry V. Levin9a176c92015-02-13 21:56:50 +0000408extern void clear_regs(void);
Elliott Hughes39bac052017-05-25 16:56:11 -0700409extern int get_scno(struct tcb *);
410extern kernel_ulong_t get_rt_sigframe_addr(struct tcb *);
411
Elliott Hughesd35df492017-02-15 15:19:05 -0800412/**
413 * Convert syscall number to syscall name.
414 *
415 * @param scno Syscall number.
416 * @return String literal corresponding to the syscall number in case latter
417 * is valid; NULL otherwise.
418 */
419extern const char *syscall_name(kernel_ulong_t scno);
Eugene Syromyatnikov6fdb1042016-09-29 15:56:27 +0300420extern const char *err_name(unsigned long err);
Dmitry V. Levin9a176c92015-02-13 21:56:50 +0000421
Dmitry V. Levin9af94a22015-09-18 01:54:59 +0000422extern bool is_erestart(struct tcb *);
Dmitry V. Levin3858b932015-09-18 01:54:59 +0000423extern void temporarily_clear_syserror(struct tcb *);
424extern void restore_cleared_syserror(struct tcb *);
425
Patrik Jakobssona1546a92015-08-24 14:42:47 +0200426extern void *get_tcb_priv_data(const struct tcb *);
427extern int set_tcb_priv_data(struct tcb *, void *priv_data,
428 void (*free_priv_data)(void *));
429extern void free_tcb_priv_data(struct tcb *);
430
431static inline unsigned long get_tcb_priv_ulong(const struct tcb *tcp)
432{
433 return (unsigned long) get_tcb_priv_data(tcp);
434}
435
436static inline int set_tcb_priv_ulong(struct tcb *tcp, unsigned long val)
437{
438 return set_tcb_priv_data(tcp, (void *) val, 0);
439}
440
Elliott Hughesd35df492017-02-15 15:19:05 -0800441extern int
Elliott Hughesdc75b012017-07-05 13:54:44 -0700442umoven(struct tcb *, kernel_ulong_t addr, unsigned int len, void *laddr);
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100443#define umove(pid, addr, objp) \
Denys Vlasenko7e69ed92015-03-21 19:50:53 +0100444 umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
Elliott Hughesd35df492017-02-15 15:19:05 -0800445
446extern int
Elliott Hughesdc75b012017-07-05 13:54:44 -0700447umoven_or_printaddr(struct tcb *, kernel_ulong_t addr,
Elliott Hughesd35df492017-02-15 15:19:05 -0800448 unsigned int len, void *laddr);
Dmitry V. Levin332a3262015-07-05 22:09:29 +0000449#define umove_or_printaddr(pid, addr, objp) \
450 umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
Elliott Hughesd35df492017-02-15 15:19:05 -0800451
452extern int
Elliott Hughesdc75b012017-07-05 13:54:44 -0700453umoven_or_printaddr_ignore_syserror(struct tcb *, kernel_ulong_t addr,
Elliott Hughesd35df492017-02-15 15:19:05 -0800454 unsigned int len, void *laddr);
455
456extern int
Elliott Hughesdc75b012017-07-05 13:54:44 -0700457umovestr(struct tcb *, kernel_ulong_t addr, unsigned int len, char *laddr);
Elliott Hughesd35df492017-02-15 15:19:05 -0800458
459extern int upeek(int pid, unsigned long, kernel_ulong_t *);
460extern int upoke(int pid, unsigned long, kernel_ulong_t);
Dmitry V. Levin78ed3f32015-03-23 00:04:27 +0000461
Dmitry V. Levin72e4f7a2016-05-06 23:26:43 +0000462extern bool
Elliott Hughesdc75b012017-07-05 13:54:44 -0700463print_array(struct tcb *,
Elliott Hughesd35df492017-02-15 15:19:05 -0800464 kernel_ulong_t start_addr,
465 size_t nmemb,
466 void *elem_buf,
467 size_t elem_size,
468 int (*umoven_func)(struct tcb *,
469 kernel_ulong_t,
Dmitry V. Levin72e4f7a2016-05-06 23:26:43 +0000470 unsigned int,
471 void *),
Elliott Hughesd35df492017-02-15 15:19:05 -0800472 bool (*print_func)(struct tcb *,
Dmitry V. Levin72e4f7a2016-05-06 23:26:43 +0000473 void *elem_buf,
474 size_t elem_size,
475 void *opaque_data),
Elliott Hughesd35df492017-02-15 15:19:05 -0800476 void *opaque_data);
Dmitry V. Levin72e4f7a2016-05-06 23:26:43 +0000477
Dmitry V. Levin8e8d7d22015-03-23 23:14:08 +0000478#if defined ALPHA || defined IA64 || defined MIPS \
479 || defined SH || defined SPARC || defined SPARC64
Dmitry V. Levin78ed3f32015-03-23 00:04:27 +0000480# define HAVE_GETRVAL2
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100481extern long getrval2(struct tcb *);
Dmitry V. Levin78ed3f32015-03-23 00:04:27 +0000482#else
483# undef HAVE_GETRVAL2
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100484#endif
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100485
Dmitry V. Levin3ed5d022014-09-10 13:46:04 +0000486extern const char *signame(const int);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700487extern void pathtrace_select_set(const char *, struct path_set *);
488extern bool pathtrace_match_set(struct tcb *, struct path_set *);
489#define pathtrace_select(tcp) \
490 pathtrace_select_set(tcp, &global_path_set)
491#define pathtrace_match(tcp) \
492 pathtrace_match_set(tcp, &global_path_set)
Denys Vlasenko61ad0a42013-03-06 18:24:34 +0100493extern int getfdpath(struct tcb *, int, char *, unsigned);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700494extern unsigned long getfdinode(struct tcb *, int);
Fabien Siron2850f742016-07-06 15:49:22 +0000495extern enum sock_proto getfdproto(struct tcb *, int);
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100496
Dmitry V. Levinc0db59b2016-05-14 21:55:35 +0000497extern const char *xlookup(const struct xlat *, const uint64_t);
Dmitry V. Levin43242e62016-04-28 18:37:54 +0000498extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100499
Elliott Hughesdc75b012017-07-05 13:54:44 -0700500struct dyxlat;
501struct dyxlat *dyxlat_alloc(size_t nmemb);
502void dyxlat_free(struct dyxlat *);
503const struct xlat *dyxlat_get(const struct dyxlat *);
504void dyxlat_add_pair(struct dyxlat *, uint64_t val, const char *str, size_t len);
505
506const struct xlat *genl_families_xlat(void);
507
Dmitry V. Levinea1fea62015-03-31 19:45:08 +0000508extern unsigned long get_pagesize(void);
Denys Vlasenkob338f2d2013-11-09 20:40:31 +0100509extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
Dmitry V. Levinccee1692012-03-25 21:49:48 +0000510
Elliott Hughesdc75b012017-07-05 13:54:44 -0700511/*
512 * Returns STR if it does not start with PREFIX,
513 * or a pointer to the first char in STR after PREFIX.
514 * The length of PREFIX is specified by PREFIX_LEN.
515 */
516static inline const char *
517str_strip_prefix_len(const char *str, const char *prefix, size_t prefix_len)
518{
519 return strncmp(str, prefix, prefix_len) ? str : str + prefix_len;
520}
521
522#define STR_STRIP_PREFIX(str, prefix) \
523 str_strip_prefix_len((str), (prefix), sizeof(prefix) - 1)
524
525#define QUOTE_0_TERMINATED 0x01
526#define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02
527#define QUOTE_OMIT_TRAILING_0 0x08
528#define QUOTE_FORCE_HEX 0x10
Dmitry V. Levin513e96e2015-01-26 01:17:08 +0000529
Dmitry V. Levin3c17d1b2016-02-01 23:14:59 +0000530extern int string_quote(const char *, char *, unsigned int, unsigned int);
Dmitry V. Levin513e96e2015-01-26 01:17:08 +0000531extern int print_quoted_string(const char *, unsigned int, unsigned int);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700532extern int print_quoted_cstring(const char *, unsigned int);
Dmitry V. Levin513e96e2015-01-26 01:17:08 +0000533
Denys Vlasenkoc9d0fc02013-02-17 22:41:33 +0100534/* a refers to the lower numbered u_arg,
535 * b refers to the higher numbered u_arg
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100536 */
Dmitry V. Levinda126fb2015-12-14 11:57:59 +0000537#ifdef WORDS_BIGENDIAN
Elliott Hughesdc75b012017-07-05 13:54:44 -0700538# define ULONG_LONG(a, b) \
Elliott Hughesd35df492017-02-15 15:19:05 -0800539 ((unsigned long long)(unsigned)(b) | ((unsigned long long)(a)<<32))
Dmitry V. Levinda126fb2015-12-14 11:57:59 +0000540#else
Elliott Hughesdc75b012017-07-05 13:54:44 -0700541# define ULONG_LONG(a, b) \
Elliott Hughesd35df492017-02-15 15:19:05 -0800542 ((unsigned long long)(unsigned)(a) | ((unsigned long long)(b)<<32))
Denys Vlasenkod63b0d52012-03-23 11:26:36 +0100543#endif
Dmitry V. Levin1ea64732015-01-10 00:08:58 +0000544extern int getllval(struct tcb *, unsigned long long *, int);
Dmitry V. Levinf523f102015-02-17 22:47:25 +0000545extern int printllval(struct tcb *, const char *, int)
Dmitry V. Levin5647cf82015-03-29 22:45:03 +0000546 ATTRIBUTE_FORMAT((printf, 2, 0));
Denys Vlasenkoc9d0fc02013-02-17 22:41:33 +0100547
Elliott Hughesd35df492017-02-15 15:19:05 -0800548extern void printaddr(kernel_ulong_t addr);
549extern int printxvals(const uint64_t, const char *, const struct xlat *, ...)
Dmitry V. Levinb0d23cc2016-04-01 00:52:01 +0000550 ATTRIBUTE_SENTINEL;
Elliott Hughesd35df492017-02-15 15:19:05 -0800551extern int printxval_searchn(const struct xlat *xlat, size_t xlat_size,
552 uint64_t val, const char *dflt);
553#define printxval_search(xlat__, val__, dflt__) \
554 printxval_searchn(xlat__, ARRAY_SIZE(xlat__), val__, dflt__)
Andreas Schwabe5355de2009-10-27 16:56:43 +0100555extern int printargs(struct tcb *);
Dmitry V. Levin1ab6e252016-02-14 16:26:37 +0000556extern int printargs_u(struct tcb *);
557extern int printargs_d(struct tcb *);
558
Dmitry V. Levinc9146eb2016-04-28 18:19:27 +0000559extern void addflags(const struct xlat *, uint64_t);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700560extern int printflags_ex(uint64_t, const char *, const struct xlat *, ...)
561 ATTRIBUTE_SENTINEL;
Dmitry V. Levin48110232016-05-15 14:26:03 +0000562extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
Elliott Hughes39bac052017-05-25 16:56:11 -0700563extern const char *sprinttime(long long sec);
564extern const char *sprinttime_nsec(long long sec, unsigned long long nsec);
565extern const char *sprinttime_usec(long long sec, unsigned long long usec);
Dmitry V. Levin8d374382016-08-03 14:05:39 +0000566extern void print_symbolic_mode_t(unsigned int);
567extern void print_numeric_umode_t(unsigned short);
568extern void print_numeric_long_umask(unsigned long);
Elliott Hughesd35df492017-02-15 15:19:05 -0800569extern void print_dev_t(unsigned long long dev);
Elliott Hughes39bac052017-05-25 16:56:11 -0700570extern void print_abnormal_hi(kernel_ulong_t);
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000571
Elliott Hughesd35df492017-02-15 15:19:05 -0800572extern void
573dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size);
Dmitry V. Levin2479ef02015-08-18 14:58:27 +0000574
Elliott Hughesd35df492017-02-15 15:19:05 -0800575extern void
576dumpiov_in_mmsghdr(struct tcb *, kernel_ulong_t addr);
577
578extern void
579dumpiov_upto(struct tcb *, int len, kernel_ulong_t addr, kernel_ulong_t data_size);
580
581extern void
582dumpstr(struct tcb *, kernel_ulong_t addr, int len);
583
584extern void
585printstr_ex(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
586 unsigned int user_style);
587
588extern void
589printpathn(struct tcb *, kernel_ulong_t addr, unsigned int n);
590
591extern void
592printpath(struct tcb *, kernel_ulong_t addr);
593
Dmitry V. Levin2950de32015-09-18 17:44:16 +0000594#define TIMESPEC_TEXT_BUFSIZE \
Elliott Hughes39bac052017-05-25 16:56:11 -0700595 (sizeof(long long) * 3 * 2 + sizeof("{tv_sec=-, tv_nsec=}"))
Dmitry V. Levin31382132011-03-04 05:08:02 +0300596extern void printfd(struct tcb *, int);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700597extern void print_sockaddr(const void *sa, int len);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700598extern bool
599print_inet_addr(int af, const void *addr, unsigned int len, const char *var_name);
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700600extern bool
601decode_inet_addr(struct tcb *, kernel_ulong_t addr,
602 unsigned int len, int family, const char *var_name);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700603extern const char *get_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode);
604extern bool print_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode);
Dmitry V. Levin99db95d2014-02-05 04:13:18 +0000605extern void print_dirfd(struct tcb *, int);
Elliott Hughesd35df492017-02-15 15:19:05 -0800606
607extern int
608decode_sockaddr(struct tcb *, kernel_ulong_t addr, int addrlen);
609
Dmitry V. Levin1da7c952014-12-13 18:24:13 +0000610extern void printuid(const char *, const unsigned int);
Elliott Hughesd35df492017-02-15 15:19:05 -0800611
612extern void
613print_sigset_addr_len(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len);
Elliott Hughes39bac052017-05-25 16:56:11 -0700614extern void
615print_sigset_addr(struct tcb *, kernel_ulong_t addr);
Elliott Hughesd35df492017-02-15 15:19:05 -0800616
Dmitry V. Levin74219ea2015-03-06 01:47:18 +0000617extern const char *sprintsigmask_n(const char *, const void *, unsigned int);
618#define tprintsigmask_addr(prefix, mask) \
619 tprints(sprintsigmask_n((prefix), (mask), sizeof(mask)))
Andreas Schwabe5355de2009-10-27 16:56:43 +0100620extern void printsignal(int);
Elliott Hughesd35df492017-02-15 15:19:05 -0800621
622extern void
623tprint_iov_upto(struct tcb *, kernel_ulong_t len, kernel_ulong_t addr,
624 enum iov_decode, kernel_ulong_t data_size);
625
626extern void
Elliott Hughesdc75b012017-07-05 13:54:44 -0700627decode_netlink(struct tcb *, int fd, kernel_ulong_t addr, kernel_ulong_t len);
Elliott Hughesd35df492017-02-15 15:19:05 -0800628
Dmitry V. Levindd9a5112016-04-28 23:40:37 +0000629extern void tprint_open_modes(unsigned int);
630extern const char *sprint_open_modes(unsigned int);
Elliott Hughesd35df492017-02-15 15:19:05 -0800631
632extern void
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700633decode_seccomp_fprog(struct tcb *, kernel_ulong_t addr);
Elliott Hughesd35df492017-02-15 15:19:05 -0800634
635extern void
636print_seccomp_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
Grant Edwards8a082772011-04-07 20:25:40 +0000637
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700638extern void
639decode_sock_fprog(struct tcb *, kernel_ulong_t addr);
640
641extern void
642print_sock_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
643
Dmitry V. Levina7c4ee42016-08-24 00:29:40 +0000644struct strace_stat;
Elliott Hughesdc75b012017-07-05 13:54:44 -0700645extern void print_struct_stat(struct tcb *, const struct strace_stat *const st);
Dmitry V. Levina7c4ee42016-08-24 00:29:40 +0000646
Dmitry V. Levin67c2f672016-04-26 00:21:26 +0000647struct strace_statfs;
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700648struct strace_keyctl_kdf_params;
Elliott Hughesd35df492017-02-15 15:19:05 -0800649
650extern void
651print_struct_statfs(struct tcb *, kernel_ulong_t addr);
652
653extern void
654print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
Dmitry V. Levin67c2f672016-04-26 00:21:26 +0000655
Dmitry V. Levin45ae9372016-06-23 17:38:18 +0000656extern void print_ifindex(unsigned int);
Dmitry V. Levin45ae9372016-06-23 17:38:18 +0000657
Elliott Hughesd35df492017-02-15 15:19:05 -0800658extern void qualify(const char *);
659extern unsigned int qual_flags(const unsigned int);
660
661#define DECL_IOCTL(name) \
662extern int \
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700663name ## _ioctl(struct tcb *, unsigned int request, kernel_ulong_t arg) \
664/* End of DECL_IOCTL definition. */
665
Elliott Hughesd35df492017-02-15 15:19:05 -0800666DECL_IOCTL(dm);
667DECL_IOCTL(file);
668DECL_IOCTL(fs_x);
Elliott Hughes39bac052017-05-25 16:56:11 -0700669DECL_IOCTL(nsfs);
Elliott Hughesd35df492017-02-15 15:19:05 -0800670DECL_IOCTL(ptp);
671DECL_IOCTL(scsi);
672DECL_IOCTL(term);
673DECL_IOCTL(ubi);
674DECL_IOCTL(uffdio);
675#undef DECL_IOCTL
676
677extern int decode_sg_io_v4(struct tcb *, const kernel_ulong_t arg);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000678
Elliott Hughesdc75b012017-07-05 13:54:44 -0700679struct nlmsghdr;
680
681typedef bool (*netlink_decoder_t)(struct tcb *, const struct nlmsghdr *,
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700682 kernel_ulong_t addr, unsigned int len);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700683
684#define DECL_NETLINK(name) \
685extern bool \
686decode_netlink_ ## name(struct tcb *, const struct nlmsghdr *, \
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700687 kernel_ulong_t addr, unsigned int len) \
688/* End of DECL_NETLINK definition. */
689
690DECL_NETLINK(crypto);
691DECL_NETLINK(route);
692DECL_NETLINK(selinux);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700693DECL_NETLINK(sock_diag);
694
Dmitry V. Levin447db452014-05-29 17:59:01 +0000695extern int tv_nz(const struct timeval *);
696extern int tv_cmp(const struct timeval *, const struct timeval *);
697extern double tv_float(const struct timeval *);
698extern void tv_add(struct timeval *, const struct timeval *, const struct timeval *);
699extern void tv_sub(struct timeval *, const struct timeval *, const struct timeval *);
700extern void tv_mul(struct timeval *, const struct timeval *, int);
701extern void tv_div(struct timeval *, const struct timeval *, int);
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000702
Luca Clementi327064b2013-07-23 00:11:35 -0700703#ifdef USE_LIBUNWIND
Masatake YAMATO61413922014-04-16 15:33:02 +0900704extern void unwind_init(void);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700705extern void unwind_tcb_init(struct tcb *);
706extern void unwind_tcb_fin(struct tcb *);
707extern void unwind_cache_invalidate(struct tcb *);
708extern void unwind_print_stacktrace(struct tcb *);
709extern void unwind_capture_stacktrace(struct tcb *);
Luca Clementi327064b2013-07-23 00:11:35 -0700710#endif
711
Eugene Syromyatnikovee70a1b2016-10-03 21:35:45 +0300712static inline void
Elliott Hughesd35df492017-02-15 15:19:05 -0800713printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len)
Eugene Syromyatnikovee70a1b2016-10-03 21:35:45 +0300714{
715 printstr_ex(tcp, addr, len, 0);
716}
717
Elliott Hughesd35df492017-02-15 15:19:05 -0800718static inline void
719printstr(struct tcb *tcp, kernel_ulong_t addr)
720{
721 printstr_ex(tcp, addr, -1, QUOTE_0_TERMINATED);
722}
723
Dmitry V. Levin00beed62016-04-28 18:55:18 +0000724static inline int
Elliott Hughesdc75b012017-07-05 13:54:44 -0700725printflags64(const struct xlat *x, uint64_t flags, const char *dflt)
726{
727 return printflags_ex(flags, dflt, x, NULL);
728}
729
730static inline int
Dmitry V. Levin00beed62016-04-28 18:55:18 +0000731printflags(const struct xlat *x, unsigned int flags, const char *dflt)
732{
733 return printflags64(x, flags, dflt);
734}
735
Dmitry V. Levin77ab8dd2016-05-16 22:44:50 +0000736static inline int
Dmitry V. Levin482bab02016-04-28 18:15:20 +0000737printxval64(const struct xlat *x, const uint64_t val, const char *dflt)
738{
Elliott Hughesd35df492017-02-15 15:19:05 -0800739 return printxvals(val, dflt, x, NULL);
Dmitry V. Levin482bab02016-04-28 18:15:20 +0000740}
741
Elliott Hughesd35df492017-02-15 15:19:05 -0800742static inline int
Dmitry V. Levin7d63aa52016-04-28 17:50:51 +0000743printxval(const struct xlat *x, const unsigned int val, const char *dflt)
744{
Elliott Hughesd35df492017-02-15 15:19:05 -0800745 return printxvals(val, dflt, x, NULL);
Dmitry V. Levin7d63aa52016-04-28 17:50:51 +0000746}
747
Dmitry V. Levin77ab8dd2016-05-16 22:44:50 +0000748static inline void
Elliott Hughesd35df492017-02-15 15:19:05 -0800749tprint_iov(struct tcb *tcp, kernel_ulong_t len, kernel_ulong_t addr,
750 enum iov_decode decode_iov)
Dmitry V. Levin77ab8dd2016-05-16 22:44:50 +0000751{
Elliott Hughesd35df492017-02-15 15:19:05 -0800752 tprint_iov_upto(tcp, len, addr, decode_iov, -1);
Dmitry V. Levin77ab8dd2016-05-16 22:44:50 +0000753}
754
Elliott Hughesd35df492017-02-15 15:19:05 -0800755#ifdef ALPHA
756typedef struct {
757 int tv_sec, tv_usec;
758} timeval32_t;
759
760extern void print_timeval32_t(const timeval32_t *);
761extern void printrusage32(struct tcb *, kernel_ulong_t);
Elliott Hughesdc75b012017-07-05 13:54:44 -0700762extern const char *sprint_timeval32(struct tcb *, kernel_ulong_t addr);
763extern void print_timeval32(struct tcb *, kernel_ulong_t addr);
764extern void print_timeval32_utimes(struct tcb *, kernel_ulong_t addr);
765extern void print_itimerval32(struct tcb *, kernel_ulong_t addr);
Elliott Hughesd35df492017-02-15 15:19:05 -0800766#endif
767
768#ifdef HAVE_STRUCT_USER_DESC
769extern void print_user_desc(struct tcb *, kernel_ulong_t addr);
770#endif
771
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100772/* Strace log generation machinery.
773 *
774 * printing_tcp: tcb which has incomplete line being printed right now.
775 * NULL if last line has been completed ('\n'-terminated).
776 * printleader(tcp) examines it, finishes incomplete line if needed,
777 * the sets it to tcp.
778 * line_ended() clears printing_tcp and resets ->curcol = 0.
779 * tcp->curcol == 0 check is also used to detect completeness
780 * of last line, since in -ff mode just checking printing_tcp for NULL
781 * is not enough.
782 *
783 * If you change this code, test log generation in both -f and -ff modes
784 * using:
785 * strace -oLOG -f[f] test/threaded_execve
786 * strace -oLOG -f[f] test/sigkill_rain
787 * strace -oLOG -f[f] -p "`pidof web_browser`"
788 */
789extern struct tcb *printing_tcp;
790extern void printleader(struct tcb *);
791extern void line_ended(void);
792extern void tabto(void);
Dmitry V. Levin5647cf82015-03-29 22:45:03 +0000793extern void tprintf(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100794extern void tprints(const char *str);
Elliott Hughes39bac052017-05-25 16:56:11 -0700795extern void tprintf_comment(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
796extern void tprints_comment(const char *str);
Denys Vlasenko7de265d2012-03-13 11:44:31 +0100797
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100798#if SUPPORTED_PERSONALITIES > 1
799extern void set_personality(int personality);
Denys Vlasenkoae8643e2013-02-15 14:55:14 +0100800extern unsigned current_personality;
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100801#else
802# define set_personality(personality) ((void)0)
803# define current_personality 0
Denys Vlasenkoae8643e2013-02-15 14:55:14 +0100804#endif
805
806#if SUPPORTED_PERSONALITIES == 1
807# define current_wordsize PERSONALITY0_WORDSIZE
Elliott Hughesd35df492017-02-15 15:19:05 -0800808# define current_klongsize PERSONALITY0_KLONGSIZE
Denys Vlasenkoae8643e2013-02-15 14:55:14 +0100809#else
810# if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_WORDSIZE == PERSONALITY1_WORDSIZE
811# define current_wordsize PERSONALITY0_WORDSIZE
812# else
813extern unsigned current_wordsize;
814# endif
Elliott Hughesd35df492017-02-15 15:19:05 -0800815# if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_KLONGSIZE == PERSONALITY1_KLONGSIZE
816# define current_klongsize PERSONALITY0_KLONGSIZE
817# else
818extern unsigned current_klongsize;
819# endif
Denys Vlasenko9fd4f962012-03-19 09:36:42 +0100820#endif
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000821
Elliott Hughesd35df492017-02-15 15:19:05 -0800822#define ANY_WORDSIZE_LESS_THAN_KERNEL_LONG \
823 (SIZEOF_KERNEL_LONG_T > 4 \
824 && (SIZEOF_LONG < SIZEOF_KERNEL_LONG_T || !defined(current_wordsize)))
825
826#define DECL_PRINTNUM(name) \
827extern bool \
828printnum_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700829 ATTRIBUTE_FORMAT((printf, 3, 0)) \
830/* End of DECL_PRINTNUM definition. */
831
Elliott Hughesd35df492017-02-15 15:19:05 -0800832DECL_PRINTNUM(short);
833DECL_PRINTNUM(int);
834DECL_PRINTNUM(int64);
835#undef DECL_PRINTNUM
836
837#define DECL_PRINTNUM_ADDR(name) \
838extern bool \
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700839printnum_addr_ ## name(struct tcb *, kernel_ulong_t addr) \
840/* End of DECL_PRINTNUM_ADDR definition. */
841
Elliott Hughesd35df492017-02-15 15:19:05 -0800842DECL_PRINTNUM_ADDR(int);
843DECL_PRINTNUM_ADDR(int64);
844#undef DECL_PRINTNUM_ADDR
845
846#ifndef current_wordsize
847extern bool
848printnum_long_int(struct tcb *, kernel_ulong_t addr,
849 const char *fmt_long, const char *fmt_int)
850 ATTRIBUTE_FORMAT((printf, 3, 0))
851 ATTRIBUTE_FORMAT((printf, 4, 0));
852extern bool printnum_addr_long_int(struct tcb *, kernel_ulong_t addr);
853# define printnum_slong(tcp, addr) \
854 printnum_long_int((tcp), (addr), "%" PRId64, "%d")
855# define printnum_ulong(tcp, addr) \
856 printnum_long_int((tcp), (addr), "%" PRIu64, "%u")
857# define printnum_ptr(tcp, addr) \
858 printnum_addr_long_int((tcp), (addr))
859#elif current_wordsize > 4
860# define printnum_slong(tcp, addr) \
861 printnum_int64((tcp), (addr), "%" PRId64)
862# define printnum_ulong(tcp, addr) \
863 printnum_int64((tcp), (addr), "%" PRIu64)
864# define printnum_ptr(tcp, addr) \
865 printnum_addr_int64((tcp), (addr))
866#else /* current_wordsize == 4 */
867# define printnum_slong(tcp, addr) \
868 printnum_int((tcp), (addr), "%d")
869# define printnum_ulong(tcp, addr) \
870 printnum_int((tcp), (addr), "%u")
871# define printnum_ptr(tcp, addr) \
872 printnum_addr_int((tcp), (addr))
Denys Vlasenkoe015d2d2013-02-15 14:58:52 +0100873#endif
874
Elliott Hughesd35df492017-02-15 15:19:05 -0800875#ifndef current_klongsize
876extern bool printnum_addr_klong_int(struct tcb *, kernel_ulong_t addr);
877# define printnum_kptr(tcp, addr) \
878 printnum_addr_klong_int((tcp), (addr))
879#elif current_klongsize > 4
880# define printnum_kptr(tcp, addr) \
881 printnum_addr_int64((tcp), (addr))
882#else /* current_klongsize == 4 */
883# define printnum_kptr(tcp, addr) \
884 printnum_addr_int((tcp), (addr))
885#endif
886
887#define DECL_PRINTPAIR(name) \
888extern bool \
889printpair_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
Elliott Hughes77c3ff82017-09-08 17:11:00 -0700890 ATTRIBUTE_FORMAT((printf, 3, 0)) \
891/* End of DECL_PRINTPAIR definition. */
892
Elliott Hughesd35df492017-02-15 15:19:05 -0800893DECL_PRINTPAIR(int);
894DECL_PRINTPAIR(int64);
895#undef DECL_PRINTPAIR
896
897static inline kernel_long_t
898truncate_klong_to_current_wordsize(const kernel_long_t v)
899{
900#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
901 if (current_wordsize < sizeof(v)) {
902 return (int) v;
903 } else
904#endif
905 {
906 return v;
907 }
908}
909
910static inline kernel_ulong_t
911truncate_kulong_to_current_wordsize(const kernel_ulong_t v)
912{
913#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
914 if (current_wordsize < sizeof(v)) {
915 return (unsigned int) v;
916 } else
917#endif
918 {
919 return v;
920 }
921}
922
923/*
924 * Cast a pointer or a pointer-sized integer to kernel_ulong_t.
925 */
926#define ptr_to_kulong(v) ((kernel_ulong_t) (unsigned long) (v))
927
Dmitry V. Levin84a979c2016-05-26 10:12:17 +0000928/*
Dmitry V. Levin031fc802016-08-23 00:24:10 +0000929 * Zero-extend a signed integer type to unsigned long long.
Dmitry V. Levin84a979c2016-05-26 10:12:17 +0000930 */
Dmitry V. Levin031fc802016-08-23 00:24:10 +0000931#define zero_extend_signed_to_ull(v) \
Dmitry V. Levin906dc4a2016-09-26 20:27:53 +0000932 (sizeof(v) == sizeof(char) ? (unsigned long long) (unsigned char) (v) : \
933 sizeof(v) == sizeof(short) ? (unsigned long long) (unsigned short) (v) : \
Dmitry V. Levinb2dd4632016-08-23 00:24:17 +0000934 sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
Dmitry V. Levin84a979c2016-05-26 10:12:17 +0000935 sizeof(v) == sizeof(long) ? (unsigned long long) (unsigned long) (v) : \
936 (unsigned long long) (v))
937
Dmitry V. Levinb685f902016-08-23 00:24:22 +0000938/*
939 * Sign-extend an unsigned integer type to long long.
940 */
941#define sign_extend_unsigned_to_ll(v) \
Dmitry V. Levin906dc4a2016-09-26 20:27:53 +0000942 (sizeof(v) == sizeof(char) ? (long long) (char) (v) : \
943 sizeof(v) == sizeof(short) ? (long long) (short) (v) : \
Dmitry V. Levinb685f902016-08-23 00:24:22 +0000944 sizeof(v) == sizeof(int) ? (long long) (int) (v) : \
945 sizeof(v) == sizeof(long) ? (long long) (long) (v) : \
946 (long long) (v))
947
Denys Vlasenko9cbc15b2013-02-22 13:37:36 +0100948extern const struct_sysent sysent0[];
949extern const char *const errnoent0[];
950extern const char *const signalent0[];
951extern const struct_ioctlent ioctlent0[];
Elvira Khabirova09294222015-08-04 01:47:02 +0300952
Denys Vlasenko9cbc15b2013-02-22 13:37:36 +0100953#if SUPPORTED_PERSONALITIES > 1
Denys Vlasenkoa9fe13c2013-02-22 13:26:10 +0100954extern const struct_sysent *sysent;
Denys Vlasenko39fca622011-08-20 02:12:33 +0200955extern const char *const *errnoent;
Roland McGrathee36ce12004-09-04 03:53:10 +0000956extern const char *const *signalent;
Denys Vlasenko9cbc15b2013-02-22 13:37:36 +0100957extern const struct_ioctlent *ioctlent;
958#else
959# define sysent sysent0
960# define errnoent errnoent0
961# define signalent signalent0
962# define ioctlent ioctlent0
963#endif
Elvira Khabirova09294222015-08-04 01:47:02 +0300964
Denys Vlasenko9cbc15b2013-02-22 13:37:36 +0100965extern unsigned nsyscalls;
966extern unsigned nerrnos;
Denys Vlasenkoafc64032011-08-23 13:29:01 +0200967extern unsigned nsignals;
Denys Vlasenko9cbc15b2013-02-22 13:37:36 +0100968extern unsigned nioctlents;
Elliott Hughesd35df492017-02-15 15:19:05 -0800969
970extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES];
971extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES];
972extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
Wichert Akkerman76baf7c1999-02-19 00:21:36 +0000973
Dmitry V. Levina8fce092016-05-21 22:53:06 +0000974#ifdef IN_MPERS_BOOTSTRAP
975/* Transform multi-line MPERS_PRINTER_DECL statements to one-liners. */
976# define MPERS_PRINTER_DECL(type, name, ...) MPERS_PRINTER_DECL(type, name, __VA_ARGS__)
977#else /* !IN_MPERS_BOOTSTRAP */
978# if SUPPORTED_PERSONALITIES > 1
979# include "printers.h"
980# else
981# include "native_printer_decls.h"
982# endif
983# define MPERS_PRINTER_DECL(type, name, ...) type MPERS_FUNC_NAME(name)(__VA_ARGS__)
984#endif /* !IN_MPERS_BOOTSTRAP */
Elvira Khabirova09294222015-08-04 01:47:02 +0300985
Elliott Hughesd35df492017-02-15 15:19:05 -0800986/* Checks that sysent[scno] is not out of range. */
987static inline bool
988scno_in_range(kernel_ulong_t scno)
989{
990 return scno < nsyscalls;
991}
Denys Vlasenkoc956ef02013-02-16 14:25:56 +0100992
Elliott Hughesd35df492017-02-15 15:19:05 -0800993/*
994 * Checks whether scno is not out of range,
995 * its corresponding sysent[scno].sys_func is non-NULL,
996 * and its sysent[scno].sys_flags has no TRACE_INDIRECT_SUBCALL flag set.
997 */
998static inline bool
999scno_is_valid(kernel_ulong_t scno)
1000{
1001 return scno_in_range(scno)
1002 && sysent[scno].sys_func
1003 && !(sysent[scno].sys_flags & TRACE_INDIRECT_SUBCALL);
1004}
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001005
Elvira Khabirova09294222015-08-04 01:47:02 +03001006#define MPERS_FUNC_NAME__(prefix, name) prefix ## name
1007#define MPERS_FUNC_NAME_(prefix, name) MPERS_FUNC_NAME__(prefix, name)
1008#define MPERS_FUNC_NAME(name) MPERS_FUNC_NAME_(MPERS_PREFIX, name)
1009
Szabolcs Nagy34683e32015-12-15 18:32:17 +00001010#define SYS_FUNC_NAME(syscall_name) MPERS_FUNC_NAME(syscall_name)
Dmitry V. Levina0bd3742015-04-07 01:36:50 +00001011
Szabolcs Nagy34683e32015-12-15 18:32:17 +00001012#define SYS_FUNC(syscall_name) int SYS_FUNC_NAME(sys_ ## syscall_name)(struct tcb *tcp)
Elvira Khabirova09294222015-08-04 01:47:02 +03001013
Dmitry V. Levin42ceb0f2016-08-07 22:02:46 +00001014#endif /* !STRACE_DEFS_H */