strace/defs.h

1375 lines
43 KiB
C
Raw Normal View History

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>
* Copyright (c) 2001-2018 The strace developers.
1999-02-19 03:21:36 +03:00
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef STRACE_DEFS_H
#define STRACE_DEFS_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <features.h>
#include <stdbool.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/types.h>
#include <stddef.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
/* Open-coding isprint(ch) et al proved more efficient than calling
* generalized libc interface. We don't *want* to do non-ASCII anyway.
*/
/* #include <ctype.h> */
#include <string.h>
#include <errno.h>
#include <time.h>
#include <sys/time.h>
#include "arch_defs.h"
#include "error_prints.h"
#include "gcc_compat.h"
#include "kernel_types.h"
#include "macros.h"
#include "mpers_type.h"
#include "string_to_uint.h"
#include "sysent.h"
#include "xmalloc.h"
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#ifndef HAVE_STRERROR
const char *strerror(int);
#endif
#ifndef HAVE_STPCPY
/* Some libc have stpcpy, some don't. Sigh...
* Roll our private implementation...
*/
#undef stpcpy
#define stpcpy strace_stpcpy
extern char *stpcpy(char *dst, const char *src);
#endif
/* Glibc has an efficient macro for sigemptyset
* (it just does one or two assignments of 0 to internal vector of longs).
*/
#if defined(__GLIBC__) && defined(__sigemptyset) && !defined(sigemptyset)
# define sigemptyset __sigemptyset
#endif
Set saner MAX_ARGS (6 or 8) for X86_64 and I386 I noticed that tcp->u_args[MAX_ARGS] array is way larger than I'd expect: for all arches except HPPA it has 32 (!) elements. I looked at the code and so far I spotted only one abuser of this fact: sys_sigreturn. On several arches, it saves sigset_t into tcp->u_args[1...N] on entry and prints it on exit, a-la memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t)) The problem here is that in glibc sigset_t is insanely large: 128 bytes, and using sizeof(sigset_t) in memcpy will overrun &tcp->u_args[1] even with MAX_ARGS == 32: On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes! We may already have a bug there! This commit changes the code to save NSIG / 8 bytes only. NSIG can't ever be > 256, and in practice is <= 129, thus NSIG / 8 is <= 16 bytes == 4 32-bit words, and even MAX_ARGS == 5 should be enough for saving signal masks. * defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8 for FreeBSD and to 6 for everyone else. Add comment about current state of needed MAX_ARGS. * signal.c: Add comment about size of sigset_t. (sprintsigmask): Reduce static string buffer from 8k to 2k. (sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes, not sizeof(sigset_t) bytes. * linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7. * linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/powerpc/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/s390x/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
/* Configuration section */
1999-02-19 03:21:36 +03:00
#ifndef DEFAULT_STRLEN
/* default maximum # of bytes printed in `printstr', change with -s switch */
# define DEFAULT_STRLEN 32
1999-02-19 03:21:36 +03:00
#endif
#ifndef DEFAULT_ACOLUMN
# define DEFAULT_ACOLUMN 40 /* default alignment column for results */
1999-02-19 03:21:36 +03:00
#endif
/*
* Maximum number of args to a syscall.
Set saner MAX_ARGS (6 or 8) for X86_64 and I386 I noticed that tcp->u_args[MAX_ARGS] array is way larger than I'd expect: for all arches except HPPA it has 32 (!) elements. I looked at the code and so far I spotted only one abuser of this fact: sys_sigreturn. On several arches, it saves sigset_t into tcp->u_args[1...N] on entry and prints it on exit, a-la memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t)) The problem here is that in glibc sigset_t is insanely large: 128 bytes, and using sizeof(sigset_t) in memcpy will overrun &tcp->u_args[1] even with MAX_ARGS == 32: On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes! We may already have a bug there! This commit changes the code to save NSIG / 8 bytes only. NSIG can't ever be > 256, and in practice is <= 129, thus NSIG / 8 is <= 16 bytes == 4 32-bit words, and even MAX_ARGS == 5 should be enough for saving signal masks. * defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8 for FreeBSD and to 6 for everyone else. Add comment about current state of needed MAX_ARGS. * signal.c: Add comment about size of sigset_t. (sprintsigmask): Reduce static string buffer from 8k to 2k. (sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes, not sizeof(sigset_t) bytes. * linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7. * linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/powerpc/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/s390x/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
*
* Make sure that all entries in all syscallent.h files have nargs <= MAX_ARGS!
* linux/<ARCH>/syscallent*.h:
* all have nargs <= 6 except mips o32 which has nargs <= 7.
Set saner MAX_ARGS (6 or 8) for X86_64 and I386 I noticed that tcp->u_args[MAX_ARGS] array is way larger than I'd expect: for all arches except HPPA it has 32 (!) elements. I looked at the code and so far I spotted only one abuser of this fact: sys_sigreturn. On several arches, it saves sigset_t into tcp->u_args[1...N] on entry and prints it on exit, a-la memcpy(&tcp->u_arg[1], &sc.oldmask[0], sizeof(sigset_t)) The problem here is that in glibc sigset_t is insanely large: 128 bytes, and using sizeof(sigset_t) in memcpy will overrun &tcp->u_args[1] even with MAX_ARGS == 32: On 32 bits, sizeof(tcp->u_args) == 32*4 == 128 bytes! We may already have a bug there! This commit changes the code to save NSIG / 8 bytes only. NSIG can't ever be > 256, and in practice is <= 129, thus NSIG / 8 is <= 16 bytes == 4 32-bit words, and even MAX_ARGS == 5 should be enough for saving signal masks. * defs.h: Reduce MAX_ARGS for X86_64 and I386 from 32 to 8 for FreeBSD and to 6 for everyone else. Add comment about current state of needed MAX_ARGS. * signal.c: Add comment about size of sigset_t. (sprintsigmask): Reduce static string buffer from 8k to 2k. (sys_sigreturn): Fix sigset saving to save only NSIG / 8 bytes, not sizeof(sigset_t) bytes. * linux/mips/syscallent.h: Reduce nargs of printargs-type syscall to 7. * linux/arm/syscallent.h: Reduce nargs of printargs-type syscall to 6. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/powerpc/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/s390x/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
2011-08-19 19:41:28 +04:00
*/
1999-02-19 03:21:36 +03:00
#ifndef MAX_ARGS
# ifdef LINUX_MIPSO32
# define MAX_ARGS 7
# else
# define MAX_ARGS 6
# endif
1999-02-19 03:21:36 +03:00
#endif
/* default sorting method for call profiling */
1999-02-19 03:21:36 +03:00
#ifndef DEFAULT_SORTBY
# define DEFAULT_SORTBY "time"
#endif
/* To force NOMMU build, set to 1 */
#define NOMMU_SYSTEM 0
#ifndef ERESTARTSYS
# define ERESTARTSYS 512
#endif
#ifndef ERESTARTNOINTR
# define ERESTARTNOINTR 513
#endif
#ifndef ERESTARTNOHAND
# define ERESTARTNOHAND 514
#endif
#ifndef ERESTART_RESTARTBLOCK
# define ERESTART_RESTARTBLOCK 516
#endif
#define PERSONALITY0_WORDSIZE SIZEOF_LONG
#define PERSONALITY0_KLONGSIZE SIZEOF_KERNEL_LONG_T
#define PERSONALITY0_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
#define PERSONALITY0_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#if SUPPORTED_PERSONALITIES > 1
# define PERSONALITY1_WORDSIZE 4
# define PERSONALITY1_KLONGSIZE PERSONALITY1_WORDSIZE
#endif
#if SUPPORTED_PERSONALITIES > 2
# define PERSONALITY2_WORDSIZE 4
# define PERSONALITY2_KLONGSIZE PERSONALITY0_KLONGSIZE
#endif
#if SUPPORTED_PERSONALITIES > 1 && defined HAVE_M32_MPERS
# define PERSONALITY1_INCLUDE_PRINTERS_DECLS "m32_printer_decls.h"
# define PERSONALITY1_INCLUDE_PRINTERS_DEFS "m32_printer_defs.h"
# define PERSONALITY1_INCLUDE_FUNCS "m32_funcs.h"
# define MPERS_m32_IOCTL_MACROS "ioctl_redefs1.h"
# define HAVE_PERSONALITY_1_MPERS 1
#else
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
# define PERSONALITY1_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
# define PERSONALITY1_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
# define PERSONALITY1_INCLUDE_FUNCS "empty.h"
# define HAVE_PERSONALITY_1_MPERS 0
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#endif
#if SUPPORTED_PERSONALITIES > 2 && defined HAVE_MX32_MPERS
# define PERSONALITY2_INCLUDE_FUNCS "mx32_funcs.h"
# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "mx32_printer_decls.h"
# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "mx32_printer_defs.h"
# define MPERS_mx32_IOCTL_MACROS "ioctl_redefs2.h"
# define HAVE_PERSONALITY_2_MPERS 1
#else
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
# define PERSONALITY2_INCLUDE_PRINTERS_DECLS "native_printer_decls.h"
# define PERSONALITY2_INCLUDE_PRINTERS_DEFS "native_printer_defs.h"
# define PERSONALITY2_INCLUDE_FUNCS "empty.h"
# define HAVE_PERSONALITY_2_MPERS 0
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#endif
#ifdef WORDS_BIGENDIAN
# define is_bigendian true
#else
# define is_bigendian false
#endif
typedef struct ioctlent {
Eliminate many SCNO_IS_VALID checks By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-21 19:13:47 +04:00
const char *symbol;
unsigned int code;
} struct_ioctlent;
Eliminate many SCNO_IS_VALID checks By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-21 19:13:47 +04:00
#define INJECT_F_SIGNAL 0x01
#define INJECT_F_ERROR 0x02
#define INJECT_F_RETVAL 0x04
#define INJECT_F_DELAY_ENTER 0x08
#define INJECT_F_DELAY_EXIT 0x10
struct inject_data {
uint8_t flags; /* 5 of 8 flags are used so far */
uint8_t signo; /* NSIG <= 128 */
uint16_t rval_idx; /* index in retval_vec */
Implement delay injection Add -e inject=SET:delay_enter= and -e inject=SET:delay_exit= options. * configure.ac (AC_SEARCH_LIBS): Check for timer_create -lrt. * delay.c: New file. * Makefile.am (strace_SOURCES): Add it. (strace_LDADD): Add $(timer_LIBS). * defs.h (INJECT_F_DELAY_ENTER, INJECT_F_DELAY_EXIT, TCB_INJECT_DELAY_EXIT, TCB_DELAYED, inject_delay_exit, syscall_delayed): New macros. (alloc_delay_data, fill_delay_data, is_delay_timer_created, arm_delay_timer, delay_tcb): New prototypes. (struct inject_data): Replace reserved field with delay_idx. (struct tcb): Add delay_expiration_time field. * filter_qualify.c (parse_delay_token): New function. (parse_inject_token): Use it. (qualify_inject_common): Initialize struct inject_opts.data.delay_idx. * strace.c: Include <setjmp.h> (timer_jmp_buf, timer_set): New static variables. (timer_sighandler, restart_delayed_tcb, restart_delayed_tcbs): New functions. (init): Block SIGALRM, set SIGALRM handler. (dispatch_event): Do not restart delayed syscalls. (next_event): Unblock SIGALRM during wait4 invocation. * syscall.c (tamper_with_syscall_entering): Arm delay timer if INJECT_F_DELAY_ENTER injection flag is set, set TCB_INJECT_DELAY_EXIT flag if INJECT_F_DELAY_EXIT injection flag is set. tamper_with_syscall_exiting): Arm delay timer if inject_delay_exit. (syscall_exiting_trace): Call tamper_with_syscall_exiting in case of inject_delay_exit. (syscall_exiting_finish): Clear TCB_INJECT_DELAY_EXIT flag. * strace.1.in: Document delay injection. * NEWS: Mention this improvement. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-02-18 23:21:48 +03:00
uint16_t delay_idx; /* index in delay_data_vec */
};
struct inject_opts {
Rewrite remaining qual_* parsers using bit sets * defs.h (struct fault_opts): Replace forward declaration with a definition. (qualbits_t, qualify_read, qualify_write, qualify_signals): Remove. (qual_flags): New function prototype. (nsyscall_vec, sysent_vec, fault_vec): New variable prototypes. * qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set): New variables. (qualify_read, qualify_write, qualify_signals): Add static qualifier. (find_errno_by_name, lookup_class, parse_fault_expression, parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault, qualify_raw, qualify_syscall, qualify_syscall_class, qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens, qualify_trace, qualify_verbose, strip_prefix): New functions. * syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier. (MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags, qual_fault, qual_syscall, qual_options, fault_opts, qualify_one, qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name, qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name, parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove. (decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall, get_scno): Update use of qual_flags. (inject_syscall_fault_entering): Update per-personality allocation of tcp->fault_vec. * tests/fault_injection-exit_group.test: Check parsing of inversed fault sets. * tests/fault_injection.test: Check parsing of -efault=none. * tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-04 17:39:48 +03:00
uint16_t first;
uint16_t step;
struct inject_data data;
Rewrite remaining qual_* parsers using bit sets * defs.h (struct fault_opts): Replace forward declaration with a definition. (qualbits_t, qualify_read, qualify_write, qualify_signals): Remove. (qual_flags): New function prototype. (nsyscall_vec, sysent_vec, fault_vec): New variable prototypes. * qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set): New variables. (qualify_read, qualify_write, qualify_signals): Add static qualifier. (find_errno_by_name, lookup_class, parse_fault_expression, parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault, qualify_raw, qualify_syscall, qualify_syscall_class, qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens, qualify_trace, qualify_verbose, strip_prefix): New functions. * syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier. (MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags, qual_fault, qual_syscall, qual_options, fault_opts, qualify_one, qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name, qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name, parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove. (decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall, get_scno): Update use of qual_flags. (inject_syscall_fault_entering): Update per-personality allocation of tcp->fault_vec. * tests/fault_injection-exit_group.test: Check parsing of inversed fault sets. * tests/fault_injection.test: Check parsing of -efault=none. * tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-04 17:39:48 +03:00
};
#define MAX_ERRNO_VALUE 4095
Implement success injection This extends fault injection syntax with :retval= option. When :retval=VALUE is specified, the syscall number is replaced by -1 and a bogus success VALUE is returned to the callee. * defs.h (fault_opts): Remove err field, add rval field. (MAX_ERRNO_VALUE, FAULT_OPTS_RVAL_DEFAULT, FAULT_OPTS_RVAL_DISABLE): New macros. * qualify.c (parse_fault_token): Handle retval= token. (qualify_fault): Update fault_opts initialization after the move from struct fault_opts.err to struct fault_opts.rval. * syscall.c (arch_set_success): New prototype. (inject_syscall_fault_entering): Check opts->rval instead of opts->err. (update_syscall_fault_exiting): Implement retval injection. * strace.1: Update the section on fault injection. * NEWS: Mention retval= option. * linux/aarch64/set_error.c (arch_set_success): New function. * linux/alpha/set_error.c: Likewise. * linux/arc/set_error.c: Likewise. * linux/arm/set_error.c: Likewise. * linux/avr32/set_error.c: Likewise. * linux/bfin/set_error.c: Likewise. * linux/crisv10/set_error.c: Likewise. * linux/hppa/set_error.c: Likewise. * linux/i386/set_error.c: Likewise. * linux/ia64/set_error.c: Likewise. * linux/m68k/set_error.c: Likewise. * linux/metag/set_error.c: Likewise. * linux/microblaze/set_error.c: Likewise. * linux/mips/set_error.c: Likewise. * linux/nios2/set_error.c: Likewise. * linux/or1k/set_error.c: Likewise. * linux/powerpc/set_error.c: Likewise. * linux/riscv/set_error.c: Likewise. * linux/s390/set_error.c: Likewise. * linux/sh/set_error.c: Likewise. * linux/sh64/set_error.c: Likewise. * linux/sparc/set_error.c: Likewise. * linux/sparc64/set_error.c: Likewise. * linux/tile/set_error.c: Likewise. * linux/x86_64/set_error.c: Likewise. * linux/xtensa/set_error.c: Likewise. Closes: https://github.com/strace/strace/issues/3
2017-01-25 02:59:16 +03:00
1999-02-19 03:21:36 +03:00
/* Trace Control Block */
struct tcb {
int flags; /* See below for TCB_ values */
int pid; /* If 0, this tcb is free */
Eliminate many SCNO_IS_VALID checks By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-21 19:13:47 +04:00
int qual_flg; /* qual_flags[scno] or DEFAULT_QUAL_FLAGS + RAW */
unsigned long u_error; /* Error code */
kernel_ulong_t scno; /* System call number */
kernel_ulong_t u_arg[MAX_ARGS]; /* System call arguments */
kernel_long_t u_rval; /* Return value */
#if SUPPORTED_PERSONALITIES > 1
Fix compilation warnings reported by gcc -Wsign-compare * configure.ac (gl_WARN_ADD): Add -Wsign-compare. * defs.h (struct tcb): Change 'currpers' type to unsigned. (struct xlat): Change 'val' type to unsigned (signame): Add 'const' qualifier to its argument. (xlookup, printxval): Add 'const' qualifier to the 2nd argument and change its type to unsigned. (printpathn): Change the 3rd argument type to unsigned. (ioctl_lookup): Change 1st argument type to unsigned. * count.c (call_summary_pers, call_summary): Change 'i' type to unsigned. * file.c (print_xattr_list): Fix comparisons between signed and unsigned long values. * ioctl.c (compare): Fix cast. (ioctl_lookup): Change 1st argument type to to unsigned. (ioctl_next_match): Change 'code' type to unsigned. * mem.c (sys_move_pages): Change 'i' type to unsigned. * mtd.c (mtd_ioctl): Change 'i' and 'j' types to unsigned. Print 'i' using %u format string. * process.c (sys_prctl): Change 'i' type to unsigned. (printargv): Change 'n' type to unsigned. (sys_ptrace): Change 'addr' type to unsigned. * scsi.c (print_sg_io_buffer): Add 'const' qualifier to 'len' argument and change its type to unsigned. Change 'i' and 'allocated' types to unsigned. * signal.c (signame): Add 'const' qualifier to its argument. Fix comparisons between signed and unsigned values. (sprintsigmask_n, printsiginfo): Fix comparisons between signed and unsigned values. * sock.c (sock_ioctl): Change 'i' and 'nifra' types to unsigned. * strace.c (expand_tcbtab, alloctcb): Change 'i' type to unsigned. (detach): Change 'sig' type to unsigned. (startup_attach): Change 'tcbi' type to unsigned. (startup_child): Change 'm', 'n', and 'len' types to unsigned. (init): Use new variable to iterate 'tcbtab'. (pid2tcb): Change 'i' type to unsigned. (cleanup): Change 'i' and 'sig' types to unsigned. * syscall.c (update_personality): Change 'personality' argument type to unsigned. (struct qual_options): Change 'bitflag' type to unsigned. (reallocate_qual): Add 'const' qualifier to its argument and change its type to unsigned. (qualify_one): Change 'n' and 'bitflag' arguments types to unsigned. Add 'const' qualifier to 'n', 'not', and 'pers' arguments. Change 'p' type to signed int. (qual_syscall): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. Change 'p' type to signed int. (qual_signal): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. Change 'i' type to unsigned. (qual_desc): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. (qualify): Change 'i' type to unsigned. (get_scno): Change 'currpers' type to unsigned. Fix a comparison between signed and unsigned values. * system.c (sys_sysctl): Change 'cnt' and 'max_cnt' types to unsigned. Fix comparisons between signed and unsigned values. * util.c (xlookup, printxval): Add 'const' qualifier to 'val' argument and change its type to unsigned. (printuid): Fix a comparison between signed and unsigned values. (printpathn): Change 'n' argument type to unsigned. (printstr): Change 'size' type to unsigned. Fix a comparison between signed and unsigned values. (setbpt): Change 'i' type to unsigned. * net.c (printsock): Silence a compilation warning. * reboot.c (sys_reboot): Likewise.
2014-09-10 17:46:04 +04:00
unsigned int currpers; /* Personality at the time of scno update */
#endif
int sys_func_rval; /* Syscall entry parser's return value */
int curcol; /* Output column for this process */
FILE *outf; /* Output file for this process */
2000-06-27 21:33:32 +04:00
const char *auxstr; /* Auxiliary info from syscall (see RVAL_STR) */
void *_priv_data; /* Private data for syscall decoding functions */
void (*_free_priv_data)(void *); /* Callback for freeing priv_data */
const struct_sysent *s_ent; /* sysent[scno] or dummy struct for bad scno */
const struct_sysent *s_prev_ent; /* for "resuming interrupted SYSCALL" msg */
struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
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
struct timespec stime; /* System time usage as of last process wait */
struct timespec dtime; /* Delta for system time usage */
struct timespec etime; /* Syscall entry time */
Implement delay injection Add -e inject=SET:delay_enter= and -e inject=SET:delay_exit= options. * configure.ac (AC_SEARCH_LIBS): Check for timer_create -lrt. * delay.c: New file. * Makefile.am (strace_SOURCES): Add it. (strace_LDADD): Add $(timer_LIBS). * defs.h (INJECT_F_DELAY_ENTER, INJECT_F_DELAY_EXIT, TCB_INJECT_DELAY_EXIT, TCB_DELAYED, inject_delay_exit, syscall_delayed): New macros. (alloc_delay_data, fill_delay_data, is_delay_timer_created, arm_delay_timer, delay_tcb): New prototypes. (struct inject_data): Replace reserved field with delay_idx. (struct tcb): Add delay_expiration_time field. * filter_qualify.c (parse_delay_token): New function. (parse_inject_token): Use it. (qualify_inject_common): Initialize struct inject_opts.data.delay_idx. * strace.c: Include <setjmp.h> (timer_jmp_buf, timer_set): New static variables. (timer_sighandler, restart_delayed_tcb, restart_delayed_tcbs): New functions. (init): Block SIGALRM, set SIGALRM handler. (dispatch_event): Do not restart delayed syscalls. (next_event): Unblock SIGALRM during wait4 invocation. * syscall.c (tamper_with_syscall_entering): Arm delay timer if INJECT_F_DELAY_ENTER injection flag is set, set TCB_INJECT_DELAY_EXIT flag if INJECT_F_DELAY_EXIT injection flag is set. tamper_with_syscall_exiting): Arm delay timer if inject_delay_exit. (syscall_exiting_trace): Call tamper_with_syscall_exiting in case of inject_delay_exit. (syscall_exiting_finish): Clear TCB_INJECT_DELAY_EXIT flag. * strace.1.in: Document delay injection. * NEWS: Mention this improvement. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-02-18 23:21:48 +03:00
struct timespec delay_expiration_time; /* When does the delay end */
struct mmap_cache_t *mmap_cache;
#ifdef ENABLE_STACKTRACE
void *unwind_ctx;
struct unwind_queue_t *unwind_queue;
#endif
1999-02-19 03:21:36 +03:00
};
/* TCB flags */
/* We have attached to this process, but did not see it stopping yet */
#define TCB_STARTUP 0x01
#define TCB_IGNORE_ONE_SIGSTOP 0x02 /* Next SIGSTOP is to be ignored */
/*
* Are we in system call entry or in syscall exit?
*
* This bit is set in syscall_entering_finish() and cleared in
* syscall_exiting_finish().
* Other stops which are possible directly after syscall entry (death, ptrace
* event stop) are handled without calling syscall_{entering,exiting}_*().
*
* Use entering(tcp) / exiting(tcp) to check this bit to make code more
* readable.
*/
#define TCB_INSYSCALL 0x04
#define TCB_ATTACHED 0x08 /* We attached to it already */
Remove support for systems without PTRACE_SETOPTIONS Assume that the kernel is v2.5.46 or newer, i.e. PTRACE_SETOPTIONS and PTRACE_O_TRACESYSGOOD|PTRACE_O_TRACEEXEC|PTRACE_O_TRACECLONE are universally available. This change removes all code that implemented post-execve SIGTRAP handling and fork/vfork/clone->CLONE_PTRACE substitution. * defs.h (TCB_BPTSET, TCB_WAITEXECVE): Remove macros. (need_fork_exec_workarounds, setbpt, clearbpt): Remove declarations. * strace.c (need_fork_exec_workarounds, test_ptrace_setoptions_followfork, test_ptrace_setoptions_for_all): Remove. (syscall_trap_sig): Set to (SIGTRAP | 0x80). (ptrace_setoptions): Set to (PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXEC). (detach): Do not test for TCB_BPTSET. (init): Do not call test_ptrace_setoptions_followfork and test_ptrace_setoptions_for_all. Do not test for TCB_BPTSET. * syscall.c (syscall_fixup_on_sysenter, internal_fork, internal_exec, syscall_fixup_for_fork_exec, syscall_fixup_on_sysexit): Remove. (trace_syscall_entering): Do not test for TCB_WAITEXECVE. Do not call syscall_fixup_on_sysenter and syscall_fixup_for_fork_exec. (trace_syscall_exiting): Do not call syscall_fixup_on_sysexit and syscall_fixup_for_fork_exec. [IA64] (ia64_ia32mode): Make static. * linux/ia64/arch_regs.h (ia64_ia32mode): Remove declaration. * util.c: Do not include "syscall.h". (arg_setup, get_arg0, get_arg1, set_arg0, set_arg1, restore_arg0, restore_arg1, arg_finish_change, change_syscall, setbpt, clearbpt): Remove. * tests/ptrace_setoptions.test: Remove. * tests/Makefile.am (TESTS): Remove it.
2015-02-08 16:05:53 +03:00
#define TCB_REPRINT 0x10 /* We should reprint this syscall on exit */
#define TCB_FILTERED 0x20 /* This system call has been filtered out */
#define TCB_TAMPERED 0x40 /* A syscall has been tampered with */
#define TCB_HIDE_LOG 0x80 /* We should hide everything (until execve) */
#define TCB_SKIP_DETACH_ON_FIRST_EXEC 0x100 /* -b execve should skip detach on first execve */
#define TCB_GRABBED 0x200 /* We grab the process and can catch it
* in the middle of a syscall */
#define TCB_RECOVERING 0x400 /* We try to recover after detecting incorrect
* syscall entering/exiting state */
Implement delay injection Add -e inject=SET:delay_enter= and -e inject=SET:delay_exit= options. * configure.ac (AC_SEARCH_LIBS): Check for timer_create -lrt. * delay.c: New file. * Makefile.am (strace_SOURCES): Add it. (strace_LDADD): Add $(timer_LIBS). * defs.h (INJECT_F_DELAY_ENTER, INJECT_F_DELAY_EXIT, TCB_INJECT_DELAY_EXIT, TCB_DELAYED, inject_delay_exit, syscall_delayed): New macros. (alloc_delay_data, fill_delay_data, is_delay_timer_created, arm_delay_timer, delay_tcb): New prototypes. (struct inject_data): Replace reserved field with delay_idx. (struct tcb): Add delay_expiration_time field. * filter_qualify.c (parse_delay_token): New function. (parse_inject_token): Use it. (qualify_inject_common): Initialize struct inject_opts.data.delay_idx. * strace.c: Include <setjmp.h> (timer_jmp_buf, timer_set): New static variables. (timer_sighandler, restart_delayed_tcb, restart_delayed_tcbs): New functions. (init): Block SIGALRM, set SIGALRM handler. (dispatch_event): Do not restart delayed syscalls. (next_event): Unblock SIGALRM during wait4 invocation. * syscall.c (tamper_with_syscall_entering): Arm delay timer if INJECT_F_DELAY_ENTER injection flag is set, set TCB_INJECT_DELAY_EXIT flag if INJECT_F_DELAY_EXIT injection flag is set. tamper_with_syscall_exiting): Arm delay timer if inject_delay_exit. (syscall_exiting_trace): Call tamper_with_syscall_exiting in case of inject_delay_exit. (syscall_exiting_finish): Clear TCB_INJECT_DELAY_EXIT flag. * strace.1.in: Document delay injection. * NEWS: Mention this improvement. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-02-18 23:21:48 +03:00
#define TCB_INJECT_DELAY_EXIT 0x800 /* Current syscall needs to be delayed
on exit */
#define TCB_DELAYED 0x1000 /* Current syscall has been delayed */
1999-02-19 03:21:36 +03:00
/* qualifier flags */
Eliminate many SCNO_IS_VALID checks By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-21 19:13:47 +04:00
#define QUAL_TRACE 0x001 /* this system call should be traced */
#define QUAL_ABBREV 0x002 /* abbreviate the structures of this syscall */
#define QUAL_VERBOSE 0x004 /* decode the structures of this syscall */
#define QUAL_RAW 0x008 /* print all args in hex for this syscall */
#define QUAL_INJECT 0x010 /* tamper with this system call on purpose */
Eliminate many SCNO_IS_VALID checks By adding tcp->s_ent pointer tot syscall table entry, we can replace sysent[tcp->scno] references by tcp->s_ent. More importantly, we may ensure that tcp->s_ent is always valid, regardless of tcp->scno value. This allows us to drop SCNO_IS_VALID(tcp->scno) checks before we access syscall table entry. We can optimize (qual_flags[tcp->scno] & QUAL_foo) checks with a similar technique. Resulting code shrink: text data bss dec hex filename 245975 700 19072 265747 40e13 strace.t3/strace 245703 700 19072 265475 40d03 strace.t4/strace * count.c (count_syscall): Use cheaper SCNO_IN_RANGE() check. * defs.h: Add "int qual_flg" and "const struct sysent *s_ent" to struct tcb. Remove "int u_nargs" from it. Add UNDEFINED_SCNO constant which will mark undefined scnos in tcp->qual_flg. * pathtrace.c (pathtrace_match): Drop SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. * process.c (sys_prctl): Use tcp->s_ent->nargs instead of tcp->u_nargs. (sys_waitid): Likewise. * strace.c (init): Add compile-time check that DEFAULT_QUAL_FLAGS constant is consistent with init code. * syscall.c (decode_socket_subcall): Use tcp->s_ent->nargs instead of tcp->u_nargs. Set tcp->qual_flg and tcp->s_ent. (decode_ipc_subcall): Likewise. (printargs): Use tcp->s_ent->nargs instead of tcp->u_nargs. (printargs_lu): Likewise. (printargs_ld): Likewise. (get_scno): [MIPS,ALPHA] Use cheaper SCNO_IN_RANGE() check. If !SCNO_IS_VALID, set tcp->s_ent and tcp->qual_flg to default values. (internal_fork): Use tcp->s_ent instead of sysent[tcp->scno]. (syscall_fixup_for_fork_exec): Remove SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. (get_syscall_args): Likewise. (get_error): Drop SCNO_IS_VALID check where it is redundant. (dumpio): Drop SCNO_IS_VALID check where it is redundant. Use tcp->s_ent instead of sysent[tcp->scno]. (trace_syscall_entering): Use (tcp->qual_flg & UNDEFINED_SCNO) instead of SCNO_IS_VALID check. Use tcp->s_ent instead of sysent[tcp->scno]. Drop SCNO_IS_VALID check where it is redundant. Print undefined syscall name with undefined_scno_name(tcp). (trace_syscall_exiting): Likewise. * util.c (setbpt): Use tcp->s_ent instead of sysent[tcp->scno]. Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
2013-02-21 19:13:47 +04:00
#define DEFAULT_QUAL_FLAGS (QUAL_TRACE | QUAL_ABBREV | QUAL_VERBOSE)
1999-02-19 03:21:36 +03:00
#define entering(tcp) (!((tcp)->flags & TCB_INSYSCALL))
#define exiting(tcp) ((tcp)->flags & TCB_INSYSCALL)
#define syserror(tcp) ((tcp)->u_error != 0)
#define traced(tcp) ((tcp)->qual_flg & QUAL_TRACE)
#define verbose(tcp) ((tcp)->qual_flg & QUAL_VERBOSE)
#define abbrev(tcp) ((tcp)->qual_flg & QUAL_ABBREV)
#define raw(tcp) ((tcp)->qual_flg & QUAL_RAW)
#define inject(tcp) ((tcp)->qual_flg & QUAL_INJECT)
#define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
#define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG)
#define syscall_tampered(tcp) ((tcp)->flags & TCB_TAMPERED)
#define recovering(tcp) ((tcp)->flags & TCB_RECOVERING)
Implement delay injection Add -e inject=SET:delay_enter= and -e inject=SET:delay_exit= options. * configure.ac (AC_SEARCH_LIBS): Check for timer_create -lrt. * delay.c: New file. * Makefile.am (strace_SOURCES): Add it. (strace_LDADD): Add $(timer_LIBS). * defs.h (INJECT_F_DELAY_ENTER, INJECT_F_DELAY_EXIT, TCB_INJECT_DELAY_EXIT, TCB_DELAYED, inject_delay_exit, syscall_delayed): New macros. (alloc_delay_data, fill_delay_data, is_delay_timer_created, arm_delay_timer, delay_tcb): New prototypes. (struct inject_data): Replace reserved field with delay_idx. (struct tcb): Add delay_expiration_time field. * filter_qualify.c (parse_delay_token): New function. (parse_inject_token): Use it. (qualify_inject_common): Initialize struct inject_opts.data.delay_idx. * strace.c: Include <setjmp.h> (timer_jmp_buf, timer_set): New static variables. (timer_sighandler, restart_delayed_tcb, restart_delayed_tcbs): New functions. (init): Block SIGALRM, set SIGALRM handler. (dispatch_event): Do not restart delayed syscalls. (next_event): Unblock SIGALRM during wait4 invocation. * syscall.c (tamper_with_syscall_entering): Arm delay timer if INJECT_F_DELAY_ENTER injection flag is set, set TCB_INJECT_DELAY_EXIT flag if INJECT_F_DELAY_EXIT injection flag is set. tamper_with_syscall_exiting): Arm delay timer if inject_delay_exit. (syscall_exiting_trace): Call tamper_with_syscall_exiting in case of inject_delay_exit. (syscall_exiting_finish): Clear TCB_INJECT_DELAY_EXIT flag. * strace.1.in: Document delay injection. * NEWS: Mention this improvement. Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
2018-02-18 23:21:48 +03:00
#define inject_delay_exit(tcp) ((tcp)->flags & TCB_INJECT_DELAY_EXIT)
#define syscall_delayed(tcp) ((tcp)->flags & TCB_DELAYED)
1999-02-19 03:21:36 +03:00
#include "xlat.h"
1999-02-19 03:21:36 +03:00
extern const struct xlat addrfams[];
extern const struct xlat arp_hardware_types[];
extern const struct xlat at_flags[];
extern const struct xlat clocknames[];
extern const struct xlat dirent_types[];
/** Ethernet protocols list, sorted, defined in sockaddr.c. */
extern const struct xlat ethernet_protocols[];
/** Ethernet protocols array size without terminating record. */
extern const size_t ethernet_protocols_size;
extern const struct xlat evdev_abs[];
/** Number of elements in evdev_abs array without the terminating record. */
extern const size_t evdev_abs_size;
extern const struct xlat iffflags[];
extern const struct xlat inet_protocols[];
extern const struct xlat ip_type_of_services[];
extern const struct xlat ipc_private[];
extern const struct xlat msg_flags[];
extern const struct xlat netlink_protocols[];
extern const struct xlat nl_netfilter_msg_types[];
extern const struct xlat nl_route_types[];
extern const struct xlat open_access_modes[];
extern const struct xlat open_mode_flags[];
extern const struct xlat resource_flags[];
extern const struct xlat routing_scopes[];
extern const struct xlat routing_table_ids[];
extern const struct xlat routing_types[];
extern const struct xlat seccomp_filter_flags[];
extern const struct xlat seccomp_ret_action[];
extern const struct xlat setns_types[];
extern const struct xlat sg_io_info[];
extern const struct xlat socketlayers[];
extern const struct xlat socktypes[];
extern const struct xlat tcp_state_flags[];
extern const struct xlat tcp_states[];
extern const struct xlat whence_codes[];
1999-02-19 03:21:36 +03:00
/* Format of syscall return values */
#define RVAL_UDECIMAL 000 /* unsigned decimal format */
1999-02-19 03:21:36 +03:00
#define RVAL_HEX 001 /* hex format */
#define RVAL_OCTAL 002 /* octal format */
#define RVAL_FD 010 /* file descriptor */
#define RVAL_MASK 013 /* mask for these values */
1999-02-19 03:21:36 +03:00
#define RVAL_STR 020 /* Print `auxstr' field after return val */
#define RVAL_NONE 040 /* Print nothing */
1999-02-19 03:21:36 +03:00
#define RVAL_DECODED 0100 /* syscall decoding finished */
#define RVAL_IOCTL_DECODED 0200 /* ioctl sub-parser successfully decoded
the argument */
#define IOCTL_NUMBER_UNKNOWN 0
#define IOCTL_NUMBER_HANDLED 1
#define IOCTL_NUMBER_STOP_LOOKUP 010
#define indirect_ipccall(tcp) (tcp->s_ent->sys_flags & TRACE_INDIRECT_SUBCALL)
enum sock_proto {
SOCK_PROTO_UNKNOWN,
SOCK_PROTO_UNIX,
SOCK_PROTO_TCP,
SOCK_PROTO_UDP,
SOCK_PROTO_TCPv6,
SOCK_PROTO_UDPv6,
SOCK_PROTO_NETLINK
};
extern enum sock_proto get_proto_by_name(const char *);
enum iov_decode {
IOV_DECODE_ADDR,
IOV_DECODE_STR,
IOV_DECODE_NETLINK
};
typedef enum {
CFLAG_NONE = 0,
CFLAG_ONLY_STATS,
CFLAG_BOTH
} cflag_t;
extern cflag_t cflag;
extern bool Tflag;
extern bool iflag;
extern bool count_wallclock;
extern unsigned int qflag;
extern bool not_failing_only;
extern unsigned int show_fd_path;
/* are we filtering traces based on paths? */
extern struct path_set {
const char **paths_selected;
size_t num_selected;
size_t size;
} global_path_set;
#define tracing_paths (global_path_set.num_selected != 0)
extern unsigned xflag;
extern unsigned followfork;
#ifdef ENABLE_STACKTRACE
/* if this is true do the stack trace for every system call */
extern bool stack_trace_enabled;
#endif
extern unsigned ptrace_setoptions;
extern unsigned max_strlen;
extern unsigned os_release;
#undef KERNEL_VERSION
#define KERNEL_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
extern int read_int_from_file(struct tcb *, const char *, int *);
extern void set_sortby(const char *);
extern void set_overhead(int);
extern void print_pc(struct tcb *);
extern int syscall_entering_decode(struct tcb *);
extern int syscall_entering_trace(struct tcb *, unsigned int *);
extern void syscall_entering_finish(struct tcb *, 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
extern int syscall_exiting_decode(struct tcb *, struct timespec *);
extern int syscall_exiting_trace(struct tcb *, struct timespec *, int);
extern void syscall_exiting_finish(struct tcb *);
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
extern void count_syscall(struct tcb *, const struct timespec *);
extern void call_summary(FILE *);
extern void clear_regs(struct tcb *tcp);
Introduce get_rt_sigframe_addr function Add get_rt_sigframe_addr function for all supported architectures. It is going to be used in a parser of rt_sigreturn syscall. * defs.h (get_rt_sigframe_addr): New function prototype. * rt_sigframe.c: New file. * Makefile.am (strace_SOURCES): Add it. * linux/aarch64/arch_rt_sigframe.c: New file. * linux/alpha/arch_rt_sigframe.c: Likewise. * linux/arc/arch_rt_sigframe.c: Likewise. * linux/arm/arch_rt_sigframe.c: Likewise. * linux/avr32/arch_rt_sigframe.c: Likewise. * linux/bfin/arch_rt_sigframe.c: Likewise. * linux/crisv10/arch_rt_sigframe.c: Likewise. * linux/crisv32/arch_rt_sigframe.c: Likewise. * linux/hppa/arch_rt_sigframe.c: Likewise. * linux/i386/arch_rt_sigframe.c: Likewise. * linux/ia64/arch_rt_sigframe.c: Likewise. * linux/m68k/arch_rt_sigframe.c: Likewise. * linux/metag/arch_rt_sigframe.c: Likewise. * linux/microblaze/arch_rt_sigframe.c: Likewise. * linux/mips/arch_rt_sigframe.c: Likewise. * linux/nios2/arch_rt_sigframe.c: Likewise. * linux/or1k/arch_rt_sigframe.c: Likewise. * linux/powerpc/arch_rt_sigframe.c: Likewise. * linux/powerpc64/arch_rt_sigframe.c: Likewise. * linux/riscv/arch_rt_sigframe.c: Likewise. * linux/s390/arch_rt_sigframe.c: Likewise. * linux/s390x/arch_rt_sigframe.c: Likewise. * linux/sh/arch_rt_sigframe.c: Likewise. * linux/sh64/arch_rt_sigframe.c: Likewise. * linux/sparc/arch_rt_sigframe.c: Likewise. * linux/sparc64/arch_rt_sigframe.c: Likewise. * linux/tile/arch_rt_sigframe.c: Likewise. * linux/x32/arch_rt_sigframe.c: Likewise. * linux/x86_64/arch_rt_sigframe.c: Likewise. * linux/xtensa/arch_rt_sigframe.c: Likewise. * Makefile.am (EXTRA_DIST): Add them.
2017-03-12 00:49:06 +03:00
extern int get_scno(struct tcb *);
extern kernel_ulong_t get_rt_sigframe_addr(struct tcb *);
/**
* Convert a (shuffled) syscall number to the corresponding syscall name.
*
* @param scno Syscall number.
* @return String literal corresponding to the syscall number in case latter
* is valid; NULL otherwise.
*/
extern const char *syscall_name(kernel_ulong_t scno);
/**
* Convert a syscall name to the corresponding (shuffled) syscall number.
*
* @param s Syscall name.
* @param p Personality.
* @param start From which position in syscall entry table resume the search.
* @return Shuffled syscall number (ready to use against sysent_vec)
* if syscall name is found; -1 otherwise.
*/
extern kernel_long_t scno_by_name(const char *s, unsigned p,
kernel_long_t start);
/**
* Shuffle syscall numbers so that we don't have huge gaps in syscall table.
* The shuffling should be an involution: shuffle_scno(shuffle_scno(n)) == n.
*
* @param scno Raw or shuffled syscall number.
* @return Shuffled or raw syscall number, respectively.
*/
extern kernel_ulong_t shuffle_scno(kernel_ulong_t scno);
extern const char *err_name(unsigned long err);
extern bool is_erestart(struct tcb *);
extern void temporarily_clear_syserror(struct tcb *);
extern void restore_cleared_syserror(struct tcb *);
extern void *get_tcb_priv_data(const struct tcb *);
extern int set_tcb_priv_data(struct tcb *, void *priv_data,
void (*free_priv_data)(void *));
extern void free_tcb_priv_data(struct tcb *);
static inline unsigned long get_tcb_priv_ulong(const struct tcb *tcp)
{
return (unsigned long) get_tcb_priv_data(tcp);
}
static inline int set_tcb_priv_ulong(struct tcb *tcp, unsigned long val)
{
return set_tcb_priv_data(tcp, (void *) val, 0);
}
/**
* @return 0 on success, -1 on error.
*/
extern int
umoven(struct tcb *, kernel_ulong_t addr, unsigned int len, void *laddr);
#define umove(pid, addr, objp) \
umoven((pid), (addr), sizeof(*(objp)), (void *) (objp))
/**
* @return 0 on success, -1 on error (and print addr).
*/
extern int
umoven_or_printaddr64(struct tcb *, uint64_t addr,
unsigned int len, void *laddr);
#define umove_or_printaddr64(pid, addr, objp) \
umoven_or_printaddr64((pid), (addr), sizeof(*(objp)), (void *) (objp))
static inline int
umoven_or_printaddr(struct tcb *tcp, const kernel_ulong_t addr,
unsigned int len, void *laddr)
{
return umoven_or_printaddr64(tcp, addr, len, laddr);
}
#define umove_or_printaddr(pid, addr, objp) \
umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
/**
* @return 0 on success, -1 on error (and print addr).
*/
extern int
umoven_or_printaddr64_ignore_syserror(struct tcb *, uint64_t addr,
unsigned int len, void *laddr);
#define umove_or_printaddr64_ignore_syserror(pid, addr, objp) \
umoven_or_printaddr64_ignore_syserror((pid), (addr), sizeof(*(objp)), \
(void *) (objp))
static inline int
umoven_or_printaddr_ignore_syserror(struct tcb *tcp, const kernel_ulong_t addr,
unsigned int len, void *laddr)
{
return umoven_or_printaddr64_ignore_syserror(tcp, addr, len, laddr);
}
#define umove_or_printaddr_ignore_syserror(pid, addr, objp) \
umoven_or_printaddr_ignore_syserror((pid), (addr), sizeof(*(objp)), \
(void *) (objp))
/**
* @return strlen + 1 on success, 0 on success and no NUL seen, -1 on error.
*/
extern int
umovestr(struct tcb *, kernel_ulong_t addr, unsigned int len, char *laddr);
Change the first argument of upeek from pid to tcp All users were changed automatically by: for i in `git grep -l 'upeek(tcp->pid'`; do \ sed -i 's/upeek(tcp->pid/upeek(tcp/g' "$i"; \ done * upeek.c (upeek): Change the first argument from pid_t pid to struct tcb *tcp. Use tcp->pid instead of pid in the function's body. * defs.h (upeek): Update declaration. * linux/alpha/arch_getrval2.c: Pass tcp instead of tcp->pid to the upeek calls. * linux/alpha/arch_rt_sigframe.c: Likewise. * linux/alpha/arch_sigreturn.c: Likewise. * linux/alpha/get_scno.c: Likewise. * linux/alpha/get_syscall_args.c: Likewise. * linux/alpha/get_syscall_result.c: Likewise. * linux/bfin/arch_rt_sigframe.c: Likewise. * linux/bfin/get_scno.c: Likewise. * linux/bfin/get_syscall_args.c: Likewise. * linux/bfin/get_syscall_result.c: Likewise. * linux/crisv10/arch_rt_sigframe.c: Likewise. * linux/crisv10/get_scno.c: Likewise. * linux/crisv10/get_syscall_args.c: Likewise. * linux/crisv10/get_syscall_result.c: Likewise. * linux/hppa/arch_rt_sigframe.c: Likewise. * linux/hppa/get_scno.c: Likewise. * linux/hppa/get_syscall_args.c: Likewise. * linux/hppa/get_syscall_result.c: Likewise. * linux/microblaze/arch_rt_sigframe.c: Likewise. * linux/microblaze/arch_sigreturn.c: Likewise. * linux/microblaze/get_scno.c: Likewise. * linux/microblaze/get_syscall_args.c: Likewise. * linux/microblaze/get_syscall_result.c: Likewise. * linux/powerpc/getregs_old.c: Likewise. * linux/sh/arch_getrval2.c: Likewise. * linux/sh/arch_rt_sigframe.c: Likewise. * linux/sh/get_scno.c: Likewise. * linux/sh/get_syscall_args.c: Likewise. * linux/sh/get_syscall_result.c: Likewise. * linux/sh64/get_scno.c: Likewise. * linux/sh64/get_syscall_args.c: Likewise. * linux/sh64/get_syscall_result.c: Likewise. * linux/xtensa/arch_rt_sigframe.c: Likewise. * linux/xtensa/get_scno.c: Likewise. * linux/xtensa/get_syscall_args.c: Likewise. * linux/xtensa/get_syscall_result.c: Likewise. * syscall.c: Likewise.
2017-12-26 01:52:48 +03:00
extern int upeek(struct tcb *tcp, unsigned long, kernel_ulong_t *);
Change the first argument of upoke from pid to tcp Users were updated automatically by: for i in `git grep -l 'upoke(tcp->pid'`; do \ sed -i 's/upoke(tcp->pid/upoke(tcp/g' "$i"; \ done * upoke.c (upoke): Change the first argument from pid_t pid to struct tcb *tcp. Use tcp->pid instead of pid in the function's body. * defs.h (upoke): Update declaration. * linux/alpha/set_error.c (arch_set_error, arch_set_success): Provide tcp in the first argument of the upoke call instead of tcp->pid. * linux/alpha/set_scno.c (arch_set_scno): Likewise. * linux/bfin/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/bfin/set_scno.c (arch_set_scno): Likewise. * linux/crisv10/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/crisv10/set_scno.c (arch_set_scno): Likewise. * linux/hppa/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/hppa/set_scno.c (arch_set_scno): Likewise. * linux/i386/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/i386/set_scno.c (arch_set_scno): Likewise. * linux/microblaze/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/microblaze/set_scno.c (arch_set_scno): Likewise. * linux/powerpc/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/powerpc/set_scno.c (arch_set_scno): Likewise. * linux/sh/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/sh/set_scno.c (arch_set_scno): Likewise. * linux/sh64/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/sh64/set_scno.c (arch_set_scno): Likewise. * linux/x86_64/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/x86_64/set_scno.c (arch_set_scno): Likewise. * linux/xtensa/set_error.c (arch_set_error, arch_set_success): Likewise. * linux/xtensa/set_scno.c (arch_set_scno): Likewise.
2017-12-26 01:45:04 +03:00
extern int upoke(struct tcb *tcp, unsigned long, kernel_ulong_t);
#if HAVE_ARCH_GETRVAL2
extern long getrval2(struct tcb *);
#endif
Fix compilation warnings reported by gcc -Wsign-compare * configure.ac (gl_WARN_ADD): Add -Wsign-compare. * defs.h (struct tcb): Change 'currpers' type to unsigned. (struct xlat): Change 'val' type to unsigned (signame): Add 'const' qualifier to its argument. (xlookup, printxval): Add 'const' qualifier to the 2nd argument and change its type to unsigned. (printpathn): Change the 3rd argument type to unsigned. (ioctl_lookup): Change 1st argument type to unsigned. * count.c (call_summary_pers, call_summary): Change 'i' type to unsigned. * file.c (print_xattr_list): Fix comparisons between signed and unsigned long values. * ioctl.c (compare): Fix cast. (ioctl_lookup): Change 1st argument type to to unsigned. (ioctl_next_match): Change 'code' type to unsigned. * mem.c (sys_move_pages): Change 'i' type to unsigned. * mtd.c (mtd_ioctl): Change 'i' and 'j' types to unsigned. Print 'i' using %u format string. * process.c (sys_prctl): Change 'i' type to unsigned. (printargv): Change 'n' type to unsigned. (sys_ptrace): Change 'addr' type to unsigned. * scsi.c (print_sg_io_buffer): Add 'const' qualifier to 'len' argument and change its type to unsigned. Change 'i' and 'allocated' types to unsigned. * signal.c (signame): Add 'const' qualifier to its argument. Fix comparisons between signed and unsigned values. (sprintsigmask_n, printsiginfo): Fix comparisons between signed and unsigned values. * sock.c (sock_ioctl): Change 'i' and 'nifra' types to unsigned. * strace.c (expand_tcbtab, alloctcb): Change 'i' type to unsigned. (detach): Change 'sig' type to unsigned. (startup_attach): Change 'tcbi' type to unsigned. (startup_child): Change 'm', 'n', and 'len' types to unsigned. (init): Use new variable to iterate 'tcbtab'. (pid2tcb): Change 'i' type to unsigned. (cleanup): Change 'i' and 'sig' types to unsigned. * syscall.c (update_personality): Change 'personality' argument type to unsigned. (struct qual_options): Change 'bitflag' type to unsigned. (reallocate_qual): Add 'const' qualifier to its argument and change its type to unsigned. (qualify_one): Change 'n' and 'bitflag' arguments types to unsigned. Add 'const' qualifier to 'n', 'not', and 'pers' arguments. Change 'p' type to signed int. (qual_syscall): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. Change 'p' type to signed int. (qual_signal): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. Change 'i' type to unsigned. (qual_desc): Change 'bitflag' argument type to unsigned. Add 'const' qualifier to 'bitflag' and 'not' arguments. (qualify): Change 'i' type to unsigned. (get_scno): Change 'currpers' type to unsigned. Fix a comparison between signed and unsigned values. * system.c (sys_sysctl): Change 'cnt' and 'max_cnt' types to unsigned. Fix comparisons between signed and unsigned values. * util.c (xlookup, printxval): Add 'const' qualifier to 'val' argument and change its type to unsigned. (printuid): Fix a comparison between signed and unsigned values. (printpathn): Change 'n' argument type to unsigned. (printstr): Change 'size' type to unsigned. Fix a comparison between signed and unsigned values. (setbpt): Change 'i' type to unsigned. * net.c (printsock): Silence a compilation warning. * reboot.c (sys_reboot): Likewise.
2014-09-10 17:46:04 +04:00
extern const char *signame(const int);
extern void pathtrace_select_set(const char *, struct path_set *);
extern bool pathtrace_match_set(struct tcb *, struct path_set *);
static inline void
pathtrace_select(const char *path)
{
return pathtrace_select_set(path, &global_path_set);
}
static inline bool
pathtrace_match(struct tcb *tcp)
{
return pathtrace_match_set(tcp, &global_path_set);
}
extern int getfdpath(struct tcb *, int, char *, unsigned);
extern unsigned long getfdinode(struct tcb *, int);
extern enum sock_proto getfdproto(struct tcb *, int);
extern const char *xlookup(const struct xlat *, const uint64_t);
extern const char *xlat_search(const struct xlat *, const size_t, const uint64_t);
extern const char *xlat_idx(const struct xlat *xlat, size_t nmemb, uint64_t val);
struct dyxlat;
struct dyxlat *dyxlat_alloc(size_t nmemb);
void dyxlat_free(struct dyxlat *);
const struct xlat *dyxlat_get(const struct dyxlat *);
void dyxlat_add_pair(struct dyxlat *, uint64_t val, const char *str, size_t len);
Add tcp arguments to netlink calls Since they call tracee-specific socket/sendmsg/recvmsg, we'd like to pass tcp there. * defs.h (genl_families_xlat): Add tcp argument. * netlink.c (decode_nlmsg_type_default, decode_nlmsg_type_generic, decode_nlmsg_type_netfilter, typedef nlmsg_types_decoder_t): Likewise. (decode_nlmsg_type): Add tcp argument. Pass tcp to decoder call. (print_nlmsghdr): Pass tcp to the decode_nlmsg_type call. * socketutils.c (send_query, receive_responses): Add tcp argument. (inet_send_query, unix_send_query, netlink_send_query, ): Add tcp argument. Pass tcp to the send_query call. (unix_get): Add tcp argument. Pass tcp to the unix_send_query and receive_responses calls. (inet_get): Add tcp argument. Pass tcp to the inet_send_query and receive_responses calls. (tcp_v4_get, udp_v4_get, tcp_v6_get, udp_v6_get): Add tcp argument. Pass tcp to the inet_get call. (netlink_get): Add tcp argument. Pass tcp to the netlink_send_query and receive_responses calls. (protocols): Add tcp argument to the get field. (get_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to the protocols[].get calls. (print_sockaddr_by_inode_uncached): Add tcp argument. Pass tcp to the get_sockaddr_by_inode_uncached call. (get_sockaddr_by_inode): Pass tcp to the get_sockaddr_by_inode_uncached call. (print_sockaddr_by_inode): Pass tcp to the print_sockaddr_by_inode_uncached call. (genl_send_dump_families): Add tcp argument. Pass tcp to the send_query call. (genl_families_xlat): Add tcp argument. Pass tcp to the genl_send_dump_families and receive_responses calls.
2017-12-26 02:14:14 +03:00
const struct xlat *genl_families_xlat(struct tcb *tcp);
extern unsigned long get_pagesize(void);
extern int next_set_bit(const void *bit_array, unsigned cur_bit, unsigned size_bits);
/*
* Returns STR if it does not start with PREFIX,
* or a pointer to the first char in STR after PREFIX.
* The length of PREFIX is specified by PREFIX_LEN.
*/
static inline const char *
str_strip_prefix_len(const char *str, const char *prefix, size_t prefix_len)
{
return strncmp(str, prefix, prefix_len) ? str : str + prefix_len;
}
#define STR_STRIP_PREFIX(str, prefix) \
str_strip_prefix_len((str), (prefix), sizeof(prefix) - 1)
#define QUOTE_0_TERMINATED 0x01
#define QUOTE_OMIT_LEADING_TRAILING_QUOTES 0x02
#define QUOTE_OMIT_TRAILING_0 0x08
#define QUOTE_FORCE_HEX 0x10
#define QUOTE_EMIT_COMMENT 0x20
extern int string_quote(const char *, char *, unsigned int, unsigned int,
const char *escape_chars);
extern int print_quoted_string_ex(const char *, unsigned int, unsigned int,
const char *escape_chars);
extern int print_quoted_string(const char *, unsigned int, unsigned int);
extern int print_quoted_cstring(const char *, unsigned int);
/* a refers to the lower numbered u_arg,
* b refers to the higher numbered u_arg
*/
#ifdef WORDS_BIGENDIAN
# define ULONG_LONG(a, b) \
((unsigned long long)(unsigned)(b) | ((unsigned long long)(a)<<32))
#else
# define ULONG_LONG(a, b) \
((unsigned long long)(unsigned)(a) | ((unsigned long long)(b)<<32))
#endif
extern int getllval(struct tcb *, unsigned long long *, int);
extern int printllval(struct tcb *, const char *, int)
ATTRIBUTE_FORMAT((printf, 2, 0));
extern void printaddr64(uint64_t addr);
static inline void
printaddr(const kernel_ulong_t addr)
{
printaddr64(addr);
}
#define XLAT_STYLE_VERBOSITY_MASK (XLAT_STYLE_RAW | XLAT_STYLE_ABBREV)
#define XLAT_STYLE_FORMAT_SHIFT 2
#define XLAT_STYLE_FORMAT_MASK (3 << XLAT_STYLE_FORMAT_SHIFT)
#define xlat_verbose(style_) ((style_) & XLAT_STYLE_VERBOSITY_MASK)
#define xlat_format(style_) ((style_) & XLAT_STYLE_FORMAT_MASK)
enum xlat_type {
XT_NORMAL,
XT_SORTED,
XT_INDEXED,
};
enum xlat_style {
/**
* Special value that is used for passing to *print{xval,flags}*_ex
* routines that indicates that no overriding of user-supplied xlat
* verbosity/formatting configuration is intended.
*/
XLAT_STYLE_DEFAULT = 0,
/** Print xlat value as is without xlat processing */
XLAT_STYLE_RAW = 1 << 0,
/**
* Historic strace style, process xlat and print the result (xlat
* constant name/combination of flags), raw number only if nothing is
* found.
*/
XLAT_STYLE_ABBREV = 1 << 1,
/** Always print both raw number and xlat processing result. */
XLAT_STYLE_VERBOSE = XLAT_STYLE_RAW | XLAT_STYLE_ABBREV,
XLAT_STYLE_FMT_X = 0 << XLAT_STYLE_FORMAT_SHIFT,
XLAT_STYLE_FMT_U = 1 << XLAT_STYLE_FORMAT_SHIFT,
XLAT_STYLE_FMT_D = 2 << XLAT_STYLE_FORMAT_SHIFT,
};
extern enum xlat_style xlat_verbosity;
extern int printxvals_ex(uint64_t val, const char *dflt,
enum xlat_style, const struct xlat *, ...)
ATTRIBUTE_SENTINEL;
#define printxvals(val_, dflt_, ...) \
printxvals_ex((val_), (dflt_), XLAT_STYLE_DEFAULT, __VA_ARGS__)
extern int printxval_searchn_ex(const struct xlat *, size_t xlat_size,
uint64_t val, const char *dflt,
enum xlat_style);
static inline int
printxval_searchn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
const char *dflt)
{
return printxval_searchn_ex(xlat, xlat_size, val, dflt,
XLAT_STYLE_DEFAULT);
}
/**
* Wrapper around printxval_searchn that passes ARRAY_SIZE - 1
* as the array size, as all arrays are XLAT_END-terminated and
* printxval_searchn expects a size without the terminating record.
*/
#define printxval_search(xlat__, val__, dflt__) \
printxval_searchn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
#define printxval_search_ex(xlat__, val__, dflt__) \
printxval_searchn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
(dflt__), XLAT_STYLE_DEFAULT)
extern int printxval_indexn_ex(const struct xlat *, size_t xlat_size,
uint64_t val, const char *dflt, enum xlat_style);
static inline int
printxval_indexn(const struct xlat *xlat, size_t xlat_size, uint64_t val,
const char *dflt)
{
return printxval_indexn_ex(xlat, xlat_size, val, dflt,
XLAT_STYLE_DEFAULT);
}
#define printxval_index(xlat__, val__, dflt__) \
printxval_indexn(xlat__, ARRAY_SIZE(xlat__) - 1, val__, dflt__)
#define printxval_index_ex(xlat__, val__, dflt__) \
printxval_indexn_ex((xlat__), ARRAY_SIZE(xlat__) - 1, (val__), \
(dflt__), XLAT_STYLE_DEFAULT)
extern int sprintxval_ex(char *buf, size_t size, const struct xlat *,
unsigned int val, const char *dflt, enum xlat_style);
static inline int
sprintxval(char *buf, size_t size, const struct xlat *xlat, unsigned int val,
const char *dflt)
{
return sprintxval_ex(buf, size, xlat, val, dflt, XLAT_STYLE_DEFAULT);
}
extern void printxval_dispatch_ex(const struct xlat *, size_t xlat_size,
uint64_t val, const char *dflt,
enum xlat_type, enum xlat_style);
static inline void
printxval_dispatch(const struct xlat *xlat, size_t xlat_size, uint64_t val,
const char *dflt, enum xlat_type xt)
{
return printxval_dispatch_ex(xlat, xlat_size, val, dflt, xt,
XLAT_STYLE_DEFAULT);
}
/** Print a value in accordance with xlat formatting settings. */
extern void print_xlat_ex(uint64_t val, const char *str, enum xlat_style style);
#define print_xlat(val_) \
print_xlat_ex((val_), #val_, XLAT_STYLE_DEFAULT)
#define print_xlat32(val_) \
print_xlat_ex((uint32_t) (val_), #val_, XLAT_STYLE_DEFAULT)
#define print_xlat_u(val_) \
print_xlat_ex((val_), #val_, XLAT_STYLE_FMT_U)
#define print_xlat_d(val_) \
print_xlat_ex((val_), #val_, XLAT_STYLE_FMT_D)
extern int printargs(struct tcb *);
extern int printargs_u(struct tcb *);
extern int printargs_d(struct tcb *);
extern int printflags_ex(uint64_t flags, const char *dflt,
enum xlat_style, const struct xlat *, ...)
ATTRIBUTE_SENTINEL;
extern const char *sprintflags_ex(const char *prefix, const struct xlat *,
uint64_t flags, enum xlat_style);
static inline const char *
sprintflags(const char *prefix, const struct xlat *xlat, uint64_t flags)
{
return sprintflags_ex(prefix, xlat, flags, XLAT_STYLE_DEFAULT);
}
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
extern const char *sprinttime(long long sec);
extern const char *sprinttime_nsec(long long sec, unsigned long long nsec);
extern const char *sprinttime_usec(long long sec, unsigned long long usec);
extern const char *sprint_mac_addr(const uint8_t addr[], size_t size);
Fix printing of mode_t, umode_t, and umask types Print numeric umode_t type using %#03ho format. Print return value of umask syscall using %#03lo format. When printing symbolic mode_t type, always print lower 9 bits, and print the numeric part using %#03o format. * defs.h (sprintmode): Remove. (print_symbolic_mode_t, print_numeric_umode_t, print_numeric_long_umask): New prototypes. * printmode.c (sprintmode): Remove. (print_symbolic_mode_t, print_numeric_umode_t, print_numeric_long_umask): New functions. * chmod.c (decode_chmod): Use print_numeric_umode_t. * ipc_msg.c (SYS_FUNC(msgget)): Likewise. * ipc_msgctl.c (print_msqid_ds): Likewise. * ipc_sem.c (SYS_FUNC(semget)): Likewise. * ipc_shm.c (SYS_FUNC(shmget)): Likewise. * ipc_shmctl.c (print_shmid_ds): Likewise. * mq.c (SYS_FUNC(mq_open)): Likewise. * open.c (decode_open, SYS_FUNC(creat)): Likewise. * umask.c (SYS_FUNC(umask)): Likewise. * mknod.c (decode_mknod): Use print_symbolic_mode_t. * printstat.h (DO_PRINTSTAT): Likewise. * syscall.c (trace_syscall_exiting): Use print_numeric_long_umask. * tests/umode_t.c: New file. * tests/Makefile.am (EXTRA_DIST): Add it. * tests/creat.c: Rewrite as a thin wrapper around umode_t.c * tests/mkdir.c: Likewise. * tests/mkdirat.c: Likewise. * tests/mknod.c: Extend test coverage of mknod syscall. * tests/mknodat.c: Extend test coverage of mknodat syscall. * tests/umask.c: Extend test coverage of umask syscall. * tests/creat.test: Update the value specified for strace -a parameter. * tests/mkdir.test: Likewise. * tests/mkdirat.test: Likewise. * tests/mknodat.test: Likewise.
2016-08-03 17:05:39 +03:00
extern void print_symbolic_mode_t(unsigned int);
extern void print_numeric_umode_t(unsigned short);
extern void print_numeric_long_umask(unsigned long);
extern void print_dev_t(unsigned long long dev);
extern void print_abnormal_hi(kernel_ulong_t);
extern bool print_int32_array_member(struct tcb *, void *elem_buf,
size_t elem_size, void *data);
extern bool print_uint32_array_member(struct tcb *, void *elem_buf,
size_t elem_size, void *data);
extern bool print_uint64_array_member(struct tcb *, void *elem_buf,
size_t elem_size, void *data);
extern bool
print_array(struct tcb *,
kernel_ulong_t start_addr,
size_t nmemb,
void *elem_buf,
size_t elem_size,
int (*umoven_func)(struct tcb *,
kernel_ulong_t,
unsigned int,
void *),
bool (*print_func)(struct tcb *,
void *elem_buf,
size_t elem_size,
void *opaque_data),
void *opaque_data);
extern kernel_ulong_t *
fetch_indirect_syscall_args(struct tcb *, kernel_ulong_t addr, unsigned int n_args);
extern void
dumpiov_in_msghdr(struct tcb *, kernel_ulong_t addr, kernel_ulong_t data_size);
extern void
dumpiov_in_mmsghdr(struct tcb *, kernel_ulong_t addr);
extern void
dumpiov_upto(struct tcb *, int len, kernel_ulong_t addr, kernel_ulong_t data_size);
extern void
dumpstr(struct tcb *, kernel_ulong_t addr, int len);
extern int
printstr_ex(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
unsigned int user_style);
extern int
printpathn(struct tcb *, kernel_ulong_t addr, unsigned int n);
extern int
printpath(struct tcb *, kernel_ulong_t addr);
#define TIMESPEC_TEXT_BUFSIZE \
Print microseconds/nanoseconds as non-negative Negative micro/nanoseconds values are treated as invalid by kernel anyway, and in one case (timespec_valid in include/linux/time.h) it is even checked by conversion to unsigned long. * print_timespec.c (timespec_fmt): Change tv_sec format to %lld and tv_nsec format to %llu. (print_timespec_t): Cast tv_sec to long long and process tv_nsec with zero_extend_signed_to_ull. (sprint_timespec): Likewise. * print_timeval.c (timeval_fmt): Change tv_sec format to %lld and tv_usec format to %llu. (print_timeval_t): Cast tv_sec to long long and process tv_nsec with zero_extend_signed_to_ull. (sprint_timeval, print_timeval32_t, sprint_timeval32): Likewise. * defs.h (TIMESPEC_TEXT_BUFSIZE): Update. * tests/adjtimex.c (main): Change tv_sec printing format to %lld, cast it to long long; change tv_usec printing format to %llu, process it with zero_extend_signed_to_ull. * tests/clock_nanosleep.c (main): Change tv_sec printing format to %lld, cast it to long long; change tv_nsec printing format to %llu, process it with zero_extend_signed_to_ull. * tests/clock_xettime.c (main): Likewise. * tests/futex.c (main): Likewise. * tests/futimesat.c (print_tv): Likewise. * tests/getrusage.c (invoke_print): Likewise. * tests/mq_sendrecv.c (do_send, do_recv, main): Likewise. * tests/nanosleep.c (main): Likewise. * tests/pselect6.c (main): Likewise. * tests/restart_syscall.c (main): Likewise. * tests/rt_sigtimedwait.c (iterate, main): Likewise. * tests/sched_rr_get_interval.c (main): Likewise. * tests/semop.c (main): Likewise. * tests/timer_xettime.c (main): Likewise. * tests/timerfd_xettime.c (main): Likewise. * tests/waitid.c (main): Likewise. * tests/xetitimer.c (main): Likewise. * tests/xettimeofday.c (main): Likewise. * tests/xselect.c (main): Likewise. * tests/xutimes.c (print_tv): Likewise. * tests/wait4.c (sprint_rusage): Likewise. * tests/waitid.c (sprint_rusage): Likewise. * tests/utimensat.c (print_ts): Likewise. (main): Add check for higher bits of tv_sec/tv_nsec. Co-authored-by: Dmitry V. Levin <ldv@altlinux.org>
2017-04-23 06:57:03 +03:00
(sizeof(long long) * 3 * 2 + sizeof("{tv_sec=-, tv_nsec=}"))
extern void printfd(struct tcb *, int);
extern void print_sockaddr(const void *sa, int len);
extern bool
print_inet_addr(int af, const void *addr, unsigned int len, const char *var_name);
extern bool
decode_inet_addr(struct tcb *, kernel_ulong_t addr,
unsigned int len, int family, const char *var_name);
extern const char *get_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode);
extern bool print_sockaddr_by_inode(struct tcb *, int fd, unsigned long inode);
extern void print_dirfd(struct tcb *, int);
extern int
decode_sockaddr(struct tcb *, kernel_ulong_t addr, int addrlen);
extern void printuid(const char *, const unsigned int);
extern void
print_sigset_addr_len(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len);
extern void
print_sigset_addr(struct tcb *, kernel_ulong_t addr);
extern const char *sprintsigmask_n(const char *, const void *, unsigned int);
#define tprintsigmask_addr(prefix, mask) \
tprints(sprintsigmask_n((prefix), (mask), sizeof(mask)))
extern void printsignal(int);
extern void
tprint_iov_upto(struct tcb *, kernel_ulong_t len, kernel_ulong_t addr,
enum iov_decode, kernel_ulong_t data_size);
extern void
decode_netlink(struct tcb *, int fd, kernel_ulong_t addr, kernel_ulong_t len);
extern void tprint_open_modes(unsigned int);
extern const char *sprint_open_modes(unsigned int);
extern void
decode_seccomp_fprog(struct tcb *, kernel_ulong_t addr);
extern void
print_seccomp_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
extern void
decode_sock_fprog(struct tcb *, kernel_ulong_t addr);
extern void
print_sock_fprog(struct tcb *, kernel_ulong_t addr, unsigned short len);
struct strace_stat;
extern void print_struct_stat(struct tcb *, const struct strace_stat *const st);
struct strace_statfs;
struct strace_keyctl_kdf_params;
extern void
print_struct_statfs(struct tcb *, kernel_ulong_t addr);
extern void
print_struct_statfs64(struct tcb *, kernel_ulong_t addr, kernel_ulong_t size);
extern int
fetch_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
extern void
print_perf_event_attr(struct tcb *const tcp, const kernel_ulong_t addr);
extern void print_ifindex(unsigned int);
extern void print_bpf_filter_code(const uint16_t code, bool extended);
Rewrite remaining qual_* parsers using bit sets * defs.h (struct fault_opts): Replace forward declaration with a definition. (qualbits_t, qualify_read, qualify_write, qualify_signals): Remove. (qual_flags): New function prototype. (nsyscall_vec, sysent_vec, fault_vec): New variable prototypes. * qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set): New variables. (qualify_read, qualify_write, qualify_signals): Add static qualifier. (find_errno_by_name, lookup_class, parse_fault_expression, parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault, qualify_raw, qualify_syscall, qualify_syscall_class, qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens, qualify_trace, qualify_verbose, strip_prefix): New functions. * syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier. (MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags, qual_fault, qual_syscall, qual_options, fault_opts, qualify_one, qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name, qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name, parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove. (decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall, get_scno): Update use of qual_flags. (inject_syscall_fault_entering): Update per-personality allocation of tcp->fault_vec. * tests/fault_injection-exit_group.test: Check parsing of inversed fault sets. * tests/fault_injection.test: Check parsing of -efault=none. * tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-04 17:39:48 +03:00
extern void qualify(const char *);
extern unsigned int qual_flags(const unsigned int);
#define DECL_IOCTL(name) \
extern int \
name ## _ioctl(struct tcb *, unsigned int request, kernel_ulong_t arg) \
/* End of DECL_IOCTL definition. */
DECL_IOCTL(dm);
DECL_IOCTL(evdev);
DECL_IOCTL(file);
DECL_IOCTL(fs_x);
DECL_IOCTL(inotify);
DECL_IOCTL(kvm);
DECL_IOCTL(nsfs);
DECL_IOCTL(ptp);
DECL_IOCTL(scsi);
DECL_IOCTL(term);
DECL_IOCTL(ubi);
DECL_IOCTL(uffdio);
#undef DECL_IOCTL
1999-02-19 03:21:36 +03:00
extern int decode_sg_io_v4(struct tcb *, const kernel_ulong_t arg);
extern void print_evdev_ff_type(const kernel_ulong_t val);
struct nlmsghdr;
typedef bool (*netlink_decoder_t)(struct tcb *, const struct nlmsghdr *,
Adjust prototypes of netlink parsing functions Change the type of "len" argument that is based on struct nlmsghdr.nlmsg_len from kernel_ulong_t to unsigned int. * defs.h (netlink_decoder_t, DECL_NETLINK): Change "len" argument type from kernel_ulong_t to unsigned int. * netlink.c (decode_nlmsgerr_attr_cookie, decode_nlmsgerr, decode_payload): Likewise. * netlink_selinux.c (decode_netlink_selinux): Likewise. * netlink_sock_diag.c (decode_family, decode_unix_diag_req, decode_meminfo, decode_unix_diag_vfs, decode_unix_diag_inode, decode_unix_diag_rqlen, decode_unix_diag_msg, decode_netlink_diag_req, print_group, decode_netlink_diag_ring, decode_netlink_diag_flags, decode_netlink_diag_msg, decode_packet_diag_req, decode_packet_diag_info, decode_packet_diag_mclist, decode_packet_diag_ring, decode_packet_diag_filter, decode_packet_diag_msg, decode_inet_addr, decode_inet_diag_hostcond, decode_inet_diag_markcond, decode_bytecode_data, decode_inet_diag_bc_op, decode_inet_diag_req_compat, decode_inet_diag_req_v2, decode_inet_diag_req, decode_inet_diag_meminfo, decode_tcpvegas_info, decode_tcp_dctcp_info, decode_tcp_bbr_info, decode_inet_diag_msg, decode_smc_diag_req, decode_smc_diag_conninfo, decode_smc_diag_lgrinfo, decode_smc_diag_msg, netlink_diag_decoder_t, decode_netlink_sock_diag): Likewise. * nlattr.c (fetch_nlattr, decode_nlattr_with_data, decode_nlattr, decode_nla_str, decode_nla_strn, DECODE_NLA_INTEGER): Likewise. * nlattr.h (nla_decoder_t, DECL_NLA, decode_nlattr): Likewise.
2017-07-19 13:07:34 +03:00
kernel_ulong_t addr, unsigned int len);
#define DECL_NETLINK(name) \
extern bool \
decode_netlink_ ## name(struct tcb *, const struct nlmsghdr *, \
kernel_ulong_t addr, unsigned int len) \
/* End of DECL_NETLINK definition. */
DECL_NETLINK(crypto);
DECL_NETLINK(netfilter);
DECL_NETLINK(route);
DECL_NETLINK(selinux);
DECL_NETLINK(sock_diag);
extern void
decode_netlink_kobject_uevent(struct tcb *, kernel_ulong_t addr,
kernel_ulong_t len);
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
extern int ts_nz(const struct timespec *);
extern int ts_cmp(const struct timespec *, const struct timespec *);
extern double ts_float(const struct timespec *);
extern void ts_add(struct timespec *, const struct timespec *, const struct timespec *);
extern void ts_sub(struct timespec *, const struct timespec *, const struct timespec *);
extern void ts_mul(struct timespec *, const struct timespec *, int);
extern void ts_div(struct timespec *, const struct timespec *, int);
1999-02-19 03:21:36 +03:00
#ifdef ENABLE_STACKTRACE
extern void unwind_init(void);
extern void unwind_tcb_init(struct tcb *);
extern void unwind_tcb_fin(struct tcb *);
extern void unwind_tcb_print(struct tcb *);
extern void unwind_tcb_capture(struct tcb *);
#endif
static inline int
printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len)
{
return printstr_ex(tcp, addr, len, 0);
}
static inline int
printstr(struct tcb *tcp, kernel_ulong_t addr)
{
return printstr_ex(tcp, addr, -1, QUOTE_0_TERMINATED);
}
static inline int
printflags64(const struct xlat *x, uint64_t flags, const char *dflt)
{
return printflags_ex(flags, dflt, XLAT_STYLE_DEFAULT, x, NULL);
}
static inline int
printflags(const struct xlat *x, unsigned int flags, const char *dflt)
{
return printflags64(x, flags, dflt);
}
static inline int
printxval64(const struct xlat *x, const uint64_t val, const char *dflt)
{
return printxvals(val, dflt, x, NULL);
}
static inline int
printxval(const struct xlat *x, const unsigned int val, const char *dflt)
{
return printxvals(val, dflt, x, NULL);
}
static inline int
printxval64_u(const struct xlat *x, const uint64_t val, const char *dflt)
{
return printxvals_ex(val, dflt, XLAT_STYLE_FMT_U, x, NULL);
}
static inline int
printxval_u(const struct xlat *x, const unsigned int val, const char *dflt)
{
return printxvals_ex(val, dflt, XLAT_STYLE_FMT_U, x, NULL);
}
static inline int
printxval64_d(const struct xlat *x, const int64_t val, const char *dflt)
{
return printxvals_ex(val, dflt, XLAT_STYLE_FMT_D, x, NULL);
}
static inline int
printxval_d(const struct xlat *x, const int val, const char *dflt)
{
return printxvals_ex(val, dflt, XLAT_STYLE_FMT_D, x, NULL);
}
static inline void
tprint_iov(struct tcb *tcp, kernel_ulong_t len, kernel_ulong_t addr,
enum iov_decode decode_iov)
{
tprint_iov_upto(tcp, len, addr, decode_iov, -1);
}
#ifdef ALPHA
typedef struct {
int tv_sec, tv_usec;
} timeval32_t;
extern void print_timeval32_t(const timeval32_t *);
extern void printrusage32(struct tcb *, kernel_ulong_t);
extern const char *sprint_timeval32(struct tcb *, kernel_ulong_t addr);
extern void print_timeval32(struct tcb *, kernel_ulong_t addr);
extern void print_timeval32_utimes(struct tcb *, kernel_ulong_t addr);
extern void print_itimerval32(struct tcb *, kernel_ulong_t addr);
#endif
#ifdef HAVE_STRUCT_USER_DESC
/**
* Filter what to print from the point of view of the get_thread_area syscall.
* Kernel copies only entry_number field at first and then tries to write the
* whole structure.
*/
enum user_desc_print_filter {
/* Print the "entering" part of struct user_desc - entry_number. */
USER_DESC_ENTERING = 1,
/* Print the "exiting" part of the structure. */
USER_DESC_EXITING = 2,
USER_DESC_BOTH = USER_DESC_ENTERING | USER_DESC_EXITING,
};
extern void print_user_desc(struct tcb *, kernel_ulong_t addr,
enum user_desc_print_filter filter);
#endif
/* Strace log generation machinery.
*
* printing_tcp: tcb which has incomplete line being printed right now.
* NULL if last line has been completed ('\n'-terminated).
* printleader(tcp) examines it, finishes incomplete line if needed,
* the sets it to tcp.
* line_ended() clears printing_tcp and resets ->curcol = 0.
* tcp->curcol == 0 check is also used to detect completeness
* of last line, since in -ff mode just checking printing_tcp for NULL
* is not enough.
*
* If you change this code, test log generation in both -f and -ff modes
* using:
* strace -oLOG -f[f] test/threaded_execve
* strace -oLOG -f[f] test/sigkill_rain
* strace -oLOG -f[f] -p "`pidof web_browser`"
*/
extern struct tcb *printing_tcp;
extern void printleader(struct tcb *);
extern void line_ended(void);
extern void tabto(void);
extern void tprintf(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
extern void tprints(const char *str);
extern void tprintf_comment(const char *fmt, ...) ATTRIBUTE_FORMAT((printf, 1, 2));
extern void tprints_comment(const char *str);
static inline void
printaddr_comment(const kernel_ulong_t addr)
{
tprintf_comment("%#llx", (unsigned long long) addr);
}
static inline void
print_mac_addr(const char *prefix, const uint8_t addr[], size_t size)
{
tprints(prefix);
tprints(sprint_mac_addr(addr, size));
}
#if SUPPORTED_PERSONALITIES > 1
extern void set_personality(unsigned int personality);
extern unsigned current_personality;
#else
# define set_personality(personality) ((void)0)
# define current_personality 0
#endif
#if SUPPORTED_PERSONALITIES == 1
# define current_wordsize PERSONALITY0_WORDSIZE
# define current_klongsize PERSONALITY0_KLONGSIZE
#else
# if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_WORDSIZE == PERSONALITY1_WORDSIZE
# define current_wordsize PERSONALITY0_WORDSIZE
# else
extern unsigned current_wordsize;
# endif
# if SUPPORTED_PERSONALITIES == 2 && PERSONALITY0_KLONGSIZE == PERSONALITY1_KLONGSIZE
# define current_klongsize PERSONALITY0_KLONGSIZE
# else
extern unsigned current_klongsize;
# endif
#endif
1999-02-19 03:21:36 +03:00
#define max_addr() (~0ULL >> ((8 - current_wordsize) * 8))
#define max_kaddr() (~0ULL >> ((8 - current_klongsize) * 8))
/*
* When u64 is interpreted by the kernel as an address, there is a difference
* in behaviour between 32-bit and 64-bit kernel in the way u64_to_user_ptr
* works (32-bit kernel trims higher bits during conversion which may result
* to a valid address). Since 32-bit strace cannot figure out what kind of
* kernel the tracee is running on, it has to account for both possibilities.
*/
#if CAN_ARCH_BE_COMPAT_ON_64BIT_KERNEL
/**
* Print raw 64-bit value as an address if it's too big to fit in strace's
* kernel_long_t.
*/
static inline void
print_big_u64_addr(const uint64_t addr)
{
if (sizeof(kernel_long_t) < 8 && addr > max_kaddr()) {
printaddr64(addr);
tprints(" or ");
}
}
#else /* !CAN_ARCH_BE_COMPAT_ON_64BIT_KERNEL */
# define print_big_u64_addr(addr_) ((void) 0)
#endif /* CAN_ARCH_BE_COMPAT_ON_64BIT_KERNEL */
#if SIZEOF_KERNEL_LONG_T > 4 \
&& (SIZEOF_LONG < SIZEOF_KERNEL_LONG_T || !defined(current_wordsize))
# define ANY_WORDSIZE_LESS_THAN_KERNEL_LONG 1
#else
# define ANY_WORDSIZE_LESS_THAN_KERNEL_LONG 0
#endif
#define DECL_PRINTNUM(name) \
extern bool \
printnum_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
ATTRIBUTE_FORMAT((printf, 3, 0)) \
/* End of DECL_PRINTNUM definition. */
DECL_PRINTNUM(short);
DECL_PRINTNUM(int);
DECL_PRINTNUM(int64);
#undef DECL_PRINTNUM
#define DECL_PRINTNUM_ADDR(name) \
extern bool \
printnum_addr_ ## name(struct tcb *, kernel_ulong_t addr) \
/* End of DECL_PRINTNUM_ADDR definition. */
DECL_PRINTNUM_ADDR(int);
DECL_PRINTNUM_ADDR(int64);
#undef DECL_PRINTNUM_ADDR
#ifndef current_wordsize
extern bool
printnum_long_int(struct tcb *, kernel_ulong_t addr,
const char *fmt_long, const char *fmt_int)
ATTRIBUTE_FORMAT((printf, 3, 0))
ATTRIBUTE_FORMAT((printf, 4, 0));
extern bool printnum_addr_long_int(struct tcb *, kernel_ulong_t addr);
static inline bool
printnum_slong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_long_int(tcp, addr, "%" PRId64, "%d");
}
static inline bool
printnum_ulong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_long_int(tcp, addr, "%" PRIu64, "%u");
}
static inline bool
printnum_ptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_long_int(tcp, addr);
}
#elif current_wordsize > 4
static inline bool
printnum_slong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_int64(tcp, addr, "%" PRId64);
}
static inline bool
printnum_ulong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_int64(tcp, addr, "%" PRIu64);
}
static inline bool
printnum_ptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_int64(tcp, addr);
}
#else /* current_wordsize == 4 */
static inline bool
printnum_slong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_int(tcp, addr, "%d");
}
static inline bool
printnum_ulong(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_int(tcp, addr, "%u");
}
static inline bool
printnum_ptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_int(tcp, addr);
}
#endif
#ifndef current_klongsize
extern bool printnum_addr_klong_int(struct tcb *, kernel_ulong_t addr);
static inline bool
printnum_kptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_klong_int(tcp, addr);
}
#elif current_klongsize > 4
static inline bool
printnum_kptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_int64(tcp, addr);
}
#else /* current_klongsize == 4 */
static inline bool
printnum_kptr(struct tcb *tcp, kernel_ulong_t addr)
{
return printnum_addr_int(tcp, addr);
}
#endif
#define DECL_PRINTPAIR(name) \
extern bool \
printpair_ ## name(struct tcb *, kernel_ulong_t addr, const char *fmt) \
ATTRIBUTE_FORMAT((printf, 3, 0)) \
/* End of DECL_PRINTPAIR definition. */
DECL_PRINTPAIR(int);
DECL_PRINTPAIR(int64);
#undef DECL_PRINTPAIR
static inline kernel_long_t
truncate_klong_to_current_wordsize(const kernel_long_t v)
{
#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
if (current_wordsize < sizeof(v)) {
return (int) v;
} else
#endif
{
return v;
}
}
static inline kernel_ulong_t
truncate_kulong_to_current_wordsize(const kernel_ulong_t v)
{
#if ANY_WORDSIZE_LESS_THAN_KERNEL_LONG
if (current_wordsize < sizeof(v)) {
return (unsigned int) v;
} else
#endif
{
return v;
}
}
/*
* Cast a pointer or a pointer-sized integer to kernel_ulong_t.
*/
#define ptr_to_kulong(v) ((kernel_ulong_t) (unsigned long) (v))
/*
* Zero-extend a signed integer type to unsigned long long.
*/
#define zero_extend_signed_to_ull(v) \
(sizeof(v) == sizeof(char) ? (unsigned long long) (unsigned char) (v) : \
sizeof(v) == sizeof(short) ? (unsigned long long) (unsigned short) (v) : \
sizeof(v) == sizeof(int) ? (unsigned long long) (unsigned int) (v) : \
sizeof(v) == sizeof(long) ? (unsigned long long) (unsigned long) (v) : \
(unsigned long long) (v))
/*
* Sign-extend an unsigned integer type to long long.
*/
#define sign_extend_unsigned_to_ll(v) \
(sizeof(v) == sizeof(char) ? (long long) (char) (v) : \
sizeof(v) == sizeof(short) ? (long long) (short) (v) : \
sizeof(v) == sizeof(int) ? (long long) (int) (v) : \
sizeof(v) == sizeof(long) ? (long long) (long) (v) : \
(long long) (v))
extern const char *const errnoent[];
extern const char *const signalent[];
extern const unsigned int nerrnos;
extern const unsigned int nsignals;
extern const struct_sysent sysent0[];
extern const struct_ioctlent ioctlent0[];
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
extern const char *const personality_names[];
#if SUPPORTED_PERSONALITIES > 1
extern const struct_sysent *sysent;
extern const struct_ioctlent *ioctlent;
#else
# define sysent sysent0
# define ioctlent ioctlent0
#endif
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
extern unsigned nsyscalls;
extern unsigned nioctlents;
1999-02-19 03:21:36 +03:00
Rewrite remaining qual_* parsers using bit sets * defs.h (struct fault_opts): Replace forward declaration with a definition. (qualbits_t, qualify_read, qualify_write, qualify_signals): Remove. (qual_flags): New function prototype. (nsyscall_vec, sysent_vec, fault_vec): New variable prototypes. * qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set): New variables. (qualify_read, qualify_write, qualify_signals): Add static qualifier. (find_errno_by_name, lookup_class, parse_fault_expression, parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault, qualify_raw, qualify_syscall, qualify_syscall_class, qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens, qualify_trace, qualify_verbose, strip_prefix): New functions. * syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier. (MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags, qual_fault, qual_syscall, qual_options, fault_opts, qualify_one, qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name, qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name, parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove. (decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall, get_scno): Update use of qual_flags. (inject_syscall_fault_entering): Update per-personality allocation of tcp->fault_vec. * tests/fault_injection-exit_group.test: Check parsing of inversed fault sets. * tests/fault_injection.test: Check parsing of -efault=none. * tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-04 17:39:48 +03:00
extern const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES];
extern const struct_sysent *const sysent_vec[SUPPORTED_PERSONALITIES];
extern struct inject_opts *inject_vec[SUPPORTED_PERSONALITIES];
Rewrite remaining qual_* parsers using bit sets * defs.h (struct fault_opts): Replace forward declaration with a definition. (qualbits_t, qualify_read, qualify_write, qualify_signals): Remove. (qual_flags): New function prototype. (nsyscall_vec, sysent_vec, fault_vec): New variable prototypes. * qualify.c (abbrev_set, fault_set, raw_set, trace_set, verbose_set): New variables. (qualify_read, qualify_write, qualify_signals): Add static qualifier. (find_errno_by_name, lookup_class, parse_fault_expression, parse_fault_token, qual_flags, qualify, qualify_abbrev, qualify_fault, qualify_raw, qualify_syscall, qualify_syscall_class, qualify_syscall_name, qualify_syscall_number, qualify_syscall_tokens, qualify_trace, qualify_verbose, strip_prefix): New functions. * syscall.c (nsyscall_vec, nsysent_vec): Remove static qualifier. (MAX_NSYSCALLS1, MAX_NSYSCALLS2, MAX_NSYSCALLS, qual_vec, qual_flags, qual_fault, qual_syscall, qual_options, fault_opts, qualify_one, qualify_scno, lookup_class, qualify_syscall_class, qualify_syscall_name, qual_syscall_ex, qual_syscall, strip_prefix, find_errno_by_name, parse_fault_token, parse_fault_expression, qual_fault, qualify): Remove. (decode_socket_subcall, decode_ipc_subcall, decode_mips_subcall, get_scno): Update use of qual_flags. (inject_syscall_fault_entering): Update per-personality allocation of tcp->fault_vec. * tests/fault_injection-exit_group.test: Check parsing of inversed fault sets. * tests/fault_injection.test: Check parsing of -efault=none. * tests/options-syntax.test: Check parsing of invalid syscall numbers.
2016-12-04 17:39:48 +03:00
#ifdef IN_MPERS_BOOTSTRAP
/* Transform multi-line MPERS_PRINTER_DECL statements to one-liners. */
# define MPERS_PRINTER_DECL(type, name, ...) MPERS_PRINTER_DECL(type, name, __VA_ARGS__)
#else /* !IN_MPERS_BOOTSTRAP */
# if SUPPORTED_PERSONALITIES > 1
# include "printers.h"
# else
# include "native_printer_decls.h"
# endif
# define MPERS_PRINTER_DECL(type, name, ...) type MPERS_FUNC_NAME(name)(__VA_ARGS__)
#endif /* !IN_MPERS_BOOTSTRAP */
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
/* Checks that sysent[scno] is not out of range. */
static inline bool
scno_in_range(kernel_ulong_t scno)
{
return scno < nsyscalls;
}
/*
* Checks whether scno is not out of range,
* its corresponding sysent[scno].sys_func is non-NULL,
* and its sysent[scno].sys_flags has no TRACE_INDIRECT_SUBCALL flag set.
*/
static inline bool
scno_is_valid(kernel_ulong_t scno)
{
return scno_in_range(scno)
&& sysent[scno].sys_func
&& !(sysent[scno].sys_flags & TRACE_INDIRECT_SUBCALL);
}
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#define MPERS_FUNC_NAME__(prefix, name) prefix ## name
#define MPERS_FUNC_NAME_(prefix, name) MPERS_FUNC_NAME__(prefix, name)
#define MPERS_FUNC_NAME(name) MPERS_FUNC_NAME_(MPERS_PREFIX, name)
#define SYS_FUNC_NAME(syscall_name) MPERS_FUNC_NAME(syscall_name)
#define SYS_FUNC(syscall_name) int SYS_FUNC_NAME(sys_ ## syscall_name)(struct tcb *tcp)
Add mpers support Add a subsystem for semi-automatical definition of how parsers should work with personality-dependent (mpers) types of tracee's data. Create auxiliary libraries containing mpers syscall parsers and printer functions, one library for each possible nonnative target personality. Currently some parsers do not handle differences in definitions of data types between personalities, namely LP64 and ILP32. When this is the case, long integers, pointers, and all compound types containing long and pointer members may be printed incorrectly, because of differences in sizes, offsets and alignments. Since in most cases these are the only differences in desired behaviour of parsers and printers for different personalities, a correct way would be to compile one source code into multiple parsers, differing only in definitions of mpers types. To get a definition of a given type for nonnative personality a very basic .c file containing a declaration of a variable of this type is being compiled for this personality (using -m32 or -mx32 compiler flag). Information about the type is then being extracted from this binary's DWARF debug info with an awk script and put into a corresponding header file. Resulting headers are being used to compile mpers variations of syscall parsers and printer functions. In addition to syscall parsers, there can occur a need to create mpers printing functions, which then can be called from many places in the code (for example, printsiginfo_at). Such functions (printers) are marked in a special manner. For each possible nonnative target personality a library is being created, containing mpers variations of syscall parsers and printers. Only syscall parsers from files marked in a special manner and specially marked functions from such files are being recompiled and included in these libraries. generate_mpers_am.sh is called by bootstrap to find the files from strace_SOURCES which include MPERS_DEFS. During compilation, these files are being inspected for inclusions of DEF_MPERS_TYPE, and nonnative variations of each included type are being generated by an awk script. Mpers parser names are being modified during inclusions of syscallent headers for nonnative personalities. Pointers to printers are being stored in structs struct_printers, and a master pointer printers is being updated on every set_personality. * README-mpers: New README explaining how to use mpers support. * empty.h: New empty file. * generate_mpers_am.sh: New file. * mpers.awk: Likewise. * mpers.sh: Likewise. * mpers_test.sh: Likewise. * mpers_type.h: Likewise. * Makefile.am (strace_SOURCES): Add empty.h and mpers_type.h. (strace_CPPFLAGS, strace_LDFLAGS, strace_LDADD): Move to the beginning of the file. (strace_LDADD, noinst_LIBRARIES): Add libmpers-%.a. (EXTRA_DIST): Add mpers.awk, mpers.sh, mpers_test.sh. (BUILT_SOURCES, CLEANFILES): Add new generated files: native_printer_decls.h, native_printer_defs.h, printers.h, [HAVE_M32_MPERS] $(mpers_m32_targets), and [HAVE_MX32_MPERS] $(mpers_mx32_targets). (mpers_NAME, mpers_PREFIX, mpers_DEFS, mpers_INCLUDES, mpers_CPPFLAGS, mpers_sh_opts, libmpers_CPPFLAGS, libmpers_m[x]32_a_SOURCES, libmpers_m[x]32_a_CPPFLAGS, mpers_m[x]32_targets): New variables. (mpers-m[x]32.stamp, m[x]32_defs.h, m[x]32_funcs.h, printers.h, %_printer_decls.h, %_printer_defs.h, clean-local, native_printer_decls.h, native_printer_defs.h, $mpers_m[x]32_targets): New targets. * bootstrap: Add generate_mpers_am.sh. * configure.ac: Add AC_PROG_RANLIB. * m4/mpers.m4: Add HAVE_MPERS variable. Add $st_cv_mpers checks. * defs.h: Include mpers_type.h. Include printers.h, native_printer_decls.h, define MPERS_PRINTER_NAME. Redefine SYS_FUNC_NAME. Define MPERS_PRINTER_DECL. [HAVE_M32_MPERS]: define PERSONALITY1_INCLUDE_FUNCS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS for X86_64, X32. [HAVE_MX32_MPERS]: define PERSONALITY2_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS for X86_64. Add fallback definitions of PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. * syscall.c: Include PERSONALITY1_INCLUDE_FUNCS, PERSONALITY2_INCLUDE_FUNCS, PERSONALITY0_INCLUDE_PRINTERS_DECLS, PERSONALITY0_INCLUDE_PRINTERS_DEFS, PERSONALITY1_INCLUDE_PRINTERS_DECLS, PERSONALITY1_INCLUDE_PRINTERS_DEFS, PERSONALITY2_INCLUDE_PRINTERS_DECLS, PERSONALITY2_INCLUDE_PRINTERS_DEFS. (printers): New struct. Update it when needed. * .gitignore: Add libmpers-m32.a, libmpers-mx32.a, m32_defs.h, m32_funcs.h, m32_printer_decls.h, m32_printer_defs.h, mpers-m32, mpers-m32.stamp, mpers-mx32, mpers-mx32.stamp, mpers.am, mx32_defs.h, mx32_funcs.h, mx32_printer_decls.h, mx32_printer_defs.h, native_printer_decls.h, native_printer_defs.h, and printers.h.
2015-08-04 01:47:02 +03:00
#endif /* !STRACE_DEFS_H */