Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
3 : : * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
4 : : * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
5 : : * Copyright (C) 2001-2017 The strace developers.
6 : : * 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.
29 : : */
30 : :
31 : : #ifndef STRACE_DEFS_H
32 : : #define STRACE_DEFS_H
33 : :
34 : : #ifdef HAVE_CONFIG_H
35 : : # include "config.h"
36 : : #endif
37 : :
38 : : #include <features.h>
39 : : #include <stdbool.h>
40 : : #include <stdint.h>
41 : : #include <inttypes.h>
42 : : #include <sys/types.h>
43 : : #include <stddef.h>
44 : : #include <unistd.h>
45 : : #include <stdlib.h>
46 : : #include <stdio.h>
47 : : /* 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> */
51 : : #include <string.h>
52 : : #include <errno.h>
53 : : #include <time.h>
54 : : #include <sys/time.h>
55 : :
56 : : #include "kernel_types.h"
57 : : #include "mpers_type.h"
58 : : #include "gcc_compat.h"
59 : : #include "sysent.h"
60 : :
61 : : #ifndef HAVE_STRERROR
62 : : const char *strerror(int);
63 : : #endif
64 : : #ifndef HAVE_STPCPY
65 : : /* Some libc have stpcpy, some don't. Sigh...
66 : : * Roll our private implementation...
67 : : */
68 : : #undef stpcpy
69 : : #define stpcpy strace_stpcpy
70 : : extern char *stpcpy(char *dst, const char *src);
71 : : #endif
72 : :
73 : : #ifndef offsetofend
74 : : # define offsetofend(type, member) \
75 : : (offsetof(type, member) + sizeof(((type *)NULL)->member))
76 : : #endif
77 : :
78 : : #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]) + MUST_BE_ARRAY(a))
79 : :
80 : : /* macros */
81 : : #ifndef MAX
82 : : # define MAX(a, b) (((a) > (b)) ? (a) : (b))
83 : : #endif
84 : : #ifndef MIN
85 : : # define MIN(a, b) (((a) < (b)) ? (a) : (b))
86 : : #endif
87 : : #define CLAMP(val, min, max) MIN(MAX(min, val), max)
88 : :
89 : : /* Glibc has an efficient macro for sigemptyset
90 : : * (it just does one or two assignments of 0 to internal vector of longs).
91 : : */
92 : : #if defined(__GLIBC__) && defined(__sigemptyset) && !defined(sigemptyset)
93 : : # define sigemptyset __sigemptyset
94 : : #endif
95 : :
96 : : /* Configuration section */
97 : : #ifndef DEFAULT_STRLEN
98 : : /* default maximum # of bytes printed in `printstr', change with -s switch */
99 : : # define DEFAULT_STRLEN 32
100 : : #endif
101 : : #ifndef DEFAULT_ACOLUMN
102 : : # define DEFAULT_ACOLUMN 40 /* default alignment column for results */
103 : : #endif
104 : : /*
105 : : * Maximum number of args to a syscall.
106 : : *
107 : : * Make sure that all entries in all syscallent.h files have nargs <= MAX_ARGS!
108 : : * linux/<ARCH>/syscallent*.h:
109 : : * all have nargs <= 6 except mips o32 which has nargs <= 7.
110 : : */
111 : : #ifndef MAX_ARGS
112 : : # ifdef LINUX_MIPSO32
113 : : # define MAX_ARGS 7
114 : : # else
115 : : # define MAX_ARGS 6
116 : : # endif
117 : : #endif
118 : : /* default sorting method for call profiling */
119 : : #ifndef DEFAULT_SORTBY
120 : : # define DEFAULT_SORTBY "time"
121 : : #endif
122 : : /*
123 : : * Experimental code using PTRACE_SEIZE can be enabled here.
124 : : * This needs Linux kernel 3.4.x or later to work.
125 : : */
126 : : #define USE_SEIZE 1
127 : : /* To force NOMMU build, set to 1 */
128 : : #define NOMMU_SYSTEM 0
129 : :
130 : : #ifndef ERESTARTSYS
131 : : # define ERESTARTSYS 512
132 : : #endif
133 : : #ifndef ERESTARTNOINTR
134 : : # define ERESTARTNOINTR 513
135 : : #endif
136 : : #ifndef ERESTARTNOHAND
137 : : # define ERESTARTNOHAND 514
138 : : #endif
139 : : #ifndef ERESTART_RESTARTBLOCK
140 : : # define ERESTART_RESTARTBLOCK 516
141 : : #endif
142 : :
143 : : #if defined X86_64
144 : : # define SUPPORTED_PERSONALITIES 3
145 : : # define PERSONALITY2_WORDSIZE 4
146 : : # define PERSONALITY2_KLONGSIZE PERSONALITY0_KLONGSIZE
147 : : #elif defined AARCH64 \
148 : : || defined POWERPC64 \
149 : : || defined RISCV \
150 : : || defined SPARC64 \
151 : : || defined TILE \
152 : : || defined X32
153 : : # define SUPPORTED_PERSONALITIES 2
154 : : #else
155 : : # define SUPPORTED_PERSONALITIES 1
156 : : #endif
157 : :
158 : : #if defined TILE && defined __tilepro__
159 : : # define DEFAULT_PERSONALITY 1
160 : : #else
161 : : # define DEFAULT_PERSONALITY 0
162 : : #endif
163 : :
164 : : #define PERSONALITY0_WORDSIZE SIZEOF_LONG
165 : : #define PERSONALITY0_KLONGSIZE SIZEOF_KERNEL_LONG_T
166 : : #define PERSONALITY0_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
167 : : #define PERSONALITY0_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
168 : :
169 : : #if SUPPORTED_PERSONALITIES > 1
170 : : # define PERSONALITY1_WORDSIZE 4
171 : : # define PERSONALITY1_KLONGSIZE PERSONALITY1_WORDSIZE
172 : : #endif
173 : :
174 : : #if SUPPORTED_PERSONALITIES > 1 && defined HAVE_M32_MPERS
175 : : # define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
176 : : # define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
177 : : # define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
178 : : # define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
179 : : #else
180 : : # define PERSONALITY1_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
181 : : # define PERSONALITY1_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
182 : : # define PERSONALITY1_INCLUDE_FUNCS "empty.h"
183 : : #endif
184 : :
185 : : #if SUPPORTED_PERSONALITIES > 2 && defined HAVE_MX32_MPERS
186 : : # define PERSONALITY2_INCLUDE_FUNCS "mx32_funcs.h"
187 : : # define PERSONALITY2_INCLUDE_PRINTERS_DECLS "mx32_printer_decls.h"
188 : : # define PERSONALITY2_INCLUDE_PRINTERS_DEFS "mx32_printer_defs.h"
189 : : # define MPERS_mx32_IOCTL_MACROS "ioctl_redefs2.h"
190 : : #else
191 : : # define PERSONALITY2_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
192 : : # define PERSONALITY2_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
193 : : # define PERSONALITY2_INCLUDE_FUNCS "empty.h"
194 : : #endif
195 : :
196 : : typedef struct ioctlent {
197 : : const char *symbol;
198 : : unsigned int code;
199 : : } struct_ioctlent;
200 : :
201 : : struct inject_opts {
202 : : uint16_t first;
203 : : uint16_t step;
204 : : uint16_t signo;
205 : : int rval;
206 : : };
207 : :
208 : : #define MAX_ERRNO_VALUE 4095
209 : : #define INJECT_OPTS_RVAL_DEFAULT (-(MAX_ERRNO_VALUE + 1))
210 : :
211 : : /* Trace Control Block */
212 : : struct tcb {
213 : : int flags; /* See below for TCB_ values */
214 : : int pid; /* If 0, this tcb is free */
215 : : int qual_flg; /* qual_flags[scno] or DEFAULT_QUAL_FLAGS + RAW */
216 : : unsigned long u_error; /* Error code */
217 : : kernel_ulong_t scno; /* System call number */
218 : : kernel_ulong_t u_arg[MAX_ARGS]; /* System call arguments */
219 : : kernel_long_t u_rval; /* Return value */
220 : : #if SUPPORTED_PERSONALITIES > 1
221 : : unsigned int currpers; /* Personality at the time of scno update */
222 : : #endif
223 : : int sys_func_rval; /* Syscall entry parser's return value */
224 : : int curcol; /* Output column for this process */
225 : : FILE *outf; /* Output file for this process */
226 : : const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */
227 : : void *_priv_data; /* Private data for syscall decoding functions */
228 : : void (*_free_priv_data)(void *); /* Callback for freeing priv_data */
229 : : const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */
230 : : const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */
231 : : struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
232 : : struct timeval stime; /* System time usage as of last process wait */
233 : : struct timeval dtime; /* Delta for system time usage */
234 : : struct timeval etime; /* Syscall entry time */
235 : :
236 : : #ifdef USE_LIBUNWIND
237 : : struct UPT_info* libunwind_ui;
238 : : struct mmap_cache_t* mmap_cache;
239 : : unsigned int mmap_cache_size;
240 : : unsigned int mmap_cache_generation;
241 : : struct queue_t* queue;
242 : : #endif
243 : : };
244 : :
245 : : /* TCB flags */
246 : : /* We have attached to this process, but did not see it stopping yet */
247 : : #define TCB_STARTUP 0x01
248 : : #define TCB_IGNORE_ONE_SIGSTOP 0x02 /* Next SIGSTOP is to be ignored */
249 : : /*
250 : : * Are we in system call entry or in syscall exit?
251 : : *
252 : : * This bit is set after all syscall entry processing is done.
253 : : * Therefore, this bit will be set when next ptrace stop occurs,
254 : : * which should be syscall exit stop. Other stops which are possible
255 : : * directly after syscall entry (death, ptrace event stop)
256 : : * are simpler and handled without calling trace_syscall(), therefore
257 : : * the places where TCB_INSYSCALL can be set but we aren't in syscall stop
258 : : * are limited to trace(), this condition is never observed in trace_syscall()
259 : : * and below.
260 : : * The bit is cleared after all syscall exit processing is done.
261 : : *
262 : : * Use entering(tcp) / exiting(tcp) to check this bit to make code more readable.
263 : : */
264 : : #define TCB_INSYSCALL 0x04
265 : : #define TCB_ATTACHED 0x08 /* We attached to it already */
266 : : #define TCB_REPRINT 0x10 /* We should reprint this syscall on exit */
267 : : #define TCB_FILTERED 0x20 /* This system call has been filtered out */
268 : : #define TCB_TAMPERED 0x40 /* A syscall has been tampered with */
269 : : #define TCB_HIDE_LOG 0x80 /* We should hide everything (until execve) */
270 : : #define TCB_SKIP_DETACH_ON_FIRST_EXEC 0x100 /* -b execve should skip detach on first execve */
271 : :
272 : : /* qualifier flags */
273 : : #define QUAL_TRACE 0x001 /* this system call should be traced */
274 : : #define QUAL_ABBREV 0x002 /* abbreviate the structures of this syscall */
275 : : #define QUAL_VERBOSE 0x004 /* decode the structures of this syscall */
276 : : #define QUAL_RAW 0x008 /* print all args in hex for this syscall */
277 : : #define QUAL_INJECT 0x010 /* tamper with this system call on purpose */
278 : : #define QUAL_SIGNAL 0x100 /* report events with this signal */
279 : : #define QUAL_READ 0x200 /* dump data read from this file descriptor */
280 : : #define QUAL_WRITE 0x400 /* dump data written to this file descriptor */
281 : :
282 : : #define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
283 : :
284 : : #define entering(tcp) (!((tcp)->flags & TCB_INSYSCALL))
285 : : #define exiting(tcp) ((tcp)->flags & TCB_INSYSCALL)
286 : : #define syserror(tcp) ((tcp)->u_error != 0)
287 : : #define verbose(tcp) ((tcp)->qual_flg & QUAL_VERBOSE)
288 : : #define abbrev(tcp) ((tcp)->qual_flg & QUAL_ABBREV)
289 : : #define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
290 : : #define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG)
291 : :
292 : : #include "xlat.h"
293 : :
294 : : extern const struct xlat addrfams[];
295 : : extern const struct xlat at_flags[];
296 : : extern const struct xlat dirent_types[];
297 : : extern const struct xlat evdev_abs[];
298 : : extern const struct xlat msg_flags[];
299 : : extern const struct xlat open_access_modes[];
300 : : extern const struct xlat open_mode_flags[];
301 : : extern const struct xlat resource_flags[];
302 : : extern const struct xlat sg_io_info[];
303 : : extern const struct xlat socketlayers[];
304 : : extern const struct xlat whence_codes[];
305 : :
306 : : /* 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 */
311 : : #define RVAL_FD 010 /* file descriptor */
312 : : #define RVAL_MASK 013 /* mask for these values */
313 : :
314 : : #define RVAL_STR 020 /* Print `auxstr' field after return val */
315 : : #define RVAL_NONE 040 /* Print nothing */
316 : :
317 : : #define RVAL_DECODED 0100 /* syscall decoding finished */
318 : :
319 : : #define IOCTL_NUMBER_UNKNOWN 0
320 : : #define IOCTL_NUMBER_HANDLED 1
321 : : #define IOCTL_NUMBER_STOP_LOOKUP 010
322 : :
323 : : #define indirect_ipccall(tcp) (tcp->s_ent->sys_flags & TRACE_INDIRECT_SUBCALL)
324 : :
325 : : #if defined(ARM) || defined(AARCH64) \
326 : : || defined(I386) || defined(X32) || defined(X86_64) \
327 : : || defined(IA64) \
328 : : || defined(BFIN) \
329 : : || defined(M68K) \
330 : : || defined(MICROBLAZE) \
331 : : || defined(RISCV) \
332 : : || defined(S390) \
333 : : || defined(SH) || defined(SH64) \
334 : : || defined(SPARC) || defined(SPARC64) \
335 : : /**/
336 : : # define NEED_UID16_PARSERS 1
337 : : #else
338 : : # define NEED_UID16_PARSERS 0
339 : : #endif
340 : :
341 : : enum sock_proto {
342 : : SOCK_PROTO_UNKNOWN,
343 : : SOCK_PROTO_UNIX,
344 : : SOCK_PROTO_TCP,
345 : : SOCK_PROTO_UDP,
346 : : SOCK_PROTO_TCPv6,
347 : : SOCK_PROTO_UDPv6,
348 : : SOCK_PROTO_NETLINK
349 : : };
350 : : extern enum sock_proto get_proto_by_name(const char *);
351 : :
352 : : enum iov_decode {
353 : : IOV_DECODE_ADDR,
354 : : IOV_DECODE_STR,
355 : : IOV_DECODE_NETLINK
356 : : };
357 : :
358 : : typedef enum {
359 : : CFLAG_NONE = 0,
360 : : CFLAG_ONLY_STATS,
361 : : CFLAG_BOTH
362 : : } cflag_t;
363 : : extern cflag_t cflag;
364 : : extern bool debug_flag;
365 : : extern bool Tflag;
366 : : extern bool iflag;
367 : : extern bool count_wallclock;
368 : : extern unsigned int qflag;
369 : : extern bool not_failing_only;
370 : : extern unsigned int show_fd_path;
371 : : /* are we filtering traces based on paths? */
372 : : extern const char **paths_selected;
373 : : #define tracing_paths (paths_selected != NULL)
374 : : extern unsigned xflag;
375 : : extern unsigned followfork;
376 : : #ifdef USE_LIBUNWIND
377 : : /* if this is true do the stack trace for every system call */
378 : : extern bool stack_trace_enabled;
379 : : #endif
380 : : extern unsigned ptrace_setoptions;
381 : : extern unsigned max_strlen;
382 : : extern unsigned os_release;
383 : : #undef KERNEL_VERSION
384 : : #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
385 : :
386 : : void error_msg(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
387 : : void perror_msg(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
388 : : void error_msg_and_die(const char *fmt, ...)
389 : : ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
390 : : void error_msg_and_help(const char *fmt, ...)
391 : : ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
392 : : void perror_msg_and_die(const char *fmt, ...)
393 : : ATTRIBUTE_FORMAT((printf, 1, 2)) ATTRIBUTE_NORETURN;
394 : : void die_out_of_memory(void) ATTRIBUTE_NORETURN;
395 : :
396 : : void *xmalloc(size_t size) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1));
397 : : void *xcalloc(size_t nmemb, size_t size)
398 : : ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1, 2));
399 : : void *xreallocarray(void *ptr, size_t nmemb, size_t size)
400 : : ATTRIBUTE_ALLOC_SIZE((2, 3));
401 : : char *xstrdup(const char *str) ATTRIBUTE_MALLOC;
402 : :
403 : : extern int read_int_from_file(const char *, int *);
404 : :
405 : : extern void set_sortby(const char *);
406 : : extern void set_overhead(int);
407 : : extern void print_pc(struct tcb *);
408 : : extern int trace_syscall(struct tcb *, unsigned int *);
409 : : extern void count_syscall(struct tcb *, const struct timeval *);
410 : : extern void call_summary(FILE *);
411 : :
412 : : extern void clear_regs(void);
413 : : extern void get_regs(pid_t pid);
414 : : extern int get_scno(struct tcb *);
415 : : extern kernel_ulong_t get_rt_sigframe_addr(struct tcb *);
416 : :
417 : : /**
418 : : * Convert syscall number to syscall name.
419 : : *
420 : : * @param scno Syscall number.
421 : : * @return String literal corresponding to the syscall number in case latter
422 : : * is valid; NULL otherwise.
423 : : */
424 : : extern const char *syscall_name(kernel_ulong_t scno);
425 : : extern const char *err_name(unsigned long err);
426 : :
427 : : extern bool is_erestart(struct tcb *);
428 : : extern void temporarily_clear_syserror(struct tcb *);
429 : : extern void restore_cleared_syserror(struct tcb *);
430 : :
431 : : extern void *get_tcb_priv_data(const struct tcb *);
432 : : extern int set_tcb_priv_data(struct tcb *, void *priv_data,
433 : : void (*free_priv_data)(void *));
434 : : extern void free_tcb_priv_data(struct tcb *);
435 : :
436 : 2669 : static inline unsigned long get_tcb_priv_ulong(const struct tcb *tcp)
437 : : {
438 : 2669 : return (unsigned long) get_tcb_priv_data(tcp);
439 : : }
440 : :
441 : 2629 : static inline int set_tcb_priv_ulong(struct tcb *tcp, unsigned long val)
442 : : {
443 : 2629 : return set_tcb_priv_data(tcp, (void *) val, 0);
444 : : }
445 : :
446 : : extern int
447 : : umoven(struct tcb *tcp, kernel_ulong_t addr, unsigned int len, void *laddr);
448 : : #define umove(pid, addr, objp) \
449 : : umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
450 : :
451 : : extern int
452 : : umoven_or_printaddr(struct tcb *tcp, kernel_ulong_t addr,
453 : : unsigned int len, void *laddr);
454 : : #define umove_or_printaddr(pid, addr, objp) \
455 : : umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
456 : :
457 : : extern int
458 : : umoven_or_printaddr_ignore_syserror(struct tcb *tcp, kernel_ulong_t addr,
459 : : unsigned int len, void *laddr);
460 : :
461 : : extern int
462 : : umovestr(struct tcb *tcp, kernel_ulong_t addr, unsigned int len, char *laddr);
463 : :
464 : : extern int upeek(int pid, unsigned long, kernel_ulong_t *);
465 : : extern int upoke(int pid, unsigned long, kernel_ulong_t);
466 : :
467 : : extern bool
468 : : print_array(struct tcb *tcp,
469 : : kernel_ulong_t start_addr,
470 : : size_t nmemb,
471 : : void *elem_buf,
472 : : size_t elem_size,
473 : : int (*umoven_func)(struct tcb *,
474 : : kernel_ulong_t,
475 : : unsigned int,
476 : : void *),
477 : : bool (*print_func)(struct tcb *,
478 : : void *elem_buf,
479 : : size_t elem_size,
480 : : void *opaque_data),
481 : : void *opaque_data);
482 : :
483 : : #if defined ALPHA || defined IA64 || defined MIPS \
484 : : || defined SH || defined SPARC || defined SPARC64
485 : : # define HAVE_GETRVAL2
486 : : extern long getrval2(struct tcb *);
487 : : #else
488 : : # undef HAVE_GETRVAL2
489 : : #endif
490 : :
491 : : extern const char *signame(const int);
492 : : extern void pathtrace_select(const char *);
493 : : extern int pathtrace_match(struct tcb *);
494 : : extern int getfdpath(struct tcb *, int, char *, unsigned);
495 : : extern enum sock_proto getfdproto(struct tcb *, int);
496 : :
497 : : extern const char *xlookup(const struct xlat *, const uint64_t);
498 : : extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
499 : :
500 : : extern unsigned long get_pagesize(void);
501 : : extern int
502 : : string_to_uint_ex(const char *str, char **endptr,
503 : : unsigned int max_val, const char *accepted_ending);
504 : : extern int string_to_uint(const char *str);
505 : : static inline int
506 : 19261 : string_to_uint_upto(const char *const str, unsigned int max_val)
507 : : {
508 : 19261 : return string_to_uint_ex(str, NULL, max_val, NULL);
509 : : }
510 : : extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
511 : :
512 : : #define QUOTE_0_TERMINATED 0x01
513 : : #define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02
514 : : #define QUOTE_OMIT_TRAILING_0 0x08
515 : : #define QUOTE_FORCE_HEX 0x10
516 : :
517 : : extern int string_quote(const char *, char *, unsigned int, unsigned int);
518 : : extern int print_quoted_string(const char *, unsigned int, unsigned int);
519 : :
520 : : /* a refers to the lower numbered u_arg,
521 : : * b refers to the higher numbered u_arg
522 : : */
523 : : #ifdef WORDS_BIGENDIAN
524 : : # define ULONG_LONG(a,b) \
525 : : ((unsigned long long)(unsigned)(b) | ((unsigned long long)(a)<<32))
526 : : #else
527 : : # define ULONG_LONG(a,b) \
528 : : ((unsigned long long)(unsigned)(a) | ((unsigned long long)(b)<<32))
529 : : #endif
530 : : extern int getllval(struct tcb *, unsigned long long *, int);
531 : : extern int printllval(struct tcb *, const char *, int)
532 : : ATTRIBUTE_FORMAT((printf, 2, 0));
533 : :
534 : : extern void printaddr(kernel_ulong_t addr);
535 : : extern int printxvals(const uint64_t, const char *, const struct xlat *, ...)
536 : : ATTRIBUTE_SENTINEL;
537 : : extern int printxval_searchn(const struct xlat *xlat, size_t xlat_size,
538 : : uint64_t val, const char *dflt);
539 : : #define printxval_search(xlat__, val__, dflt__) \
540 : : printxval_searchn(xlat__, ARRAY_SIZE(xlat__), val__, dflt__)
541 : : extern int printargs(struct tcb *);
542 : : extern int printargs_u(struct tcb *);
543 : : extern int printargs_d(struct tcb *);
544 : :
545 : : extern void addflags(const struct xlat *, uint64_t);
546 : : extern int printflags64(const struct xlat *, uint64_t, const char *);
547 : : extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
548 : : extern const char *sprinttime(time_t);
549 : : extern void print_symbolic_mode_t(unsigned int);
550 : : extern void print_numeric_umode_t(unsigned short);
551 : : extern void print_numeric_long_umask(unsigned long);
552 : : extern void print_dev_t(unsigned long long dev);
553 : :
554 : : extern void
555 : : dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size);
556 : :
557 : : extern void
558 : : dumpiov_in_mmsghdr(struct tcb *, kernel_ulong_t addr);
559 : :
560 : : extern void
561 : : dumpiov_upto(struct tcb *, int len, kernel_ulong_t addr, kernel_ulong_t data_size);
562 : :
563 : : extern void
564 : : dumpstr(struct tcb *, kernel_ulong_t addr, int len);
565 : :
566 : : extern void
567 : : printstr_ex(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
568 : : unsigned int user_style);
569 : :
570 : : extern void
571 : : printpathn(struct tcb *, kernel_ulong_t addr, unsigned int n);
572 : :
573 : : extern void
574 : : printpath(struct tcb *, kernel_ulong_t addr);
575 : :
576 : : #define TIMESPEC_TEXT_BUFSIZE \
577 : : (sizeof(intmax_t)*3 * 2 + sizeof("{tv_sec=%jd, tv_nsec=%jd}"))
578 : : extern void printfd(struct tcb *, int);
579 : : extern void print_sockaddr(struct tcb *tcp, const void *, int);
580 : : extern bool print_sockaddr_by_inode(const unsigned long, const enum sock_proto);
581 : : extern bool print_sockaddr_by_inode_cached(const unsigned long);
582 : : extern void print_dirfd(struct tcb *, int);
583 : :
584 : : extern int
585 : : decode_sockaddr(struct tcb *, kernel_ulong_t addr, int addrlen);
586 : :
587 : : extern void printuid(const char *, const unsigned int);
588 : :
589 : : extern void
590 : : print_sigset_addr_len(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len);
591 : : extern void
592 : : print_sigset_addr(struct tcb *, kernel_ulong_t addr);
593 : :
594 : : extern const char *sprintsigmask_n(const char *, const void *, unsigned int);
595 : : #define tprintsigmask_addr(prefix, mask) \
596 : : tprints(sprintsigmask_n((prefix), (mask), sizeof(mask)))
597 : : extern void printsignal(int);
598 : :
599 : : extern void
600 : : tprint_iov_upto(struct tcb *, kernel_ulong_t len, kernel_ulong_t addr,
601 : : enum iov_decode, kernel_ulong_t data_size);
602 : :
603 : : extern void
604 : : decode_netlink(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len);
605 : :
606 : : extern void tprint_open_modes(unsigned int);
607 : : extern const char *sprint_open_modes(unsigned int);
608 : :
609 : : extern void
610 : : print_seccomp_filter(struct tcb *, kernel_ulong_t addr);
611 : :
612 : : extern void
613 : : print_seccomp_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
614 : :
615 : : struct strace_stat;
616 : : extern void print_struct_stat(struct tcb *tcp, const struct strace_stat *const st);
617 : :
618 : : struct strace_statfs;
619 : :
620 : : extern void
621 : : print_struct_statfs(struct tcb *, kernel_ulong_t addr);
622 : :
623 : : extern void
624 : : print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
625 : :
626 : : extern void print_ifindex(unsigned int);
627 : :
628 : : struct number_set;
629 : : extern struct number_set read_set;
630 : : extern struct number_set write_set;
631 : : extern struct number_set signal_set;
632 : :
633 : : extern bool is_number_in_set(unsigned int number, const struct number_set *);
634 : : extern void qualify(const char *);
635 : : extern unsigned int qual_flags(const unsigned int);
636 : :
637 : : #define DECL_IOCTL(name) \
638 : : extern int \
639 : : name ## _ioctl(struct tcb *, unsigned int request, kernel_ulong_t arg)
640 : : DECL_IOCTL(dm);
641 : : DECL_IOCTL(file);
642 : : DECL_IOCTL(fs_x);
643 : : DECL_IOCTL(nsfs);
644 : : DECL_IOCTL(ptp);
645 : : DECL_IOCTL(scsi);
646 : : DECL_IOCTL(term);
647 : : DECL_IOCTL(ubi);
648 : : DECL_IOCTL(uffdio);
649 : : #undef DECL_IOCTL
650 : :
651 : : extern int decode_sg_io_v4(struct tcb *, const kernel_ulong_t arg);
652 : :
653 : : extern int tv_nz(const struct timeval *);
654 : : extern int tv_cmp(const struct timeval *, const struct timeval *);
655 : : extern double tv_float(const struct timeval *);
656 : : extern void tv_add(struct timeval *, const struct timeval *, const struct timeval *);
657 : : extern void tv_sub(struct timeval *, const struct timeval *, const struct timeval *);
658 : : extern void tv_mul(struct timeval *, const struct timeval *, int);
659 : : extern void tv_div(struct timeval *, const struct timeval *, int);
660 : :
661 : : #ifdef USE_LIBUNWIND
662 : : extern void unwind_init(void);
663 : : extern void unwind_tcb_init(struct tcb *tcp);
664 : : extern void unwind_tcb_fin(struct tcb *tcp);
665 : : extern void unwind_cache_invalidate(struct tcb* tcp);
666 : : extern void unwind_print_stacktrace(struct tcb* tcp);
667 : : extern void unwind_capture_stacktrace(struct tcb* tcp);
668 : : #endif
669 : :
670 : : static inline void
671 : 49345 : printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len)
672 : : {
673 : 49345 : printstr_ex(tcp, addr, len, 0);
674 : 49345 : }
675 : :
676 : : static inline void
677 : 28865 : printstr(struct tcb *tcp, kernel_ulong_t addr)
678 : : {
679 : 28865 : printstr_ex(tcp, addr, -1, QUOTE_0_TERMINATED);
680 : 28865 : }
681 : :
682 : : static inline int
683 : 448228 : printflags(const struct xlat *x, unsigned int flags, const char *dflt)
684 : : {
685 : 448228 : return printflags64(x, flags, dflt);
686 : : }
687 : :
688 : : static inline int
689 : 671 : printxval64(const struct xlat *x, const uint64_t val, const char *dflt)
690 : : {
691 : 671 : return printxvals(val, dflt, x, NULL);
692 : : }
693 : :
694 : : static inline int
695 : 857333 : printxval(const struct xlat *x, const unsigned int val, const char *dflt)
696 : : {
697 : 857333 : return printxvals(val, dflt, x, NULL);
698 : : }
699 : :
700 : : static inline void
701 : 28286 : tprint_iov(struct tcb *tcp, kernel_ulong_t len, kernel_ulong_t addr,
702 : : enum iov_decode decode_iov)
703 : : {
704 : 28286 : tprint_iov_upto(tcp, len, addr, decode_iov, -1);
705 : 28286 : }
706 : :
707 : : #ifdef ALPHA
708 : : typedef struct {
709 : : int tv_sec, tv_usec;
710 : : } timeval32_t;
711 : :
712 : : extern void print_timeval32_t(const timeval32_t *);
713 : : extern void printrusage32(struct tcb *, kernel_ulong_t);
714 : : extern const char *sprint_timeval32(struct tcb *tcp, kernel_ulong_t);
715 : : extern void print_timeval32(struct tcb *tcp, kernel_ulong_t);
716 : : extern void print_timeval32_pair(struct tcb *tcp, kernel_ulong_t);
717 : : extern void print_itimerval32(struct tcb *tcp, kernel_ulong_t);
718 : : #endif
719 : :
720 : : #ifdef HAVE_STRUCT_USER_DESC
721 : : extern void print_user_desc(struct tcb *, kernel_ulong_t addr);
722 : : #endif
723 : :
724 : : /* Strace log generation machinery.
725 : : *
726 : : * printing_tcp: tcb which has incomplete line being printed right now.
727 : : * NULL if last line has been completed ('\n'-terminated).
728 : : * printleader(tcp) examines it, finishes incomplete line if needed,
729 : : * the sets it to tcp.
730 : : * line_ended() clears printing_tcp and resets ->curcol = 0.
731 : : * tcp->curcol == 0 check is also used to detect completeness
732 : : * of last line, since in -ff mode just checking printing_tcp for NULL
733 : : * is not enough.
734 : : *
735 : : * If you change this code, test log generation in both -f and -ff modes
736 : : * using:
737 : : * strace -oLOG -f[f] test/threaded_execve
738 : : * strace -oLOG -f[f] test/sigkill_rain
739 : : * strace -oLOG -f[f] -p "`pidof web_browser`"
740 : : */
741 : : extern struct tcb *printing_tcp;
742 : : extern void printleader(struct tcb *);
743 : : extern void line_ended(void);
744 : : extern void tabto(void);
745 : : extern void tprintf(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
746 : : extern void tprints(const char *str);
747 : :
748 : : #if SUPPORTED_PERSONALITIES > 1
749 : : extern void set_personality(int personality);
750 : : extern unsigned current_personality;
751 : : #else
752 : : # define set_personality(personality) ((void)0)
753 : : # define current_personality 0
754 : : #endif
755 : :
756 : : #if SUPPORTED_PERSONALITIES == 1
757 : : # define current_wordsize PERSONALITY0_WORDSIZE
758 : : # define current_klongsize PERSONALITY0_KLONGSIZE
759 : : #else
760 : : # if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_WORDSIZE == PERSONALITY1_WORDSIZE
761 : : # define current_wordsize PERSONALITY0_WORDSIZE
762 : : # else
763 : : extern unsigned current_wordsize;
764 : : # endif
765 : : # if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_KLONGSIZE == PERSONALITY1_KLONGSIZE
766 : : # define current_klongsize PERSONALITY0_KLONGSIZE
767 : : # else
768 : : extern unsigned current_klongsize;
769 : : # endif
770 : : #endif
771 : :
772 : : #define ANY_WORDSIZE_LESS_THAN_KERNEL_LONG \
773 : : (SIZEOF_KERNEL_LONG_T > 4 \
774 : : && (SIZEOF_LONG < SIZEOF_KERNEL_LONG_T || !defined(current_wordsize)))
775 : :
776 : : #define DECL_PRINTNUM(name) \
777 : : extern bool \
778 : : printnum_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
779 : : ATTRIBUTE_FORMAT((printf, 3, 0))
780 : : DECL_PRINTNUM(short);
781 : : DECL_PRINTNUM(int);
782 : : DECL_PRINTNUM(int64);
783 : : #undef DECL_PRINTNUM
784 : :
785 : : #define DECL_PRINTNUM_ADDR(name) \
786 : : extern bool \
787 : : printnum_addr_ ## name(struct tcb *, kernel_ulong_t addr)
788 : : DECL_PRINTNUM_ADDR(int);
789 : : DECL_PRINTNUM_ADDR(int64);
790 : : #undef DECL_PRINTNUM_ADDR
791 : :
792 : : #ifndef current_wordsize
793 : : extern bool
794 : : printnum_long_int(struct tcb *, kernel_ulong_t addr,
795 : : const char *fmt_long, const char *fmt_int)
796 : : ATTRIBUTE_FORMAT((printf, 3, 0))
797 : : ATTRIBUTE_FORMAT((printf, 4, 0));
798 : : extern bool printnum_addr_long_int(struct tcb *, kernel_ulong_t addr);
799 : : # define printnum_slong(tcp, addr) \
800 : : printnum_long_int((tcp), (addr), "%" PRId64, "%d")
801 : : # define printnum_ulong(tcp, addr) \
802 : : printnum_long_int((tcp), (addr), "%" PRIu64, "%u")
803 : : # define printnum_ptr(tcp, addr) \
804 : : printnum_addr_long_int((tcp), (addr))
805 : : #elif current_wordsize > 4
806 : : # define printnum_slong(tcp, addr) \
807 : : printnum_int64((tcp), (addr), "%" PRId64)
808 : : # define printnum_ulong(tcp, addr) \
809 : : printnum_int64((tcp), (addr), "%" PRIu64)
810 : : # define printnum_ptr(tcp, addr) \
811 : : printnum_addr_int64((tcp), (addr))
812 : : #else /* current_wordsize == 4 */
813 : : # define printnum_slong(tcp, addr) \
814 : : printnum_int((tcp), (addr), "%d")
815 : : # define printnum_ulong(tcp, addr) \
816 : : printnum_int((tcp), (addr), "%u")
817 : : # define printnum_ptr(tcp, addr) \
818 : : printnum_addr_int((tcp), (addr))
819 : : #endif
820 : :
821 : : #ifndef current_klongsize
822 : : extern bool printnum_addr_klong_int(struct tcb *, kernel_ulong_t addr);
823 : : # define printnum_kptr(tcp, addr) \
824 : : printnum_addr_klong_int((tcp), (addr))
825 : : #elif current_klongsize > 4
826 : : # define printnum_kptr(tcp, addr) \
827 : : printnum_addr_int64((tcp), (addr))
828 : : #else /* current_klongsize == 4 */
829 : : # define printnum_kptr(tcp, addr) \
830 : : printnum_addr_int((tcp), (addr))
831 : : #endif
832 : :
833 : : #define DECL_PRINTPAIR(name) \
834 : : extern bool \
835 : : printpair_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
836 : : ATTRIBUTE_FORMAT((printf, 3, 0))
837 : : DECL_PRINTPAIR(int);
838 : : DECL_PRINTPAIR(int64);
839 : : #undef DECL_PRINTPAIR
840 : :
841 : : static inline kernel_long_t
842 : 70 : truncate_klong_to_current_wordsize(const kernel_long_t v)
843 : : {
844 : : #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
845 [ + + ]: 70 : if (current_wordsize < sizeof(v)) {
846 : 14 : return (int) v;
847 : : } else
848 : : #endif
849 : : {
850 : 56 : return v;
851 : : }
852 : : }
853 : :
854 : : static inline kernel_ulong_t
855 : 258 : truncate_kulong_to_current_wordsize(const kernel_ulong_t v)
856 : : {
857 : : #if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
858 [ + + ]: 258 : if (current_wordsize < sizeof(v)) {
859 : 43 : return (unsigned int) v;
860 : : } else
861 : : #endif
862 : : {
863 : 215 : return v;
864 : : }
865 : : }
866 : :
867 : : /*
868 : : * Cast a pointer or a pointer-sized integer to kernel_ulong_t.
869 : : */
870 : : #define ptr_to_kulong(v) ((kernel_ulong_t) (unsigned long) (v))
871 : :
872 : : /*
873 : : * Zero-extend a signed integer type to unsigned long long.
874 : : */
875 : : #define zero_extend_signed_to_ull(v) \
876 : : (sizeof(v) == sizeof(char) ? (unsigned long long) (unsigned char) (v) : \
877 : : sizeof(v) == sizeof(short) ? (unsigned long long) (unsigned short) (v) : \
878 : : sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
879 : : sizeof(v) == sizeof(long) ? (unsigned long long) (unsigned long) (v) : \
880 : : (unsigned long long) (v))
881 : :
882 : : /*
883 : : * Sign-extend an unsigned integer type to long long.
884 : : */
885 : : #define sign_extend_unsigned_to_ll(v) \
886 : : (sizeof(v) == sizeof(char) ? (long long) (char) (v) : \
887 : : sizeof(v) == sizeof(short) ? (long long) (short) (v) : \
888 : : sizeof(v) == sizeof(int) ? (long long) (int) (v) : \
889 : : sizeof(v) == sizeof(long) ? (long long) (long) (v) : \
890 : : (long long) (v))
891 : :
892 : : extern const struct_sysent sysent0[];
893 : : extern const char *const errnoent0[];
894 : : extern const char *const signalent0[];
895 : : extern const struct_ioctlent ioctlent0[];
896 : :
897 : : #if SUPPORTED_PERSONALITIES > 1
898 : : extern const struct_sysent *sysent;
899 : : extern const char *const *errnoent;
900 : : extern const char *const *signalent;
901 : : extern const struct_ioctlent *ioctlent;
902 : : #else
903 : : # define sysent sysent0
904 : : # define errnoent errnoent0
905 : : # define signalent signalent0
906 : : # define ioctlent ioctlent0
907 : : #endif
908 : :
909 : : extern unsigned nsyscalls;
910 : : extern unsigned nerrnos;
911 : : extern unsigned nsignals;
912 : : extern unsigned nioctlents;
913 : :
914 : : extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES];
915 : : extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES];
916 : : extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
917 : :
918 : : #ifdef IN_MPERS_BOOTSTRAP
919 : : /* Transform multi-line MPERS_PRINTER_DECL statements to one-liners. */
920 : : # define MPERS_PRINTER_DECL(type, name, ...) MPERS_PRINTER_DECL(type, name, __VA_ARGS__)
921 : : #else /* !IN_MPERS_BOOTSTRAP */
922 : : # if SUPPORTED_PERSONALITIES > 1
923 : : # include "printers.h"
924 : : # else
925 : : # include "native_printer_decls.h"
926 : : # endif
927 : : # define MPERS_PRINTER_DECL(type, name, ...) type MPERS_FUNC_NAME(name)(__VA_ARGS__)
928 : : #endif /* !IN_MPERS_BOOTSTRAP */
929 : :
930 : : /* Checks that sysent[scno] is not out of range. */
931 : : static inline bool
932 : 11726376 : scno_in_range(kernel_ulong_t scno)
933 : : {
934 : 11726376 : return scno < nsyscalls;
935 : : }
936 : :
937 : : /*
938 : : * Checks whether scno is not out of range,
939 : : * its corresponding sysent[scno].sys_func is non-NULL,
940 : : * and its sysent[scno].sys_flags has no TRACE_INDIRECT_SUBCALL flag set.
941 : : */
942 : : static inline bool
943 : 11667265 : scno_is_valid(kernel_ulong_t scno)
944 : : {
945 : 11667265 : return scno_in_range(scno)
946 [ + - ]: 11667250 : && sysent[scno].sys_func
947 [ + + ][ + + ]: 23334515 : && !(sysent[scno].sys_flags & TRACE_INDIRECT_SUBCALL);
948 : : }
949 : :
950 : : #define MPERS_FUNC_NAME__(prefix, name) prefix ## name
951 : : #define MPERS_FUNC_NAME_(prefix, name) MPERS_FUNC_NAME__(prefix, name)
952 : : #define MPERS_FUNC_NAME(name) MPERS_FUNC_NAME_(MPERS_PREFIX, name)
953 : :
954 : : #define SYS_FUNC_NAME(syscall_name) MPERS_FUNC_NAME(syscall_name)
955 : :
956 : : #define SYS_FUNC(syscall_name) int SYS_FUNC_NAME(sys_ ## syscall_name)(struct tcb *tcp)
957 : :
958 : : #if SIZEOF_KERNEL_LONG_T > SIZEOF_LONG
959 : : # define PRI_kl "ll"
960 : : #else
961 : : # define PRI_kl "l"
962 : : #endif
963 : :
964 : : #define PRI_kld PRI_kl"d"
965 : : #define PRI_klu PRI_kl"u"
966 : : #define PRI_klx PRI_kl"x"
967 : :
968 : : /*
969 : : * The kernel used to define 64-bit types on 64-bit systems on a per-arch
970 : : * basis. Some architectures would use unsigned long and others would use
971 : : * unsigned long long. These types were exported as part of the
972 : : * kernel-userspace ABI and now must be maintained forever. This matches
973 : : * what the kernel exports for each architecture so we don't need to cast
974 : : * every printing of __u64 or __s64 to stdint types.
975 : : */
976 : : #if SIZEOF_LONG == 4
977 : : # define PRI__64 "ll"
978 : : #elif defined ALPHA || defined IA64 || defined MIPS || defined POWERPC
979 : : # define PRI__64 "l"
980 : : #else
981 : : # define PRI__64 "ll"
982 : : #endif
983 : :
984 : : #define PRI__d64 PRI__64"d"
985 : : #define PRI__u64 PRI__64"u"
986 : : #define PRI__x64 PRI__64"x"
987 : :
988 : : #endif /* !STRACE_DEFS_H */
|