strace/defs.h

1019 lines
32 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-2017 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 "error_prints.h"
#include "gcc_compat.h"
#include "kernel_types.h"
#include "macros.h"
#include "mpers_type.h"
#include "string_to_uint.h"
#include "supported_personalities.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
/*
* Experimental code using PTRACE_SEIZE can be enabled here.
* This needs Linux kernel 3.4.x or later to work.
*/
#define USE_SEIZE 1
/* 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"
#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"
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"
#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"
#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 1
#define INJECT_F_RETVAL 2
struct inject_data {
uint16_t flags;
uint16_t signo;
int rval;
};
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];
1999-02-19 03:21:36 +03:00
struct timeval stime; /* System time usage as of last process wait */
struct timeval dtime; /* Delta for system time usage */
struct timeval etime; /* Syscall entry time */
#ifdef USE_LIBUNWIND
struct UPT_info *libunwind_ui;
struct mmap_cache_t *mmap_cache;
unsigned int mmap_cache_size;
unsigned int mmap_cache_generation;
struct queue_t *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 */
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 */
#define QUAL_READ 0x020 /* dump data read in this syscall */
#define QUAL_WRITE 0x040 /* dump data written in this syscall */
#ifdef USE_LIBUNWIND
# define QUAL_STACKTRACE 0x080 /* do the stack trace */
#endif
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 dump_read(tcp) ((tcp)->qual_flg & QUAL_READ)
#define dump_write(tcp) ((tcp)->qual_flg & QUAL_WRITE)
#define raw(tcp) ((tcp)->qual_flg & QUAL_RAW)
#define inject(tcp) ((tcp)->qual_flg & QUAL_INJECT)
#ifdef USE_LIBUNWIND
# define stacktrace(tcp) ((tcp)->qual_flg & QUAL_STACKTRACE)
#endif
#define filtered(tcp) ((tcp)->flags & TCB_FILTERED)
#define hide_log(tcp) ((tcp)->flags & TCB_HIDE_LOG)
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[];
extern const struct xlat ethernet_protocols[];
extern const struct xlat evdev_abs[];
extern const struct xlat iffflags[];
extern const struct xlat inet_protocols[];
extern const struct xlat ip_type_of_services[];
extern const struct xlat msg_flags[];
extern const struct xlat netlink_protocols[];
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_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_DECIMAL 000 /* decimal format */
#define RVAL_HEX 001 /* hex format */
#define RVAL_OCTAL 002 /* octal format */
#define RVAL_UDECIMAL 003 /* unsigned decimal 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)
Fix decoding of 16-bit *chown and [gs]et*[gu]id syscalls Define two sets of parsers on architectures that support (either directly or via multiarch) 16-bit and 32-bit uid/gid syscalls simultaneously. Since the code in these two sets is essentially the same and the key difference between them is the size of uid_t, implement it by parametrizing uid_t and names of parser functions. * defs.h (NEED_UID16_PARSERS): New macro. * linux/syscall.h [NEED_UID16_PARSERS] (sys_chown16, sys_fchown16, sys_getresuid16, sys_getuid16, sys_setfsuid16, sys_setresuid16, sys_setreuid16, sys_setuid16): New prototypes. * linux/dummy.h (sys_geteuid16): Alias to sys_getuid16. (sys_getegid16, sys_getgid16, sys_getresgid16, sys_setfsgid16, sys_setgid16, sys_setregid16, sys_setresgid16): Alias to corresponding sys_*uid16 functions. * uid.c: Stop including <asm/posix_types.h>. Parametrize uid_t and names of all exported functions. (get_print_uid): New function. (sys_getresuid): Use it. (printuid): Check for (uid_t) -1. * uid16.c: New file. * Makefile.am (strace_SOURCES): Add it. * linux/arm/syscallent.h: Use sys_chown16, sys_fchown16, sys_getegid16, sys_geteuid16, sys_getgid16, sys_getresgid16, sys_getresuid16, sys_getuid16, sys_setfsgid16, sys_setfsuid16, sys_setgid16, sys_setregid16, sys_setresgid16, sys_setresuid16, sys_setreuid16, and sys_setuid16 parsers for *chown and [gs]et*[gu]id syscall entries. * linux/bfin/syscallent.h: Likewise. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/microblaze/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * tests/uid16.c: New file. * tests/uid16.test: New test. * tests/Makefile.am (CHECK_PROGRAMS): Add uid16. (TESTS): Add uid16.test. * tests/.gitignore: Add uid16.
2014-12-14 00:49:01 +03:00
#if defined(ARM) || defined(AARCH64) \
|| defined(I386) || defined(X32) || defined(X86_64) \
|| defined(IA64) \
Fix decoding of 16-bit *chown and [gs]et*[gu]id syscalls Define two sets of parsers on architectures that support (either directly or via multiarch) 16-bit and 32-bit uid/gid syscalls simultaneously. Since the code in these two sets is essentially the same and the key difference between them is the size of uid_t, implement it by parametrizing uid_t and names of parser functions. * defs.h (NEED_UID16_PARSERS): New macro. * linux/syscall.h [NEED_UID16_PARSERS] (sys_chown16, sys_fchown16, sys_getresuid16, sys_getuid16, sys_setfsuid16, sys_setresuid16, sys_setreuid16, sys_setuid16): New prototypes. * linux/dummy.h (sys_geteuid16): Alias to sys_getuid16. (sys_getegid16, sys_getgid16, sys_getresgid16, sys_setfsgid16, sys_setgid16, sys_setregid16, sys_setresgid16): Alias to corresponding sys_*uid16 functions. * uid.c: Stop including <asm/posix_types.h>. Parametrize uid_t and names of all exported functions. (get_print_uid): New function. (sys_getresuid): Use it. (printuid): Check for (uid_t) -1. * uid16.c: New file. * Makefile.am (strace_SOURCES): Add it. * linux/arm/syscallent.h: Use sys_chown16, sys_fchown16, sys_getegid16, sys_geteuid16, sys_getgid16, sys_getresgid16, sys_getresuid16, sys_getuid16, sys_setfsgid16, sys_setfsuid16, sys_setgid16, sys_setregid16, sys_setresgid16, sys_setresuid16, sys_setreuid16, and sys_setuid16 parsers for *chown and [gs]et*[gu]id syscall entries. * linux/bfin/syscallent.h: Likewise. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/microblaze/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * tests/uid16.c: New file. * tests/uid16.test: New test. * tests/Makefile.am (CHECK_PROGRAMS): Add uid16. (TESTS): Add uid16.test. * tests/.gitignore: Add uid16.
2014-12-14 00:49:01 +03:00
|| defined(BFIN) \
|| defined(M68K) \
|| defined(MICROBLAZE) \
|| defined(RISCV) \
Fix decoding of 16-bit *chown and [gs]et*[gu]id syscalls Define two sets of parsers on architectures that support (either directly or via multiarch) 16-bit and 32-bit uid/gid syscalls simultaneously. Since the code in these two sets is essentially the same and the key difference between them is the size of uid_t, implement it by parametrizing uid_t and names of parser functions. * defs.h (NEED_UID16_PARSERS): New macro. * linux/syscall.h [NEED_UID16_PARSERS] (sys_chown16, sys_fchown16, sys_getresuid16, sys_getuid16, sys_setfsuid16, sys_setresuid16, sys_setreuid16, sys_setuid16): New prototypes. * linux/dummy.h (sys_geteuid16): Alias to sys_getuid16. (sys_getegid16, sys_getgid16, sys_getresgid16, sys_setfsgid16, sys_setgid16, sys_setregid16, sys_setresgid16): Alias to corresponding sys_*uid16 functions. * uid.c: Stop including <asm/posix_types.h>. Parametrize uid_t and names of all exported functions. (get_print_uid): New function. (sys_getresuid): Use it. (printuid): Check for (uid_t) -1. * uid16.c: New file. * Makefile.am (strace_SOURCES): Add it. * linux/arm/syscallent.h: Use sys_chown16, sys_fchown16, sys_getegid16, sys_geteuid16, sys_getgid16, sys_getresgid16, sys_getresuid16, sys_getuid16, sys_setfsgid16, sys_setfsuid16, sys_setgid16, sys_setregid16, sys_setresgid16, sys_setresuid16, sys_setreuid16, and sys_setuid16 parsers for *chown and [gs]et*[gu]id syscall entries. * linux/bfin/syscallent.h: Likewise. * linux/i386/syscallent.h: Likewise. * linux/m68k/syscallent.h: Likewise. * linux/microblaze/syscallent.h: Likewise. * linux/s390/syscallent.h: Likewise. * linux/sparc/syscallent.h: Likewise. * linux/sh/syscallent.h: Likewise. * linux/sh64/syscallent.h: Likewise. * tests/uid16.c: New file. * tests/uid16.test: New test. * tests/Makefile.am (CHECK_PROGRAMS): Add uid16. (TESTS): Add uid16.test. * tests/.gitignore: Add uid16.
2014-12-14 00:49:01 +03:00
|| defined(S390) \
|| defined(SH) || defined(SH64) \
|| defined(SPARC) || defined(SPARC64) \
/**/
# define NEED_UID16_PARSERS 1
#else
# define NEED_UID16_PARSERS 0
#endif
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 USE_LIBUNWIND
/* if this is true do the initialization of stack tracing mechanism */
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(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);
extern int syscall_exiting_decode(struct tcb *, struct timeval *);
extern int syscall_exiting_trace(struct tcb *, struct timeval, int);
extern void syscall_exiting_finish(struct tcb *);
extern void count_syscall(struct tcb *, const struct timeval *);
extern void call_summary(FILE *);
extern void clear_regs(void);
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 syscall number to 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);
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);
}
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))
extern int
umoven_or_printaddr(struct tcb *, kernel_ulong_t addr,
unsigned int len, void *laddr);
#define umove_or_printaddr(pid, addr, objp) \
umoven_or_printaddr((pid), (addr), sizeof(*(objp)), (void *) (objp))
extern int
umoven_or_printaddr_ignore_syserror(struct tcb *, kernel_ulong_t addr,
unsigned int len, void *laddr);
extern int
umovestr(struct tcb *, kernel_ulong_t addr, unsigned int len, char *laddr);
extern int upeek(int pid, unsigned long, kernel_ulong_t *);
extern int upoke(int pid, unsigned long, kernel_ulong_t);
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);
#if defined ALPHA || defined IA64 || defined MIPS \
|| defined SH || defined SPARC || defined SPARC64
# define HAVE_GETRVAL2
extern long getrval2(struct tcb *);
#else
# undef HAVE_GETRVAL2
#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 *);
#define pathtrace_select(tcp) \
pathtrace_select_set(tcp, &global_path_set)
#define pathtrace_match(tcp) \
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);
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);
const struct xlat *genl_families_xlat(void);
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
extern int string_quote(const char *, char *, unsigned int, unsigned int);
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 printaddr(kernel_ulong_t addr);
extern int printxvals(const uint64_t, const char *, const struct xlat *, ...)
ATTRIBUTE_SENTINEL;
extern int printxval_searchn(const struct xlat *xlat, size_t xlat_size,
uint64_t val, const char *dflt);
#define printxval_search(xlat__, val__, dflt__) \
printxval_searchn(xlat__, ARRAY_SIZE(xlat__), val__, dflt__)
extern int printargs(struct tcb *);
extern int printargs_u(struct tcb *);
extern int printargs_d(struct tcb *);
extern void addflags(const struct xlat *, uint64_t);
extern int printflags_ex(uint64_t, const char *, const struct xlat *, ...)
ATTRIBUTE_SENTINEL;
extern const char *sprintflags(const char *, const struct xlat *, uint64_t);
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);
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 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 void
printstr_ex(struct tcb *, kernel_ulong_t addr, kernel_ulong_t len,
unsigned int user_style);
extern void
printpathn(struct tcb *, kernel_ulong_t addr, unsigned int n);
extern void
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 void print_ifindex(unsigned int);
Implement new filtering language parsing * basic_filters.c (lookup_class, qualify_syscall_class, qualify_syscall, qualify_syscall_tokens, parse_syscall_filter, qualify_tokens, parse_fd_filter, parse_path_filter): Add qualify_mode argument. (qualify_tokens, qualify_syscall_tokens): Use set inversion only in qualify mode. (lookup_class): Use deprecated class names only in qualify mode. * defs.h (qualify): Remove declaration. (filtering_parse): Add new declaration. * filter.c (struct filter_type, parse_filter): Add bool argument to parse_*_filter declarations. * filter.h (parse_filter_action, parse_qualify_action, parse_filter_expression): Add new declarations. (parse_filter, qualify_tokens, qualify_syscall_tokens): Add qualify_mode argument. (DECL_FILTER): Add bool argument to parse_*_filter declarations. * filter_action.c (parse_filter_action): Add new parsing function. (inject_path_tracing): Use filtering_parse instead of qualify. * filter_expression.c (parse_filter_expression): Implement parsing of filter expression. (parse_operator, push_operator, is_higher_priority): Add helper functions. (is_space_ascii, is_allowed_in_name): Add new declarations. * filter_parse.c: New file. * filter_qualify.c (qualify_read, qualify_write, qualify_signals, qualify_trace, qualify_abbrev, qualify_verbose, qualify_raw, qualify_inject_common, qualify_fault, qualify_inject): Use main_part and args arguments. * strace.c (init): Use filtering_parse instead of qualify. * Makefile.am (strace_SOURCES): Add filter_parse.c.
2017-08-28 07:28:57 +03:00
extern void filtering_parse(const char *);
extern void filtering_parsing_finish(void);
extern void filter_syscall(struct tcb *);
#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(file);
DECL_IOCTL(fs_x);
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);
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(route);
DECL_NETLINK(selinux);
DECL_NETLINK(sock_diag);
extern int tv_nz(const struct timeval *);
extern int tv_cmp(const struct timeval *, const struct timeval *);
extern double tv_float(const struct timeval *);
extern void tv_add(struct timeval *, const struct timeval *, const struct timeval *);
extern void tv_sub(struct timeval *, const struct timeval *, const struct timeval *);
extern void tv_mul(struct timeval *, const struct timeval *, int);
extern void tv_div(struct timeval *, const struct timeval *, int);
1999-02-19 03:21:36 +03:00
#ifdef USE_LIBUNWIND
extern void unwind_init(void);
extern void unwind_tcb_init(struct tcb *);
extern void unwind_tcb_fin(struct tcb *);
extern void unwind_cache_invalidate(struct tcb *);
extern void unwind_print_stacktrace(struct tcb *);
extern void unwind_capture_stacktrace(struct tcb *);
#endif
static inline void
printstrn(struct tcb *tcp, kernel_ulong_t addr, kernel_ulong_t len)
{
printstr_ex(tcp, addr, len, 0);
}
static inline void
printstr(struct tcb *tcp, kernel_ulong_t addr)
{
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, 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 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
extern void print_user_desc(struct tcb *, kernel_ulong_t addr);
#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);
#if SUPPORTED_PERSONALITIES > 1
extern void set_personality(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 ANY_WORDSIZE_LESS_THAN_KERNEL_LONG \
(SIZEOF_KERNEL_LONG_T > 4 \
&& (SIZEOF_LONG < SIZEOF_KERNEL_LONG_T || !defined(current_wordsize)))
#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);
# define printnum_slong(tcp, addr) \
printnum_long_int((tcp), (addr), "%" PRId64, "%d")
# define printnum_ulong(tcp, addr) \
printnum_long_int((tcp), (addr), "%" PRIu64, "%u")
# define printnum_ptr(tcp, addr) \
printnum_addr_long_int((tcp), (addr))
#elif current_wordsize > 4
# define printnum_slong(tcp, addr) \
printnum_int64((tcp), (addr), "%" PRId64)
# define printnum_ulong(tcp, addr) \
printnum_int64((tcp), (addr), "%" PRIu64)
# define printnum_ptr(tcp, addr) \
printnum_addr_int64((tcp), (addr))
#else /* current_wordsize == 4 */
# define printnum_slong(tcp, addr) \
printnum_int((tcp), (addr), "%d")
# define printnum_ulong(tcp, addr) \
printnum_int((tcp), (addr), "%u")
# define printnum_ptr(tcp, addr) \
printnum_addr_int((tcp), (addr))
#endif
#ifndef current_klongsize
extern bool printnum_addr_klong_int(struct tcb *, kernel_ulong_t addr);
# define printnum_kptr(tcp, addr) \
printnum_addr_klong_int((tcp), (addr))
#elif current_klongsize > 4
# define printnum_kptr(tcp, addr) \
printnum_addr_int64((tcp), (addr))
#else /* current_klongsize == 4 */
# define printnum_kptr(tcp, addr) \
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 struct_sysent sysent0[];
extern const char *const errnoent0[];
extern const char *const signalent0[];
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
#if SUPPORTED_PERSONALITIES > 1
extern const struct_sysent *sysent;
extern const char *const *errnoent;
extern const char *const *signalent;
extern const struct_ioctlent *ioctlent;
#else
# define sysent sysent0
# define errnoent errnoent0
# define signalent signalent0
# 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 nerrnos;
extern unsigned nsignals;
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 */