1999-02-19 03:21:36 +03:00
/*
* Copyright ( c ) 1991 , 1992 Paul Kranenburg < pk @ cs . few . eur . nl >
* Copyright ( c ) 1993 Branko Lankester < branko @ hacktic . nl >
* Copyright ( c ) 1993 , 1994 , 1995 , 1996 Rick Sladkey < jrs @ world . std . com >
1999-12-23 17:20:14 +03:00
* Copyright ( c ) 1996 - 1999 Wichert Akkerman < wichert @ cistron . nl >
* Copyright ( c ) 1999 IBM Deutschland Entwicklung GmbH , IBM Corporation
* Linux for s390 port by D . J . Barrow
* < barrow_dj @ mail . yahoo . com , djbarrow @ de . ibm . com >
2018-02-14 01:00:00 +03:00
* Copyright ( c ) 1999 - 2018 The strace developers .
1999-02-19 03:21:36 +03:00
* All rights reserved .
*
2018-12-10 03:00:00 +03:00
* SPDX - License - Identifier : LGPL - 2.1 - or - later
1999-02-19 03:21:36 +03:00
*/
# include "defs.h"
2018-02-11 03:26:09 +03:00
# include <limits.h>
1999-02-19 03:21:36 +03:00
# include <fcntl.h>
decode extend getsockopt/setsockopt options
Currently the code assumes the set of valid options between getsockopt
and setsockopt are exactly the same and thus maintains one list. The
kernel unfortunately does not do this -- it allows for different opts
between the get and set functions. See the {g,s}et_opt{min,max} fields
in the various netfilter subcores.
To support this, extend the printxval function to take multiple sets of
xlats as varargs. Then we add the new get/set lists, and pass them down
in the net code when decoding things.
A simple example is iptables; before:
getsockopt(4, SOL_IP, 0x40 /* IP_??? */, ...) = 0
getsockopt(4, SOL_IP, 0x41 /* IP_??? */, ...) = 0
after:
getsockopt(4, SOL_IP, IPT_SO_GET_INFO, ...) = 0
getsockopt(4, SOL_IP, IPT_SO_GET_ENTRIES, ...) = 0
If these were setsockopt calls, then 0x40 & 0x41 would be
IPT_SO_SET_REPLACE & IPT_SO_SET_ADD_COUNTERS.
* configure.ac: Check for netfilter headers.
* defs.h (printxvals): New prototype.
(printxval): Change to a define.
* net.c: Include netfilter headers and new sockopts headers.
(print_sockopt_fd_level_name): Add a is_getsockopt argument. Change SOL_IP
and SOL_IPV6 decoding to use printxvals, and use is_getsockopt to pass more
xlats down.
(getsockopt): Call print_sockopt_fd_level_name with is_getsockopt as true.
(setsockopt): Call print_sockopt_fd_level_name with is_getsockopt as false.
* util.c (printxval): Rename to ...
(printxvals): ... this. Rewrite to be varargs based.
* xlat/getsockipoptions.in: New xlat list.
* xlat/getsockipv6options.in, xlat/setsockipoptions.in,
xlat/setsockipv6options.in: Likewise.
2015-08-19 20:29:27 +03:00
# include <stdarg.h>
2018-01-25 19:53:23 +03:00
# include <sys/stat.h>
# include <sys/sysmacros.h>
2015-06-17 23:09:13 +03:00
# ifdef HAVE_SYS_XATTR_H
2014-11-22 13:03:33 +03:00
# include <sys / xattr.h>
# endif
2014-11-21 23:46:16 +03:00
# include <sys/uio.h>
2018-01-25 19:53:23 +03:00
# include "largefile_wrappers.h"
print_array: add support for printing array indices
* defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants.
(tfetch_mem_fn, print_fn): New typedefs.
(enum print_array_flag_bits, enum print_array_flags): New enumerations.
(print_array_ex): Rename from print_array, add flags, index_xlat,
index_xlat_size, and index_dflt arguments.
(print_array): New static inline function, a thin wrapper around
print_array_ex.
util.c: Include "xlat.h".
(print_array): Rename to print_array_ex, add flags, index_xlat,
index_xlat_size, and index_dflt arguments. Print array indices
according to the style settings specified by flags if PAF_PRINT_INDICES
is set.
2018-05-07 09:06:14 +03:00
# include "xlat.h"
2018-01-06 04:45:16 +03:00
# include "xstring.h"
1999-05-09 04:29:58 +04:00
1999-02-19 03:21:36 +03:00
int
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_nz ( const struct timespec * a )
1999-02-19 03:21:36 +03:00
{
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
return a - > tv_sec | | a - > tv_nsec ;
1999-02-19 03:21:36 +03:00
}
int
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_cmp ( const struct timespec * a , const struct timespec * b )
1999-02-19 03:21:36 +03:00
{
if ( a - > tv_sec < b - > tv_sec
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
| | ( a - > tv_sec = = b - > tv_sec & & a - > tv_nsec < b - > tv_nsec ) )
1999-02-19 03:21:36 +03:00
return - 1 ;
if ( a - > tv_sec > b - > tv_sec
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
| | ( a - > tv_sec = = b - > tv_sec & & a - > tv_nsec > b - > tv_nsec ) )
1999-02-19 03:21:36 +03:00
return 1 ;
return 0 ;
}
double
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_float ( const struct timespec * tv )
1999-02-19 03:21:36 +03:00
{
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
return tv - > tv_sec + tv - > tv_nsec / 1000000000.0 ;
1999-02-19 03:21:36 +03:00
}
void
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_add ( struct timespec * tv , const struct timespec * a , const struct timespec * b )
1999-02-19 03:21:36 +03:00
{
tv - > tv_sec = a - > tv_sec + b - > tv_sec ;
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
tv - > tv_nsec = a - > tv_nsec + b - > tv_nsec ;
if ( tv - > tv_nsec > = 1000000000 ) {
1999-02-19 03:21:36 +03:00
tv - > tv_sec + + ;
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
tv - > tv_nsec - = 1000000000 ;
1999-02-19 03:21:36 +03:00
}
}
void
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_sub ( struct timespec * tv , const struct timespec * a , const struct timespec * b )
1999-02-19 03:21:36 +03:00
{
tv - > tv_sec = a - > tv_sec - b - > tv_sec ;
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
tv - > tv_nsec = a - > tv_nsec - b - > tv_nsec ;
if ( tv - > tv_nsec < 0 ) {
1999-02-19 03:21:36 +03:00
tv - > tv_sec - - ;
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
tv - > tv_nsec + = 1000000000 ;
1999-02-19 03:21:36 +03:00
}
}
void
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_div ( struct timespec * tv , const struct timespec * a , int n )
1999-02-19 03:21:36 +03:00
{
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
long long nsec = ( a - > tv_sec % n * 1000000000LL + a - > tv_nsec + n / 2 ) / n ;
tv - > tv_sec = a - > tv_sec / n + nsec / 1000000000 ;
tv - > tv_nsec = nsec % 1000000000 ;
1999-02-19 03:21:36 +03:00
}
void
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
ts_mul ( struct timespec * tv , const struct timespec * a , int n )
1999-02-19 03:21:36 +03:00
{
Replace struct timeval with struct timespec in time measurements
This is required to implement more precise time measurements.
* Makefile.am (strace_LDADD): Add $(clock_LIBS).
* defs.h (struct tcb): Change the type of stime, dtime, and etime fields
from struct timeval to struct timespec, all users updated.
(syscall_exiting_decode, syscall_exiting_trace, count_syscall): Change
the type of "struct timeval *" argument to "struct timespec *", all
users updated.
(tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul): Rename to
ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul. Change
the type of all "struct timeval *" arguments to "struct timespec *",
all users updated.
* util.c (tv_nz, tv_cmp, tv_float, tv_add, tv_sub, tv_div, tv_mul):
Rename to ts_nz, ts_cmp, ts_float, ts_add, ts_sub, ts_div, and ts_mul.
Change the type of all "struct timeval *" arguments to "struct timespec *".
* count.c (struct call_counts): Change the type of "time" field
from struct timeval to struct timespec, all users updated.
(overhead): Change type from struct timeval to struct timespec, all
users updated.
(count_syscall): Change the type of "struct timeval *" argument to
"struct timespec *".
* strace.c (printleader): Change the type of struct timeval variables
to struct timespec, call clock_gettime instead of gettimeofday.
(next_event, trace_syscall): Change the type of struct timeval variables
to struct timespec.
* syscall.c (syscall_entering_finish, syscall_exiting_decode): Call
clock_gettime instead of gettimeofday.
2018-03-16 03:55:58 +03:00
long long nsec = a - > tv_nsec * n ;
tv - > tv_sec = a - > tv_sec * n + nsec / 1000000000 ;
tv - > tv_nsec = nsec % 1000000000 ;
1999-02-19 03:21:36 +03:00
}
2011-09-01 18:31:48 +04:00
# if !defined HAVE_STPCPY
2011-08-31 14:07:38 +04:00
char *
stpcpy ( char * dst , const char * src )
{
while ( ( * dst = * src + + ) ! = ' \0 ' )
dst + + ;
return dst ;
}
2011-09-01 18:31:48 +04:00
# endif
2011-08-31 14:07:38 +04:00
2013-11-09 23:40:31 +04:00
/* Find a next bit which is set.
* Starts testing at cur_bit .
* Returns - 1 if no more bits are set .
*
* We never touch bytes we don ' t need to .
* On big - endian , array is assumed to consist of
* current_wordsize wide words : for example , is current_wordsize is 4 ,
* the bytes are walked in 3 , 2 , 1 , 0 , 7 , 6 , 5 , 4 , 11 , 10 , 9 , 8 . . . sequence .
* On little - endian machines , word size is immaterial .
*/
int
next_set_bit ( const void * bit_array , unsigned cur_bit , unsigned size_bits )
{
const unsigned endian = 1 ;
2017-06-18 01:23:09 +03:00
int little_endian = * ( char * ) ( void * ) & endian ;
2013-11-09 23:40:31 +04:00
const uint8_t * array = bit_array ;
unsigned pos = cur_bit / 8 ;
unsigned pos_xor_mask = little_endian ? 0 : current_wordsize - 1 ;
for ( ; ; ) {
uint8_t bitmask ;
uint8_t cur_byte ;
if ( cur_bit > = size_bits )
return - 1 ;
cur_byte = array [ pos ^ pos_xor_mask ] ;
if ( cur_byte = = 0 ) {
cur_bit = ( cur_bit + 8 ) & ( - 8 ) ;
pos + + ;
continue ;
}
bitmask = 1 < < ( cur_bit & 7 ) ;
for ( ; ; ) {
if ( cur_byte & bitmask )
return cur_bit ;
cur_bit + + ;
if ( cur_bit > = size_bits )
return - 1 ;
bitmask < < = 1 ;
/* This check *can't be* optimized out: */
if ( bitmask = = 0 )
break ;
}
pos + + ;
}
}
2016-11-27 18:04:58 +03:00
2009-11-04 19:08:34 +03:00
/*
2015-01-10 03:08:58 +03:00
* Fetch 64 bit argument at position arg_no and
* return the index of the next argument .
2009-11-04 19:08:34 +03:00
*/
int
2015-01-10 03:08:58 +03:00
getllval ( struct tcb * tcp , unsigned long long * val , int arg_no )
2009-11-04 19:08:34 +03:00
{
2016-12-26 19:54:31 +03:00
# if SIZEOF_KERNEL_LONG_T > 4
2016-12-19 21:30:22 +03:00
# ifndef current_klongsize
2016-12-26 19:54:31 +03:00
if ( current_klongsize < SIZEOF_KERNEL_LONG_T ) {
2013-05-04 23:51:57 +04:00
# if defined(AARCH64) || defined(POWERPC64)
Fix preadv/pwritev offset decoding on bigendian architectures
This partially reverts commit 7845a42b39e59e904d01e75e21f7bc7eb6462560.
* util.c (printllval): Remove align argument.
* defs.h (printllval): Update prototype.
(printllval_aligned, printllval_unaligned): Remove.
* file.c (sys_readahead, sys_truncate64, sys_ftruncate64, sys_fadvise64,
sys_fadvise64_64, sys_sync_file_range, sys_sync_file_range2,
sys_fallocate): Replace printllval_aligned call with printllval.
* io.c (sys_pread, sys_pwrite): Likewise.
(print_llu_from_low_high_val): New function.
(sys_preadv, sys_pwritev): Use it instead of printllval_unaligned.
2014-08-07 04:07:28 +04:00
/* Align arg_no to the next even number. */
arg_no = ( arg_no + 1 ) & 0xe ;
2015-01-10 03:08:58 +03:00
# endif /* AARCH64 || POWERPC64 */
2016-12-23 22:12:38 +03:00
* val = ULONG_LONG ( tcp - > u_arg [ arg_no ] , tcp - > u_arg [ arg_no + 1 ] ) ;
2013-03-01 13:41:02 +04:00
arg_no + = 2 ;
2016-12-19 21:30:22 +03:00
} else
# endif /* !current_klongsize */
{
* val = tcp - > u_arg [ arg_no ] ;
arg_no + + ;
2009-11-04 19:08:34 +03:00
}
2016-12-26 19:54:31 +03:00
# else /* SIZEOF_KERNEL_LONG_T == 4 */
2017-06-18 01:23:09 +03:00
# if defined __ARM_EABI__ \
| | defined LINUX_MIPSO32 \
| | defined POWERPC \
| | defined XTENSA
Fix preadv/pwritev offset decoding on bigendian architectures
This partially reverts commit 7845a42b39e59e904d01e75e21f7bc7eb6462560.
* util.c (printllval): Remove align argument.
* defs.h (printllval): Update prototype.
(printllval_aligned, printllval_unaligned): Remove.
* file.c (sys_readahead, sys_truncate64, sys_ftruncate64, sys_fadvise64,
sys_fadvise64_64, sys_sync_file_range, sys_sync_file_range2,
sys_fallocate): Replace printllval_aligned call with printllval.
* io.c (sys_pread, sys_pwrite): Likewise.
(print_llu_from_low_high_val): New function.
(sys_preadv, sys_pwritev): Use it instead of printllval_unaligned.
2014-08-07 04:07:28 +04:00
/* Align arg_no to the next even number. */
arg_no = ( arg_no + 1 ) & 0xe ;
2016-08-20 17:02:55 +03:00
# elif defined SH
/*
* The SH4 ABI does allow long longs in odd - numbered registers , but
* does not allow them to be split between registers and memory - and
* there are only four argument registers for normal functions . As a
* result , pread , for example , takes an extra padding argument before
* the offset . This was changed late in the 2.4 series ( around 2.4 .20 ) .
*/
if ( arg_no = = 3 )
arg_no + + ;
# endif /* __ARM_EABI__ || LINUX_MIPSO32 || POWERPC || XTENSA || SH */
2016-12-23 22:12:38 +03:00
* val = ULONG_LONG ( tcp - > u_arg [ arg_no ] , tcp - > u_arg [ arg_no + 1 ] ) ;
2013-03-01 13:41:02 +04:00
arg_no + = 2 ;
2013-02-18 01:41:33 +04:00
# endif
2013-05-04 23:51:57 +04:00
2013-03-01 13:41:02 +04:00
return arg_no ;
2009-11-04 19:08:34 +03:00
}
2015-01-10 03:08:58 +03:00
/*
* Print 64 bit argument at position arg_no and
* return the index of the next argument .
*/
int
printllval ( struct tcb * tcp , const char * format , int arg_no )
{
unsigned long long val = 0 ;
arg_no = getllval ( tcp , & val , arg_no ) ;
tprintf ( format , val ) ;
return arg_no ;
}
2015-07-06 01:09:29 +03:00
void
2018-02-22 01:15:54 +03:00
printaddr64 ( const uint64_t addr )
2015-07-06 01:09:29 +03:00
{
if ( ! addr )
tprints ( " NULL " ) ;
else
2018-02-22 01:15:54 +03:00
tprintf ( " %# " PRIx64 , addr ) ;
}
2015-07-06 01:09:29 +03:00
# define DEF_PRINTNUM(name, type) \
2015-08-19 00:57:27 +03:00
bool \
2016-12-26 13:26:03 +03:00
printnum_ # # name ( struct tcb * const tcp , const kernel_ulong_t addr , \
2016-12-21 01:33:52 +03:00
const char * const fmt ) \
2015-07-06 01:09:29 +03:00
{ \
type num ; \
2015-08-19 00:57:27 +03:00
if ( umove_or_printaddr ( tcp , addr , & num ) ) \
return false ; \
tprints ( " [ " ) ; \
tprintf ( fmt , num ) ; \
tprints ( " ] " ) ; \
return true ; \
1999-02-19 03:21:36 +03:00
}
2016-12-11 18:50:53 +03:00
# define DEF_PRINTNUM_ADDR(name, type) \
bool \
printnum_addr_ # # name ( struct tcb * tcp , const kernel_ulong_t addr ) \
{ \
type num ; \
if ( umove_or_printaddr ( tcp , addr , & num ) ) \
return false ; \
tprints ( " [ " ) ; \
2018-02-22 01:15:54 +03:00
printaddr64 ( num ) ; \
2016-12-11 18:50:53 +03:00
tprints ( " ] " ) ; \
return true ; \
}
2015-07-06 01:09:29 +03:00
# define DEF_PRINTPAIR(name, type) \
2015-08-19 00:57:27 +03:00
bool \
2016-12-26 13:26:03 +03:00
printpair_ # # name ( struct tcb * const tcp , const kernel_ulong_t addr , \
2016-12-21 01:33:52 +03:00
const char * const fmt ) \
2015-07-06 01:09:29 +03:00
{ \
type pair [ 2 ] ; \
2015-08-19 00:57:27 +03:00
if ( umove_or_printaddr ( tcp , addr , & pair ) ) \
return false ; \
tprints ( " [ " ) ; \
tprintf ( fmt , pair [ 0 ] ) ; \
tprints ( " , " ) ; \
tprintf ( fmt , pair [ 1 ] ) ; \
tprints ( " ] " ) ; \
return true ; \
2015-07-06 01:09:29 +03:00
}
2015-07-06 01:09:29 +03:00
DEF_PRINTNUM ( int , int )
2016-12-11 18:50:53 +03:00
DEF_PRINTNUM_ADDR ( int , unsigned int )
2015-07-06 01:09:29 +03:00
DEF_PRINTPAIR ( int , int )
2015-07-06 01:09:29 +03:00
DEF_PRINTNUM ( short , short )
DEF_PRINTNUM ( int64 , uint64_t )
2016-12-11 18:50:53 +03:00
DEF_PRINTNUM_ADDR ( int64 , uint64_t )
2015-07-06 01:09:29 +03:00
DEF_PRINTPAIR ( int64 , uint64_t )
Fix printing tracee's long integers
Replace ambiguous printnum_long that used to fetch native long integers
from tracee's memory with printnum_ptr, printnum_slong, and printnum_ulong
that fetch tracee's pointer, signed long, and unsigned long integers.
* defs.h (printnum_long, printpair_long): Remove prototypes.
(printnum_int64, printpair_int64): Remove macros, declare functions
unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New prototype.
(printnum_ptr, printnum_slong, printnum_ulong): New macros.
* aio.c (sys_io_setup): Use printnum_ulong.
* block.c (block_ioctl): Use printnum_slong and printnum_ulong.
* get_robust_list.c (sys_get_robust_list): Use printnum_ptr
and printnum_ulong.
* io.c (print_off_t): Remove.
(sys_sendfile): Use printnum_ulong.
* ipc.c (sys_semctl): Use printnum_ptr.
* prctl.c (sys_prctl): Likewise.
* process.c (sys_ptrace): Likewise.
* rtc.c (rtc_ioctl): Use printnum_ulong.
* util.c (printnum_long, printpair_long): Remove.
(printnum_int64, printpair_int64): Define unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New function.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Elvira Khabirova <lineprinter0@gmail.com>
2015-08-18 17:58:27 +03:00
2016-12-26 16:50:14 +03:00
# ifndef current_wordsize
2015-08-19 00:57:27 +03:00
bool
2016-12-26 13:26:03 +03:00
printnum_long_int ( struct tcb * const tcp , const kernel_ulong_t addr ,
2016-12-21 01:33:52 +03:00
const char * const fmt_long , const char * const fmt_int )
Fix printing tracee's long integers
Replace ambiguous printnum_long that used to fetch native long integers
from tracee's memory with printnum_ptr, printnum_slong, and printnum_ulong
that fetch tracee's pointer, signed long, and unsigned long integers.
* defs.h (printnum_long, printpair_long): Remove prototypes.
(printnum_int64, printpair_int64): Remove macros, declare functions
unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New prototype.
(printnum_ptr, printnum_slong, printnum_ulong): New macros.
* aio.c (sys_io_setup): Use printnum_ulong.
* block.c (block_ioctl): Use printnum_slong and printnum_ulong.
* get_robust_list.c (sys_get_robust_list): Use printnum_ptr
and printnum_ulong.
* io.c (print_off_t): Remove.
(sys_sendfile): Use printnum_ulong.
* ipc.c (sys_semctl): Use printnum_ptr.
* prctl.c (sys_prctl): Likewise.
* process.c (sys_ptrace): Likewise.
* rtc.c (rtc_ioctl): Use printnum_ulong.
* util.c (printnum_long, printpair_long): Remove.
(printnum_int64, printpair_int64): Define unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New function.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Elvira Khabirova <lineprinter0@gmail.com>
2015-08-18 17:58:27 +03:00
{
if ( current_wordsize > sizeof ( int ) ) {
2015-08-19 00:57:27 +03:00
return printnum_int64 ( tcp , addr , fmt_long ) ;
Fix printing tracee's long integers
Replace ambiguous printnum_long that used to fetch native long integers
from tracee's memory with printnum_ptr, printnum_slong, and printnum_ulong
that fetch tracee's pointer, signed long, and unsigned long integers.
* defs.h (printnum_long, printpair_long): Remove prototypes.
(printnum_int64, printpair_int64): Remove macros, declare functions
unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New prototype.
(printnum_ptr, printnum_slong, printnum_ulong): New macros.
* aio.c (sys_io_setup): Use printnum_ulong.
* block.c (block_ioctl): Use printnum_slong and printnum_ulong.
* get_robust_list.c (sys_get_robust_list): Use printnum_ptr
and printnum_ulong.
* io.c (print_off_t): Remove.
(sys_sendfile): Use printnum_ulong.
* ipc.c (sys_semctl): Use printnum_ptr.
* prctl.c (sys_prctl): Likewise.
* process.c (sys_ptrace): Likewise.
* rtc.c (rtc_ioctl): Use printnum_ulong.
* util.c (printnum_long, printpair_long): Remove.
(printnum_int64, printpair_int64): Define unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New function.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Elvira Khabirova <lineprinter0@gmail.com>
2015-08-18 17:58:27 +03:00
} else {
2015-08-19 00:57:27 +03:00
return printnum_int ( tcp , addr , fmt_int ) ;
Fix printing tracee's long integers
Replace ambiguous printnum_long that used to fetch native long integers
from tracee's memory with printnum_ptr, printnum_slong, and printnum_ulong
that fetch tracee's pointer, signed long, and unsigned long integers.
* defs.h (printnum_long, printpair_long): Remove prototypes.
(printnum_int64, printpair_int64): Remove macros, declare functions
unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New prototype.
(printnum_ptr, printnum_slong, printnum_ulong): New macros.
* aio.c (sys_io_setup): Use printnum_ulong.
* block.c (block_ioctl): Use printnum_slong and printnum_ulong.
* get_robust_list.c (sys_get_robust_list): Use printnum_ptr
and printnum_ulong.
* io.c (print_off_t): Remove.
(sys_sendfile): Use printnum_ulong.
* ipc.c (sys_semctl): Use printnum_ptr.
* prctl.c (sys_prctl): Likewise.
* process.c (sys_ptrace): Likewise.
* rtc.c (rtc_ioctl): Use printnum_ulong.
* util.c (printnum_long, printpair_long): Remove.
(printnum_int64, printpair_int64): Define unconditionally.
[SUPPORTED_PERSONALITIES > 1 && SIZEOF_LONG > 4] (printnum_long_int):
New function.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org>
Signed-off-by: Elvira Khabirova <lineprinter0@gmail.com>
2015-08-18 17:58:27 +03:00
}
}
2016-12-11 18:50:53 +03:00
bool
printnum_addr_long_int ( struct tcb * tcp , const kernel_ulong_t addr )
{
if ( current_wordsize > sizeof ( int ) ) {
return printnum_addr_int64 ( tcp , addr ) ;
} else {
return printnum_addr_int ( tcp , addr ) ;
}
}
2016-12-26 16:50:14 +03:00
# endif /* !current_wordsize */
2005-07-05 03:28:10 +04:00
2016-12-11 22:18:11 +03:00
# ifndef current_klongsize
bool
printnum_addr_klong_int ( struct tcb * tcp , const kernel_ulong_t addr )
{
if ( current_klongsize > sizeof ( int ) ) {
return printnum_addr_int64 ( tcp , addr ) ;
} else {
return printnum_addr_int ( tcp , addr ) ;
}
}
# endif /* !current_klongsize */
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
/**
* Prints time to a ( static internal ) buffer and returns pointer to it .
2018-03-18 09:53:32 +03:00
* Returns NULL if the provided time specification is not correct .
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
*
* @ param sec Seconds since epoch .
* @ param part_sec Amount of second parts since the start of a second .
* @ param max_part_sec Maximum value of a valid part_sec .
* @ param width 1 + floor ( log10 ( max_part_sec ) ) .
2018-03-18 09:53:32 +03:00
* @ return Pointer to a statically allocated string on success ,
* NULL on error .
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
*/
static const char *
sprinttime_ex ( const long long sec , const unsigned long long part_sec ,
const unsigned int max_part_sec , const int width )
{
static char buf [ sizeof ( int ) * 3 * 6 + sizeof ( part_sec ) * 3
+ sizeof ( " +0000 " ) ] ;
if ( ( sec = = 0 & & part_sec = = 0 ) | | part_sec > max_part_sec )
return NULL ;
time_t t = ( time_t ) sec ;
struct tm * tmp = ( sec = = t ) ? localtime ( & t ) : NULL ;
if ( ! tmp )
return NULL ;
size_t pos = strftime ( buf , sizeof ( buf ) , " %FT%T " , tmp ) ;
if ( ! pos )
return NULL ;
2018-01-06 04:45:16 +03:00
if ( part_sec > 0 )
pos + = xsnprintf ( buf + pos , sizeof ( buf ) - pos , " .%0*llu " ,
width , part_sec ) ;
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
return strftime ( buf + pos , sizeof ( buf ) - pos , " %z " , tmp ) ? buf : NULL ;
}
2014-12-06 06:53:16 +03:00
const char *
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
sprinttime ( long long sec )
2014-12-06 06:53:16 +03:00
{
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
return sprinttime_ex ( sec , 0 , 0 , 0 ) ;
}
2014-12-06 06:53:16 +03:00
Always print raw values of time data fields
Refactor sprinttime: implement sprinttime_nsec and sprinttime_usec
that handle nanoseconds and microseconds, respectively.
Always print raw values of time data fields, format string
representations of time as comments.
* defs.h (sprinttime): Change argument type from time_t to long long.
(sprinttime_nsec, sprinttime_usec): New prototypes.
* util.c (sprinttime_ex, sprinttime_nsec, sprinttime_usec): New
functions.
(sprinttime): Turn into a thin wrapper around sprinttime_ex.
* stat.h (struct strace_stat): Add has_nsec field.
* fetch_struct_stat.c (HAVE_NSEC): New macro.
(fetch_struct_stat): Initialize has_nsec field with HAVE_NSEC.
* fetch_struct_stat64.c (HAVE_NSEC): New macro.
(fetch_struct_stat64): Initialize has_nsec field with HAVE_NSEC.
* print_struct_stat.c (print_struct_stat) <PRINT_ST_TIME>:
Print raw values of time fields, use sprinttime_nsec to format a string
representation of time, use tprints_comment to print it as a comment.
* statx.c (SYS_FUNC(statx)) <PRINT_FIELD_TIME>: Likewise.
* utime.c (SYS_FUNC(utime)): Print raw values of struct utimbuf.actime
and struct utimbuf.modtime fields, use sprinttime to format a string
representation of time, use tprints_comment to print it as a comment.
* tests/tests.h (print_time_t_nsec): Add int argument.
* tests/print_time.c (print_time_t_ex): New function.
(print_time_t_nsec): Add int argument, turn into a thin wrapper around
print_time_t_ex.
* tests/utime.c (main): Update expected output.
* tests/xstatx.c [!IS_STATX] (HAVE_NSEC): New macro.
[!IS_STATX] (PRINT_ST_TIME), [IS_STATX] (PRINT_FIELD_TIME): Update
expected output.
* NEWS: Mention this timestamps representation improvement.
Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-21 06:16:12 +03:00
const char *
sprinttime_usec ( long long sec , unsigned long long usec )
{
return sprinttime_ex ( sec , usec , 999999 , 6 ) ;
}
const char *
sprinttime_nsec ( long long sec , unsigned long long nsec )
{
return sprinttime_ex ( sec , nsec , 999999999 , 9 ) ;
2014-12-06 06:53:16 +03:00
}
2016-07-06 18:49:22 +03:00
enum sock_proto
2016-06-17 19:29:53 +03:00
getfdproto ( struct tcb * tcp , int fd )
2014-11-22 13:03:33 +03:00
{
2015-06-17 23:09:13 +03:00
# ifdef HAVE_SYS_XATTR_H
2016-06-17 19:29:53 +03:00
size_t bufsize = 256 ;
char buf [ bufsize ] ;
2014-11-22 13:03:33 +03:00
ssize_t r ;
char path [ sizeof ( " /proc/%u/fd/%u " ) + 2 * sizeof ( int ) * 3 ] ;
if ( fd < 0 )
2016-06-17 19:29:53 +03:00
return SOCK_PROTO_UNKNOWN ;
2014-11-22 13:03:33 +03:00
2018-01-06 04:45:16 +03:00
xsprintf ( path , " /proc/%u/fd/%u " , tcp - > pid , fd ) ;
2014-11-22 13:03:33 +03:00
r = getxattr ( path , " system.sockprotoname " , buf , bufsize - 1 ) ;
if ( r < = 0 )
2016-06-17 19:29:53 +03:00
return SOCK_PROTO_UNKNOWN ;
2014-11-22 13:03:33 +03:00
else {
/*
* This is a protection for the case when the kernel
* side does not append a null byte to the buffer .
*/
buf [ r ] = ' \0 ' ;
2016-06-17 19:29:53 +03:00
return get_proto_by_name ( buf ) ;
2014-11-22 13:03:33 +03:00
}
# else
2016-06-17 19:29:53 +03:00
return SOCK_PROTO_UNKNOWN ;
2014-11-22 13:03:33 +03:00
# endif
}
2016-05-26 13:59:07 +03:00
unsigned long
getfdinode ( struct tcb * tcp , int fd )
{
char path [ PATH_MAX + 1 ] ;
if ( getfdpath ( tcp , fd , path , sizeof ( path ) ) > = 0 ) {
const char * str = STR_STRIP_PREFIX ( path , " socket:[ " ) ;
if ( str ! = path ) {
const size_t str_len = strlen ( str ) ;
if ( str_len & & str [ str_len - 1 ] = = ' ] ' )
return strtoul ( str , NULL , 10 ) ;
}
}
return 0 ;
}
2018-01-25 19:53:23 +03:00
static bool
printsocket ( struct tcb * tcp , int fd , const char * path )
{
const char * str = STR_STRIP_PREFIX ( path , " socket:[ " ) ;
size_t len ;
unsigned long inode ;
return ( str ! = path )
& & ( len = strlen ( str ) )
& & ( str [ len - 1 ] = = ' ] ' )
& & ( inode = strtoul ( str , NULL , 10 ) )
& & print_sockaddr_by_inode ( tcp , fd , inode ) ;
}
static bool
printdev ( struct tcb * tcp , int fd , const char * path )
{
struct_stat st ;
if ( path [ 0 ] ! = ' / ' )
return false ;
if ( stat_file ( path , & st ) ) {
debug_func_perror_msg ( " stat( \" %s \" ) " , path ) ;
return false ;
}
switch ( st . st_mode & S_IFMT ) {
case S_IFBLK :
case S_IFCHR :
print_quoted_string_ex ( path , strlen ( path ) ,
QUOTE_OMIT_LEADING_TRAILING_QUOTES ,
" <> " ) ;
tprintf ( " <%s %u:%u> " ,
S_ISBLK ( st . st_mode ) ? " block " : " char " ,
major ( st . st_rdev ) , minor ( st . st_rdev ) ) ;
return true ;
}
return false ;
}
Fix decoding of file descriptors
* defs.h (printfd): New function prototype.
* util.c (printfd): New function.
* file.c (print_dirfd): Update prototype to use printfd().
(sys_openat, sys_faccessat, sys_newfstatat, sys_mkdirat, sys_linkat,
sys_unlinkat, sys_readlinkat, sys_renameat, sys_fchownat, sys_fchmodat,
sys_futimesat, sys_utimensat, sys_mknodat): Update use of print_dirfd().
(sys_lseek, sys_llseek, sys_readahead, sys_ftruncate, sys_ftruncate64,
sys_fstat, sys_fstat64, sys_oldfstat, sys_fstatfs, sys_fstatfs64,
sys_fchdir, sys_fchroot, sys_linkat, sys_fchown, sys_fchmod, sys_fsync,
sys_readdir, sys_getdents, sys_getdirentries, sys_fsetxattr,
sys_fgetxattr, sys_flistxattr, sys_fremovexattr, sys_fadvise64,
sys_fadvise64_64, sys_inotify_add_watch, sys_inotify_rm_watch,
sys_fallocate): Use printfd() for decoding of file descriptors.
* desc.c (sys_fcntl, sys_flock, sys_close, sys_dup, do_dup2,
decode_select, sys_epoll_ctl, epoll_wait_common): Use printfd() for
decoding of file descriptors.
* io.c (sys_read, sys_write, sys_readv, sys_writev, sys_pread,
sys_pwrite, sys_sendfile, sys_sendfile64, sys_pread64, sys_pwrite64,
sys_ioctl): Likewise.
* mem.c (print_mmap, sys_mmap64): Likewise.
* signal.c (do_signalfd): Likewise.
* stream.c (decode_poll): Likewise.
* time.c (sys_timerfd_settime, sys_timerfd_gettime): Likewise.
Based on patch from Grant Edwards <grant.b.edwards@gmail.com>.
2011-03-04 05:08:02 +03:00
void
printfd ( struct tcb * tcp , int fd )
{
2013-03-06 21:24:34 +04:00
char path [ PATH_MAX + 1 ] ;
2014-08-21 07:17:48 +04:00
if ( show_fd_path & & getfdpath ( tcp , fd , path , sizeof ( path ) ) > = 0 ) {
2015-01-24 22:51:39 +03:00
tprintf ( " %d< " , fd ) ;
2017-06-03 20:52:24 +03:00
if ( show_fd_path < = 1
2018-01-25 19:53:23 +03:00
| | ( ! printsocket ( tcp , fd , path )
& & ! printdev ( tcp , fd , path ) ) ) {
2018-02-02 21:06:31 +03:00
print_quoted_string_ex ( path , strlen ( path ) ,
2018-01-25 19:53:23 +03:00
QUOTE_OMIT_LEADING_TRAILING_QUOTES , " <> " ) ;
2014-08-21 07:17:48 +04:00
}
2015-01-24 22:51:39 +03:00
tprints ( " > " ) ;
2014-08-21 07:17:48 +04:00
} else
2011-04-08 00:25:40 +04:00
tprintf ( " %d " , fd ) ;
Fix decoding of file descriptors
* defs.h (printfd): New function prototype.
* util.c (printfd): New function.
* file.c (print_dirfd): Update prototype to use printfd().
(sys_openat, sys_faccessat, sys_newfstatat, sys_mkdirat, sys_linkat,
sys_unlinkat, sys_readlinkat, sys_renameat, sys_fchownat, sys_fchmodat,
sys_futimesat, sys_utimensat, sys_mknodat): Update use of print_dirfd().
(sys_lseek, sys_llseek, sys_readahead, sys_ftruncate, sys_ftruncate64,
sys_fstat, sys_fstat64, sys_oldfstat, sys_fstatfs, sys_fstatfs64,
sys_fchdir, sys_fchroot, sys_linkat, sys_fchown, sys_fchmod, sys_fsync,
sys_readdir, sys_getdents, sys_getdirentries, sys_fsetxattr,
sys_fgetxattr, sys_flistxattr, sys_fremovexattr, sys_fadvise64,
sys_fadvise64_64, sys_inotify_add_watch, sys_inotify_rm_watch,
sys_fallocate): Use printfd() for decoding of file descriptors.
* desc.c (sys_fcntl, sys_flock, sys_close, sys_dup, do_dup2,
decode_select, sys_epoll_ctl, epoll_wait_common): Use printfd() for
decoding of file descriptors.
* io.c (sys_read, sys_write, sys_readv, sys_writev, sys_pread,
sys_pwrite, sys_sendfile, sys_sendfile64, sys_pread64, sys_pwrite64,
sys_ioctl): Likewise.
* mem.c (print_mmap, sys_mmap64): Likewise.
* signal.c (do_signalfd): Likewise.
* stream.c (decode_poll): Likewise.
* time.c (sys_timerfd_settime, sys_timerfd_gettime): Likewise.
Based on patch from Grant Edwards <grant.b.edwards@gmail.com>.
2011-03-04 05:08:02 +03:00
}
2008-11-11 02:19:13 +03:00
/*
* Quote string ` instr ' of length ` size '
* Write up to ( 3 + ` size ' * 4 ) bytes to ` outstr ' buffer .
2012-01-20 14:56:00 +04:00
*
2018-02-02 20:46:29 +03:00
* ` escape_chars ' specifies characters ( in addition to characters with
* codes 0. .31 , 127. .255 , single and double quotes ) that should be escaped .
*
2015-01-26 04:17:08 +03:00
* If QUOTE_0_TERMINATED ` style ' flag is set ,
* treat ` instr ' as a NUL - terminated string ,
* checking up to ( ` size ' + 1 ) bytes of ` instr ' .
*
* If QUOTE_OMIT_LEADING_TRAILING_QUOTES ` style ' flag is set ,
* do not add leading and trailing quoting symbols .
*
* Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen , 1 otherwise .
* Note that if QUOTE_0_TERMINATED is not set , always returns 1.
2008-11-11 02:19:13 +03:00
*/
Implement caching of print_sockaddr_by_inode
As -yy parser, compared to -y, needs to do at least 5 extra syscalls
(getxattr, socket, sendmsg, recvmsg, close) to print socket details,
caching results of netlink conversations between strace and kernel
noticeably reduces amount of system time spent by strace.
The caching is safe since sockets do not change their addresses after
successful bind or connect syscall.
* defs.h (string_quote, print_sockaddr_by_inode_cached): New prototypes.
* socketutils.c (cache_entry): New type.
(CACHE_SIZE, CACHE_MASK): New macros.
(cache): New static array.
(cache_and_print_inode_details): New static function.
(print_sockaddr_by_inode_cached): New function.
(inet_parse_response, unix_parse_response): Use
cache_and_print_inode_details.
* util.c (printfd): Use string_quote and print_sockaddr_by_inode_cached.
(string_quote): Remove static qualifier.
* NEWS: Mention this improvement.
* tests/unix-yy.c (main): Update.
2016-02-02 02:14:59 +03:00
int
2015-01-26 04:17:08 +03:00
string_quote ( const char * instr , char * outstr , const unsigned int size ,
2018-02-02 20:46:29 +03:00
const unsigned int style , const char * escape_chars )
1999-02-19 03:21:36 +03:00
{
2007-10-09 01:48:01 +04:00
const unsigned char * ustr = ( const unsigned char * ) instr ;
char * s = outstr ;
2015-01-26 04:17:08 +03:00
unsigned int i ;
int usehex , c , eol ;
2018-02-02 20:46:29 +03:00
bool escape ;
1999-02-19 03:21:36 +03:00
2015-01-26 04:17:08 +03:00
if ( style & QUOTE_0_TERMINATED )
2011-08-31 14:22:56 +04:00
eol = ' \0 ' ;
2015-01-26 04:17:08 +03:00
else
eol = 0x100 ; /* this can never match a char */
2011-08-31 14:22:56 +04:00
usehex = 0 ;
2017-01-06 11:55:30 +03:00
if ( ( xflag > 1 ) | | ( style & QUOTE_FORCE_HEX ) ) {
2007-10-09 01:48:01 +04:00
usehex = 1 ;
2017-01-06 11:55:30 +03:00
} else if ( xflag ) {
2008-11-11 02:19:13 +03:00
/* Check for presence of symbol which require
to hex - quote the whole string . */
2007-10-09 01:48:01 +04:00
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
2008-11-11 02:19:13 +03:00
/* Check for NUL-terminated string. */
2011-08-31 14:22:56 +04:00
if ( c = = eol )
break ;
2013-03-07 02:44:23 +04:00
/* Force hex unless c is printable or whitespace */
if ( c > 0x7e ) {
usehex = 1 ;
break ;
}
/* In ASCII isspace is only these chars: "\t\n\v\f\r".
* They happen to have ASCII codes 9 , 10 , 11 , 12 , 13.
*/
if ( c < ' ' & & ( unsigned ) ( c - 9 ) > = 5 ) {
2007-10-09 01:48:01 +04:00
usehex = 1 ;
break ;
}
}
1999-02-19 03:21:36 +03:00
}
2007-10-09 01:48:01 +04:00
2018-01-12 00:46:23 +03:00
if ( style & QUOTE_EMIT_COMMENT )
s = stpcpy ( s , " /* " ) ;
2015-01-26 04:17:08 +03:00
if ( ! ( style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ) )
* s + + = ' \" ' ;
2007-10-09 01:48:01 +04:00
if ( usehex ) {
2008-11-11 02:19:13 +03:00
/* Hex-quote the whole string. */
2007-10-09 01:48:01 +04:00
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
2008-11-11 02:19:13 +03:00
/* Check for NUL-terminated string. */
2011-08-31 14:22:56 +04:00
if ( c = = eol )
goto asciz_ended ;
* s + + = ' \\ ' ;
* s + + = ' x ' ;
* s + + = " 0123456789abcdef " [ c > > 4 ] ;
* s + + = " 0123456789abcdef " [ c & 0xf ] ;
2007-10-09 01:48:01 +04:00
}
2018-02-01 22:13:53 +03:00
goto string_ended ;
}
for ( i = 0 ; i < size ; + + i ) {
c = ustr [ i ] ;
/* Check for NUL-terminated string. */
if ( c = = eol )
goto asciz_ended ;
if ( ( i = = ( size - 1 ) ) & &
( style & QUOTE_OMIT_TRAILING_0 ) & & ( c = = ' \0 ' ) )
goto asciz_ended ;
switch ( c ) {
case ' \" ' : case ' \\ ' :
* s + + = ' \\ ' ;
* s + + = c ;
break ;
case ' \f ' :
* s + + = ' \\ ' ;
* s + + = ' f ' ;
break ;
case ' \n ' :
* s + + = ' \\ ' ;
* s + + = ' n ' ;
break ;
case ' \r ' :
* s + + = ' \\ ' ;
* s + + = ' r ' ;
break ;
case ' \t ' :
* s + + = ' \\ ' ;
* s + + = ' t ' ;
break ;
case ' \v ' :
* s + + = ' \\ ' ;
* s + + = ' v ' ;
break ;
default :
2018-02-02 20:46:29 +03:00
escape = ( c < ' ' ) | | ( c > 0x7e ) ;
if ( ! escape & & escape_chars )
escape = ! ! strchr ( escape_chars , c ) ;
if ( ! escape ) {
2018-02-01 22:08:08 +03:00
* s + + = c ;
2018-02-02 20:46:29 +03:00
} else {
2018-02-01 22:13:53 +03:00
/* Print \octal */
2018-02-01 22:08:08 +03:00
* s + + = ' \\ ' ;
2018-02-01 22:13:53 +03:00
if ( i + 1 < size
& & ustr [ i + 1 ] > = ' 0 '
2018-02-02 18:15:48 +03:00
& & ustr [ i + 1 ] < = ' 7 '
2018-02-01 22:13:53 +03:00
) {
/* Print \ooo */
* s + + = ' 0 ' + ( c > > 6 ) ;
* s + + = ' 0 ' + ( ( c > > 3 ) & 0x7 ) ;
} else {
/* Print \[[o]o]o */
if ( ( c > > 3 ) ! = 0 ) {
if ( ( c > > 6 ) ! = 0 )
* s + + = ' 0 ' + ( c > > 6 ) ;
2018-02-01 22:08:08 +03:00
* s + + = ' 0 ' + ( ( c > > 3 ) & 0x7 ) ;
2007-10-09 01:48:01 +04:00
}
2018-02-01 22:08:08 +03:00
}
2018-02-01 22:13:53 +03:00
* s + + = ' 0 ' + ( c & 0x7 ) ;
2007-10-09 01:48:01 +04:00
}
1999-02-19 03:21:36 +03:00
}
}
2018-02-01 22:13:53 +03:00
string_ended :
2015-01-26 04:17:08 +03:00
if ( ! ( style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ) )
* s + + = ' \" ' ;
2018-01-12 00:46:23 +03:00
if ( style & QUOTE_EMIT_COMMENT )
s = stpcpy ( s , " */ " ) ;
2007-10-09 01:48:01 +04:00
* s = ' \0 ' ;
2007-11-02 02:53:59 +03:00
2011-08-31 14:22:56 +04:00
/* Return zero if we printed entire ASCIZ string (didn't truncate it) */
2015-01-26 04:17:08 +03:00
if ( style & QUOTE_0_TERMINATED & & ustr [ i ] = = ' \0 ' ) {
2011-08-31 14:22:56 +04:00
/* We didn't see NUL yet (otherwise we'd jump to 'asciz_ended')
* but next char is NUL .
*/
return 0 ;
}
return 1 ;
asciz_ended :
2015-01-26 04:17:08 +03:00
if ( ! ( style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ) )
* s + + = ' \" ' ;
2018-01-12 00:46:23 +03:00
if ( style & QUOTE_EMIT_COMMENT )
s = stpcpy ( s , " */ " ) ;
2011-08-31 14:22:56 +04:00
* s = ' \0 ' ;
/* Return zero: we printed entire ASCIZ string (didn't truncate it) */
return 0 ;
1999-02-19 03:21:36 +03:00
}
2015-01-26 04:17:08 +03:00
# ifndef ALLOCA_CUTOFF
# define ALLOCA_CUTOFF 4032
# endif
# define use_alloca(n) ((n) <= ALLOCA_CUTOFF)
/*
* Quote string ` str ' of length ` size ' and print the result .
*
* If QUOTE_0_TERMINATED ` style ' flag is set ,
* treat ` str ' as a NUL - terminated string and
* quote at most ( ` size ' - 1 ) bytes .
*
* If QUOTE_OMIT_LEADING_TRAILING_QUOTES ` style ' flag is set ,
* do not add leading and trailing quoting symbols .
*
* Returns 0 if QUOTE_0_TERMINATED is set and NUL was seen , 1 otherwise .
* Note that if QUOTE_0_TERMINATED is not set , always returns 1.
*/
int
2018-02-02 20:46:29 +03:00
print_quoted_string_ex ( const char * str , unsigned int size ,
const unsigned int style , const char * escape_chars )
2015-01-26 04:17:08 +03:00
{
char * buf ;
char * outstr ;
unsigned int alloc_size ;
int rc ;
if ( size & & style & QUOTE_0_TERMINATED )
- - size ;
alloc_size = 4 * size ;
if ( alloc_size / 4 ! = size ) {
2018-04-09 18:14:40 +03:00
error_func_msg ( " requested %u bytes exceeds %u bytes limit " ,
size , - 1U / 4 ) ;
2015-01-26 04:17:08 +03:00
tprints ( " ??? " ) ;
return - 1 ;
}
2018-01-12 00:46:23 +03:00
alloc_size + = 1 + ( style & QUOTE_OMIT_LEADING_TRAILING_QUOTES ? 0 : 2 ) +
( style & QUOTE_EMIT_COMMENT ? 7 : 0 ) ;
2015-01-26 04:17:08 +03:00
if ( use_alloca ( alloc_size ) ) {
outstr = alloca ( alloc_size ) ;
buf = NULL ;
} else {
outstr = buf = malloc ( alloc_size ) ;
if ( ! buf ) {
2018-04-09 18:14:40 +03:00
error_func_msg ( " memory exhausted when tried to allocate "
" %u bytes " , alloc_size ) ;
2015-01-26 04:17:08 +03:00
tprints ( " ??? " ) ;
return - 1 ;
}
}
2018-02-02 20:46:29 +03:00
rc = string_quote ( str , outstr , size , style , escape_chars ) ;
2015-01-26 04:17:08 +03:00
tprints ( outstr ) ;
free ( buf ) ;
return rc ;
}
2018-02-02 20:46:29 +03:00
inline int
print_quoted_string ( const char * str , unsigned int size ,
const unsigned int style )
{
return print_quoted_string_ex ( str , size , style , NULL ) ;
}
2017-07-24 15:10:54 +03:00
/*
* Quote a NUL - terminated string ` str ' of length up to ` size ' - 1
* and print the result .
*
* Returns 0 if NUL was seen , 1 otherwise .
*/
int
print_quoted_cstring ( const char * str , unsigned int size )
{
int unterminated =
print_quoted_string ( str , size , QUOTE_0_TERMINATED ) ;
if ( unterminated )
tprints ( " ... " ) ;
return unterminated ;
}
2008-11-11 02:19:13 +03:00
/*
* Print path string specified by address ` addr ' and length ` n ' .
* If path length exceeds ` n ' , append ` . . . ' to the output .
2017-09-17 05:58:07 +03:00
*
* Returns the result of umovenstr .
2008-11-11 02:19:13 +03:00
*/
2017-09-17 05:58:07 +03:00
int
2016-12-26 13:26:03 +03:00
printpathn ( struct tcb * const tcp , const kernel_ulong_t addr , unsigned int n )
1999-02-19 03:21:36 +03:00
{
2017-08-01 23:59:48 +03:00
char path [ PATH_MAX ] ;
2012-01-20 14:56:00 +04:00
int nul_seen ;
2012-01-19 20:20:23 +04:00
2008-11-11 02:19:13 +03:00
if ( ! addr ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2017-09-17 05:58:07 +03:00
return - 1 ;
2007-10-09 01:48:01 +04:00
}
2012-01-20 14:56:00 +04:00
/* Cap path length to the path buffer size */
2017-06-17 21:49:58 +03:00
if ( n > sizeof ( path ) - 1 )
n = sizeof ( path ) - 1 ;
2008-11-11 02:19:13 +03:00
/* Fetch one byte more to find out whether path length > n. */
2012-01-20 14:56:00 +04:00
nul_seen = umovestr ( tcp , addr , n + 1 , path ) ;
if ( nul_seen < 0 )
2016-06-11 04:28:21 +03:00
printaddr ( addr ) ;
1999-02-19 03:21:36 +03:00
else {
2017-07-24 15:10:54 +03:00
path [ n + + ] = ! nul_seen ;
print_quoted_cstring ( path , n ) ;
1999-02-19 03:21:36 +03:00
}
2017-09-17 05:58:07 +03:00
return nul_seen ;
1999-02-19 03:21:36 +03:00
}
2017-09-17 05:58:07 +03:00
int
2016-12-26 13:26:03 +03:00
printpath ( struct tcb * const tcp , const kernel_ulong_t addr )
2007-10-09 01:48:01 +04:00
{
2012-01-19 20:20:23 +04:00
/* Size must correspond to char path[] size in printpathn */
2017-09-17 05:58:07 +03:00
return printpathn ( tcp , addr , PATH_MAX - 1 ) ;
2007-10-09 01:48:01 +04:00
}
2008-11-11 02:19:13 +03:00
/*
* Print string specified by address ` addr ' and length ` len ' .
2016-11-20 00:01:03 +03:00
* If ` user_style ' has QUOTE_0_TERMINATED bit set , treat the string
* as a NUL - terminated string .
* Pass ` user_style ' on to ` string_quote ' .
* Append ` . . . ' to the output if either the string length exceeds ` max_strlen ' ,
2016-12-24 20:35:40 +03:00
* or QUOTE_0_TERMINATED bit is set and the string length exceeds ` len ' .
2017-09-17 05:58:07 +03:00
*
* Returns the result of umovenstr if style has QUOTE_0_TERMINATED ,
* or the result of umoven otherwise .
2008-11-11 02:19:13 +03:00
*/
2017-09-17 05:58:07 +03:00
int
2016-12-26 13:26:03 +03:00
printstr_ex ( struct tcb * const tcp , const kernel_ulong_t addr ,
const kernel_ulong_t len , const unsigned int user_style )
1999-02-19 03:21:36 +03:00
{
2017-06-17 22:20:11 +03:00
static char * str ;
1999-02-19 03:21:36 +03:00
static char * outstr ;
2017-06-17 22:20:11 +03:00
2014-09-10 17:46:04 +04:00
unsigned int size ;
2016-11-19 19:33:37 +03:00
unsigned int style = user_style ;
int rc ;
2012-01-19 20:20:23 +04:00
int ellipsis ;
1999-02-19 03:21:36 +03:00
if ( ! addr ) {
2011-09-01 12:00:28 +04:00
tprints ( " NULL " ) ;
2017-09-17 05:58:07 +03:00
return - 1 ;
1999-02-19 03:21:36 +03:00
}
2008-11-11 02:19:13 +03:00
/* Allocate static buffers if they are not allocated yet. */
2011-08-31 16:00:02 +04:00
if ( ! str ) {
2017-06-27 01:30:19 +03:00
const unsigned int outstr_size =
4 * max_strlen + /* for quotes and NUL */ 3 ;
/*
* We can assume that outstr_size / 4 = = max_strlen
* since we have a guarantee that max_strlen < = - 1U / 4.
*/
2012-03-26 02:56:53 +04:00
Introduce memory allocation wrappers
Introduce wrappers to the following functions that do memory allocation:
malloc, calloc, realloc, strdup.
This commit is a follow-up to the related discussions in strace-devel ML:
http://sourceforge.net/p/strace/mailman/message/33618180/
http://sourceforge.net/p/strace/mailman/message/33733470/
* defs.h (xmalloc, xcalloc, xreallocarray, xstrdup): New prototypes.
* xmalloc.c: New file.
* Makefile.am (strace_SOURCES): Add it.
* count.c (count_syscall, call_summary_pers): Use xcalloc.
* desc.c (decode_select): Use xmalloc.
* dirent.c (sys_getdents, sys_getdents64): Likewise.
* net.c (sys_recvmmsg): Use xstrdup.
* pathtrace.c (storepath): Use xreallocarray.
(pathtrace_match): Use xmalloc.
* strace.c (die_out_of_memory): Move to xmalloc.c.
(expand_tcbtab): Use xcalloc and xreallocarray.
(startup_child): Use xstrdup.
(init): Use xmalloc, xcalloc, and xstrdup.
* syscall.c (reallocate_qual): Use xreallocarray.
(qualify): Use xstrdup.
* unwind.c (unwind_tcb_init): Use xmalloc.
(build_mmap_cache): Use xcalloc, xreallocarray, and xstrdup.
(get_symbol_name): Use xreallocarray.
(stacktrace_walk, queue_put): Use xmalloc.
* util.c (printstr): Use xmalloc.
* vsprintf.c (strace_vfprintf): Likewise.
2015-05-25 23:41:02 +03:00
str = xmalloc ( max_strlen + 1 ) ;
outstr = xmalloc ( outstr_size ) ;
1999-02-19 03:21:36 +03:00
}
2007-10-09 01:48:01 +04:00
2016-12-24 20:35:40 +03:00
/* Fetch one byte more because string_quote may look one byte ahead. */
2016-10-10 19:55:54 +03:00
size = max_strlen + 1 ;
2016-12-24 20:35:40 +03:00
2016-12-24 22:24:37 +03:00
if ( size > len )
size = len ;
2016-12-24 20:35:40 +03:00
if ( style & QUOTE_0_TERMINATED )
2016-11-19 19:33:37 +03:00
rc = umovestr ( tcp , addr , size , str ) ;
2016-12-24 20:35:40 +03:00
else
rc = umoven ( tcp , addr , size , str ) ;
2016-11-19 19:33:37 +03:00
if ( rc < 0 ) {
printaddr ( addr ) ;
2017-09-17 05:58:07 +03:00
return rc ;
1999-02-19 03:21:36 +03:00
}
2016-10-10 19:55:54 +03:00
if ( size > max_strlen )
size = max_strlen ;
2016-11-20 03:29:46 +03:00
else
str [ size ] = ' \xff ' ;
2016-10-10 19:55:54 +03:00
2012-01-20 14:56:00 +04:00
/* If string_quote didn't see NUL and (it was supposed to be ASCIZ str
* or we were requested to print more than - s NUM chars ) . . .
*/
2018-02-02 20:46:29 +03:00
ellipsis = string_quote ( str , outstr , size , style , NULL )
2016-11-20 03:29:46 +03:00
& & len
& & ( ( style & QUOTE_0_TERMINATED )
2016-12-24 22:24:37 +03:00
| | len > max_strlen ) ;
1999-02-19 03:21:36 +03:00
2012-01-19 20:20:23 +04:00
tprints ( outstr ) ;
if ( ellipsis )
tprints ( " ... " ) ;
2017-09-17 05:58:07 +03:00
return rc ;
1999-02-19 03:21:36 +03:00
}
2001-07-10 17:48:44 +04:00
void
2016-12-26 13:26:03 +03:00
dumpiov_upto ( struct tcb * const tcp , const int len , const kernel_ulong_t addr ,
kernel_ulong_t data_size )
2001-07-10 17:48:44 +04:00
{
2016-12-26 23:12:23 +03:00
# if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
2006-12-13 20:08:08 +03:00
union {
Replace u_int{8,16,32,64} with uint{8,16,32,64}
* util.c: Replace u_int{32,64} with uint{32,64}.
* quota.c: Replace u_int{8,16,32,64} with uint{8,16,32,64}.
2016-01-17 01:50:09 +03:00
struct { uint32_t base ; uint32_t len ; } * iov32 ;
struct { uint64_t base ; uint64_t len ; } * iov64 ;
2006-12-13 20:08:08 +03:00
} iovu ;
2018-12-30 18:35:21 +03:00
# define iov iovu.iov64
# define sizeof_iov \
2018-04-09 18:14:40 +03:00
( current_wordsize = = 4 ? ( unsigned int ) sizeof ( * iovu . iov32 ) \
: ( unsigned int ) sizeof ( * iovu . iov64 ) )
2018-12-30 18:35:21 +03:00
# define iov_iov_base(i) \
2012-03-19 12:36:42 +04:00
( current_wordsize = = 4 ? ( uint64_t ) iovu . iov32 [ i ] . base : iovu . iov64 [ i ] . base )
2018-12-30 18:35:21 +03:00
# define iov_iov_len(i) \
2012-03-19 12:36:42 +04:00
( current_wordsize = = 4 ? ( uint64_t ) iovu . iov32 [ i ] . len : iovu . iov64 [ i ] . len )
2006-12-13 20:08:08 +03:00
# else
2001-07-10 17:48:44 +04:00
struct iovec * iov ;
2018-12-30 18:35:21 +03:00
# define sizeof_iov ((unsigned int) sizeof(*iov))
# define iov_iov_base(i) ptr_to_kulong(iov[i].iov_base)
# define iov_iov_len(i) iov[i].iov_len
2006-12-13 20:08:08 +03:00
# endif
2001-07-10 17:48:44 +04:00
int i ;
2018-04-09 18:14:40 +03:00
unsigned int size = sizeof_iov * len ;
if ( size / sizeof_iov ! = ( unsigned int ) len ) {
error_func_msg ( " requested %u iovec elements exceeds "
" %u iovec limit " , len , - 1U / sizeof_iov ) ;
return ;
}
2001-07-10 17:48:44 +04:00
2018-04-09 18:14:40 +03:00
iov = malloc ( size ) ;
if ( ! iov ) {
error_func_msg ( " memory exhausted when tried to allocate "
" %u bytes " , size ) ;
2011-09-01 18:35:44 +04:00
return ;
2001-07-10 17:48:44 +04:00
}
2015-03-21 21:50:53 +03:00
if ( umoven ( tcp , addr , size , iov ) > = 0 ) {
2001-07-10 17:48:44 +04:00
for ( i = 0 ; i < len ; i + + ) {
2016-12-26 13:26:03 +03:00
kernel_ulong_t iov_len = iov_iov_len ( i ) ;
2016-01-20 03:17:02 +03:00
if ( iov_len > data_size )
iov_len = data_size ;
if ( ! iov_len )
break ;
data_size - = iov_len ;
2008-12-30 21:47:55 +03:00
/* include the buffer number to make it easy to
* match up the trace with the source */
2016-12-26 13:16:35 +03:00
tprintf ( " * % " PRI_klu " bytes in buffer %d \n " , iov_len , i ) ;
2016-12-26 04:37:21 +03:00
dumpstr ( tcp , iov_iov_base ( i ) , iov_len ) ;
2008-12-30 21:47:55 +03:00
}
2001-07-10 17:48:44 +04:00
}
2011-09-01 18:35:44 +04:00
free ( iov ) ;
2006-12-13 20:08:08 +03:00
# undef sizeof_iov
# undef iov_iov_base
# undef iov_iov_len
# undef iov
2001-07-10 17:48:44 +04:00
}
1999-02-19 03:21:36 +03:00
void
2016-12-26 13:26:03 +03:00
dumpstr ( struct tcb * const tcp , const kernel_ulong_t addr , const int len )
1999-02-19 03:21:36 +03:00
{
static int strsize = - 1 ;
static unsigned char * str ;
2013-02-22 17:47:39 +04:00
char outbuf [
(
( sizeof (
" xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx xx "
" 1234567890123456 " ) + /*in case I'm off by few:*/ 4 )
/*align to 8 to make memset easier:*/ + 7 ) & - 8
] ;
const unsigned char * src ;
int i ;
2018-05-02 21:57:58 +03:00
if ( ( len < 0 ) | | ( len > INT_MAX - 16 ) )
return ;
2013-02-22 17:47:39 +04:00
memset ( outbuf , ' ' , sizeof ( outbuf ) ) ;
if ( strsize < len + 16 ) {
2011-08-20 14:48:18 +04:00
free ( str ) ;
2013-02-22 17:47:39 +04:00
str = malloc ( len + 16 ) ;
2011-09-01 18:35:44 +04:00
if ( ! str ) {
strsize = - 1 ;
2018-04-09 18:14:40 +03:00
error_func_msg ( " memory exhausted when tried to allocate "
" %zu bytes " , ( size_t ) ( len + 16 ) ) ;
2011-09-01 18:35:44 +04:00
return ;
}
2013-02-22 17:47:39 +04:00
strsize = len + 16 ;
1999-02-19 03:21:36 +03:00
}
2015-03-21 21:50:53 +03:00
if ( umoven ( tcp , addr , len , str ) < 0 )
1999-02-19 03:21:36 +03:00
return ;
2013-02-22 17:47:39 +04:00
/* Space-pad to 16 bytes */
i = len ;
while ( i & 0xf )
str [ i + + ] = ' ' ;
i = 0 ;
src = str ;
while ( i < len ) {
char * dst = outbuf ;
/* Hex dump */
do {
if ( i < len ) {
* dst + + = " 0123456789abcdef " [ * src > > 4 ] ;
* dst + + = " 0123456789abcdef " [ * src & 0xf ] ;
2017-06-18 01:23:09 +03:00
} else {
2013-02-22 17:47:39 +04:00
* dst + + = ' ' ;
* dst + + = ' ' ;
1999-02-19 03:21:36 +03:00
}
2013-02-22 17:47:39 +04:00
dst + + ; /* space is there by memset */
i + + ;
if ( ( i & 7 ) = = 0 )
dst + + ; /* space is there by memset */
src + + ;
} while ( i & 0xf ) ;
/* ASCII dump */
i - = 16 ;
src - = 16 ;
do {
if ( * src > = ' ' & & * src < 0x7f )
* dst + + = * src ;
1999-02-19 03:21:36 +03:00
else
2013-02-22 17:47:39 +04:00
* dst + + = ' . ' ;
src + + ;
} while ( + + i & 0xf ) ;
* dst = ' \0 ' ;
2013-02-22 18:00:11 +04:00
tprintf ( " | %05x %s | \n " , i - 16 , outbuf ) ;
1999-02-19 03:21:36 +03:00
}
}
2018-05-28 14:32:03 +03:00
bool
tfetch_mem64 ( struct tcb * const tcp , const uint64_t addr ,
const unsigned int len , void * const our_addr )
{
return addr & & verbose ( tcp ) & &
( entering ( tcp ) | | ! syserror ( tcp ) ) & &
! umoven ( tcp , addr , len , our_addr ) ;
}
bool
tfetch_mem64_ignore_syserror ( struct tcb * const tcp , const uint64_t addr ,
const unsigned int len , void * const our_addr )
{
return addr & & verbose ( tcp ) & &
! umoven ( tcp , addr , len , our_addr ) ;
}
2015-07-06 01:09:29 +03:00
int
2018-03-25 12:54:18 +03:00
umoven_or_printaddr64 ( struct tcb * const tcp , const uint64_t addr ,
const unsigned int len , void * const our_addr )
2015-07-06 01:09:29 +03:00
{
2018-05-28 14:32:03 +03:00
if ( tfetch_mem64 ( tcp , addr , len , our_addr ) )
return 0 ;
printaddr64 ( addr ) ;
return - 1 ;
2015-07-06 01:09:29 +03:00
}
2016-10-15 02:27:21 +03:00
int
2018-03-25 12:54:18 +03:00
umoven_or_printaddr64_ignore_syserror ( struct tcb * const tcp ,
2018-05-28 14:32:03 +03:00
const uint64_t addr ,
const unsigned int len ,
void * const our_addr )
2016-10-15 02:27:21 +03:00
{
2018-05-28 14:32:03 +03:00
if ( tfetch_mem64_ignore_syserror ( tcp , addr , len , our_addr ) )
return 0 ;
printaddr64 ( addr ) ;
return - 1 ;
2016-10-15 02:27:21 +03:00
}
2018-05-07 09:04:21 +03:00
bool
print_int32_array_member ( struct tcb * tcp , void * elem_buf , size_t elem_size ,
void * data )
{
tprintf ( " % " PRId32 , * ( int32_t * ) elem_buf ) ;
return true ;
}
2018-05-10 20:35:46 +03:00
bool
print_uint32_array_member ( struct tcb * tcp , void * elem_buf , size_t elem_size ,
void * data )
{
tprintf ( " % " PRIu32 , * ( uint32_t * ) elem_buf ) ;
return true ;
}
2018-03-05 12:20:02 +03:00
bool
print_uint64_array_member ( struct tcb * tcp , void * elem_buf , size_t elem_size ,
void * data )
{
tprintf ( " % " PRIu64 , * ( uint64_t * ) elem_buf ) ;
return true ;
}
2016-05-07 02:26:43 +03:00
/*
* Iteratively fetch and print up to nmemb elements of elem_size size
* from the array that starts at tracee ' s address start_addr .
*
* Array elements are being fetched to the address specified by elem_buf .
*
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 04:15:19 +03:00
* The fetcher callback function specified by tfetch_mem_func should follow
* the same semantics as tfetch_mem function .
2016-05-07 02:26:43 +03:00
*
* The printer callback function specified by print_func is expected
* to print something ; if it returns false , no more iterations will be made .
*
* The pointer specified by opaque_data is passed to each invocation
* of print_func callback function .
*
* This function prints :
* - " NULL " , if start_addr is NULL ;
* - " [] " , if nmemb is 0 ;
* - start_addr , if nmemb * elem_size overflows or wraps around ;
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 04:15:19 +03:00
* - start_addr , if the first tfetch_mem_func invocation returned false ;
2016-05-07 02:26:43 +03:00
* - elements of the array , delimited by " , " , with the array itself
* enclosed with [ ] brackets .
*
* If abbrev ( tcp ) is true , then
* - the maximum number of elements printed equals to max_strlen ;
* - " ... " is printed instead of max_strlen + 1 element
* and no more iterations will be made .
*
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 04:15:19 +03:00
* This function returns true only if tfetch_mem_func has returned true
* at least once .
2016-05-07 02:26:43 +03:00
*/
bool
print_array: add support for printing array indices
* defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants.
(tfetch_mem_fn, print_fn): New typedefs.
(enum print_array_flag_bits, enum print_array_flags): New enumerations.
(print_array_ex): Rename from print_array, add flags, index_xlat,
index_xlat_size, and index_dflt arguments.
(print_array): New static inline function, a thin wrapper around
print_array_ex.
util.c: Include "xlat.h".
(print_array): Rename to print_array_ex, add flags, index_xlat,
index_xlat_size, and index_dflt arguments. Print array indices
according to the style settings specified by flags if PAF_PRINT_INDICES
is set.
2018-05-07 09:06:14 +03:00
print_array_ex ( struct tcb * const tcp ,
const kernel_ulong_t start_addr ,
const size_t nmemb ,
void * const elem_buf ,
const size_t elem_size ,
tfetch_mem_fn tfetch_mem_func ,
print_fn print_func ,
void * const opaque_data ,
unsigned int flags ,
const struct xlat * index_xlat ,
size_t index_xlat_size ,
const char * index_dflt )
2016-05-07 02:26:43 +03:00
{
if ( ! start_addr ) {
tprints ( " NULL " ) ;
return false ;
}
if ( ! nmemb ) {
tprints ( " [] " ) ;
return false ;
}
const size_t size = nmemb * elem_size ;
2016-12-26 13:26:03 +03:00
const kernel_ulong_t end_addr = start_addr + size ;
2016-05-07 02:26:43 +03:00
if ( end_addr < = start_addr | | size / elem_size ! = nmemb ) {
printaddr ( start_addr ) ;
return false ;
}
2016-12-26 13:26:03 +03:00
const kernel_ulong_t abbrev_end =
2016-05-07 02:26:43 +03:00
( abbrev ( tcp ) & & max_strlen < nmemb ) ?
start_addr + elem_size * max_strlen : end_addr ;
2016-12-26 13:26:03 +03:00
kernel_ulong_t cur ;
print_array: add support for printing array indices
* defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants.
(tfetch_mem_fn, print_fn): New typedefs.
(enum print_array_flag_bits, enum print_array_flags): New enumerations.
(print_array_ex): Rename from print_array, add flags, index_xlat,
index_xlat_size, and index_dflt arguments.
(print_array): New static inline function, a thin wrapper around
print_array_ex.
util.c: Include "xlat.h".
(print_array): Rename to print_array_ex, add flags, index_xlat,
index_xlat_size, and index_dflt arguments. Print array indices
according to the style settings specified by flags if PAF_PRINT_INDICES
is set.
2018-05-07 09:06:14 +03:00
kernel_ulong_t idx = 0 ;
enum xlat_style xlat_style = flags & XLAT_STYLE_MASK ;
2016-05-07 02:26:43 +03:00
print_array: add support for printing array indices
* defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants.
(tfetch_mem_fn, print_fn): New typedefs.
(enum print_array_flag_bits, enum print_array_flags): New enumerations.
(print_array_ex): Rename from print_array, add flags, index_xlat,
index_xlat_size, and index_dflt arguments.
(print_array): New static inline function, a thin wrapper around
print_array_ex.
util.c: Include "xlat.h".
(print_array): Rename to print_array_ex, add flags, index_xlat,
index_xlat_size, and index_dflt arguments. Print array indices
according to the style settings specified by flags if PAF_PRINT_INDICES
is set.
2018-05-07 09:06:14 +03:00
for ( cur = start_addr ; cur < end_addr ; cur + = elem_size , idx + + ) {
2016-05-07 02:26:43 +03:00
if ( cur ! = start_addr )
tprints ( " , " ) ;
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 04:15:19 +03:00
if ( ! tfetch_mem_func ( tcp , cur , elem_size , elem_buf ) ) {
if ( cur = = start_addr )
printaddr ( cur ) ;
else {
tprints ( " ... " ) ;
printaddr_comment ( cur ) ;
}
2016-05-07 02:26:43 +03:00
break ;
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 04:15:19 +03:00
}
2016-05-07 02:26:43 +03:00
if ( cur = = start_addr )
tprints ( " [ " ) ;
if ( cur > = abbrev_end ) {
tprints ( " ... " ) ;
cur = end_addr ;
break ;
}
print_array: add support for printing array indices
* defs.h (XLAT_STYLE_SPEC_BITS, XLAT_STYLE_MASK): New macro constants.
(tfetch_mem_fn, print_fn): New typedefs.
(enum print_array_flag_bits, enum print_array_flags): New enumerations.
(print_array_ex): Rename from print_array, add flags, index_xlat,
index_xlat_size, and index_dflt arguments.
(print_array): New static inline function, a thin wrapper around
print_array_ex.
util.c: Include "xlat.h".
(print_array): Rename to print_array_ex, add flags, index_xlat,
index_xlat_size, and index_dflt arguments. Print array indices
according to the style settings specified by flags if PAF_PRINT_INDICES
is set.
2018-05-07 09:06:14 +03:00
if ( flags & PAF_PRINT_INDICES ) {
tprints ( " [ " ) ;
if ( ! index_xlat ) {
print_xlat_ex ( idx , NULL , xlat_style ) ;
} else if ( flags & PAF_INDEX_XLAT_VALUE_INDEXED ) {
printxval_indexn_ex ( index_xlat ,
index_xlat_size , idx ,
index_dflt , xlat_style ) ;
} else {
printxvals_ex ( idx , index_dflt , xlat_style ,
( flags & PAF_INDEX_XLAT_SORTED )
& & idx ? NULL : index_xlat ,
NULL ) ;
}
tprints ( " ] = " ) ;
}
2016-05-07 02:26:43 +03:00
if ( ! print_func ( tcp , elem_buf , elem_size , opaque_data ) ) {
cur = end_addr ;
break ;
}
}
if ( cur ! = start_addr )
tprints ( " ] " ) ;
return cur > = end_addr ;
}
2016-06-12 16:39:02 +03:00
2016-09-22 00:21:27 +03:00
int
printargs ( struct tcb * tcp )
{
2016-11-27 17:19:09 +03:00
const int n = tcp - > s_ent - > nargs ;
int i ;
for ( i = 0 ; i < n ; + + i )
2016-12-26 05:28:04 +03:00
tprintf ( " %s%# " PRI_klx , i ? " , " : " " , tcp - > u_arg [ i ] ) ;
2016-11-27 17:19:09 +03:00
return RVAL_DECODED ;
2016-06-12 16:39:02 +03:00
}
int
printargs_u ( struct tcb * tcp )
{
const int n = tcp - > s_ent - > nargs ;
int i ;
for ( i = 0 ; i < n ; + + i )
tprintf ( " %s%u " , i ? " , " : " " ,
( unsigned int ) tcp - > u_arg [ i ] ) ;
return RVAL_DECODED ;
}
int
printargs_d ( struct tcb * tcp )
{
const int n = tcp - > s_ent - > nargs ;
int i ;
for ( i = 0 ; i < n ; + + i )
tprintf ( " %s%d " , i ? " , " : " " ,
( int ) tcp - > u_arg [ i ] ) ;
return RVAL_DECODED ;
}
2016-07-04 01:15:45 +03:00
2017-03-29 20:55:35 +03:00
/* Print abnormal high bits of a kernel_ulong_t value. */
void
print_abnormal_hi ( const kernel_ulong_t val )
{
if ( current_klongsize > 4 ) {
const unsigned int hi = ( unsigned int ) ( ( uint64_t ) val > > 32 ) ;
if ( hi )
tprintf ( " %#x<<32| " , hi ) ;
}
}
2016-07-04 01:15:45 +03:00
# if defined _LARGEFILE64_SOURCE && defined HAVE_OPEN64
# define open_file open64
# else
# define open_file open
# endif
int
2017-12-26 01:55:22 +03:00
read_int_from_file ( struct tcb * tcp , const char * const fname , int * const pvalue )
2016-07-04 01:15:45 +03:00
{
const int fd = open_file ( fname , O_RDONLY ) ;
if ( fd < 0 )
return - 1 ;
long lval ;
char buf [ sizeof ( lval ) * 3 ] ;
int n = read ( fd , buf , sizeof ( buf ) - 1 ) ;
int saved_errno = errno ;
close ( fd ) ;
if ( n < 0 ) {
errno = saved_errno ;
return - 1 ;
}
buf [ n ] = ' \0 ' ;
char * endptr = 0 ;
errno = 0 ;
lval = strtol ( buf , & endptr , 10 ) ;
if ( ! endptr | | ( * endptr & & ' \n ' ! = * endptr )
# if INT_MAX < LONG_MAX
| | lval > INT_MAX | | lval < INT_MIN
# endif
| | ERANGE = = errno ) {
if ( ! errno )
errno = EINVAL ;
return - 1 ;
}
* pvalue = ( int ) lval ;
return 0 ;
}