On Mon, 31 Jul 2017 06:19:23 +0200 Eugene Syromiatnikov <e...@redhat.com> wrote:
> On Fri, Jul 28, 2017 at 06:43:25PM +0300, Edgar Kaziakhmedov wrote: > > From: Edgar Kaziakhmedov <edgar.kaziakhme...@virtuzzo.com> > > > > The 1.2 version of asinfo tool. The asinfo tool has the > This version is not mentioned anywhere else. > > > following architecture: > > commnand dispatcher->architecture dispatcher->abi dispatcher-> > "command" > > > system call dispatcher->filter dispatcher > > > > As for arch. dispatcher, the asinfo has get-arch, list-arch, > > set-arch %name_of_arch options, arch_dispatcher is purposed to > > process them. As for abi dispatcher, the asinfo has get-abi, > > list-abi, set-abi %name_of_abi options, abi_dispatcher is putposed > > to process it. > "purposed" > > > As for command_dispatcher, for now it checks all options for > > correctness. > > Now, to find out the main principle of working, let’s consider next > > one case: > > $ asinfo get-arch > > Firstly, arch_dispatcher will return the current architecture, > > based on uname return value, after that in case of no options for > > abi_dispatcher, AD perceives it as get-abi option and returns > > corresponding for the set arch value. > > > > NOTE: syscall_dispatcher for now is not supported > > > > It is worth mentioning that this tool supports almostly all > > architectures supporting by Linux kernel. > More precisely, it supports (or, at least, should support) all > architectures/ABIs supported by strace (AFAIR RISC-V is not yet > supported by the Linux mainline kernel, for example). > > > > > * Makefile.am (SUBDIRS): Add tools directory. > > * configure.ac (AC_CONFIG_FILES): Add Makefile's. > > * tools/Makefile.am: New file. > > * tools/asinfo/Makefile.am: New file. > > * tools/asinfo/dispatchers.h: New file. Prototype abi_dispatcher, > > arch_dispatcher, and syscall_dispatcher. > > * tools/asinfo/dispatchers.c: New file. Implement it. > > * tools/asinfo/arch_interface.h: New file. Prototype methods to > > simplify work with the list of arch_descriptor. Introduce struct > > arch_descriptor. > > * tools/asinfo/arch_interface.c: New file. Implement it. > > * tools/asinfo/request_msgs.h: New file. Introduce main types of > > requests. Introduce structures for syscall_dispatcher. > > * tools/asinfo/asinfo.c: New file. Implement support of all options. > > * tools/asinfo/asinfo.1: New file. Empty man. > > > > Signed-off-by: Edgar Kaziakhmedov <edgar.kaziakhme...@virtuozzo.com> > > --- > > Makefile.am | 2 +- > > configure.ac | 2 + > > tools/Makefile.am | 28 ++ > > tools/asinfo/Makefile.am | 56 +++ > > tools/asinfo/arch_interface.c | 888 > > ++++++++++++++++++++++++++++++++++++++++++ > > tools/asinfo/arch_interface.h | 184 +++++++++ > > tools/asinfo/asinfo.1 | 0 tools/asinfo/asinfo.c | > > 196 ++++++++++ tools/asinfo/dispatchers.c | 242 ++++++++++++ > > tools/asinfo/dispatchers.h | 60 +++ > > tools/asinfo/request_msgs.h | 115 ++++++ > > 11 files changed, 1772 insertions(+), 1 deletion(-) > > create mode 100644 tools/Makefile.am > > create mode 100644 tools/asinfo/Makefile.am > > create mode 100644 tools/asinfo/arch_interface.c > > create mode 100644 tools/asinfo/arch_interface.h > > create mode 100644 tools/asinfo/asinfo.1 > > create mode 100644 tools/asinfo/asinfo.c > > create mode 100644 tools/asinfo/dispatchers.c > > create mode 100644 tools/asinfo/dispatchers.h > > create mode 100644 tools/asinfo/request_msgs.h > > > > diff --git a/Makefile.am b/Makefile.am > > index da175a27..ac40a8f2 100644 > > --- a/Makefile.am > > +++ b/Makefile.am > > @@ -35,7 +35,7 @@ endif > > if HAVE_MX32_RUNTIME > > TESTS_MX32 = tests-mx32 > > endif > > -SUBDIRS = tests $(TESTS_M32) $(TESTS_MX32) > > +SUBDIRS = tests $(TESTS_M32) $(TESTS_MX32) tools > > > > bin_PROGRAMS = strace > > man_MANS = strace.1 > > diff --git a/configure.ac b/configure.ac > > index 0d407aff..ea14e270 100644 > > --- a/configure.ac > > +++ b/configure.ac > > @@ -842,6 +842,8 @@ AC_CONFIG_FILES([Makefile > > tests/Makefile > > tests-m32/Makefile > > tests-mx32/Makefile > > + tools/Makefile > > + tools/asinfo/Makefile > > strace.spec > > debian/changelog]) > > AC_OUTPUT > > diff --git a/tools/Makefile.am b/tools/Makefile.am > > new file mode 100644 > > index 00000000..f1c75cfb > > --- /dev/null > > +++ b/tools/Makefile.am > > @@ -0,0 +1,28 @@ > > +# Automake input for strace tools. > > +# > > +# Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> +# 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. + +SUBDIRS = asinfo > > diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am > > new file mode 100644 > > index 00000000..c2d5d8b2 > > --- /dev/null > > +++ b/tools/asinfo/Makefile.am > > @@ -0,0 +1,56 @@ > > +# Automake input for asinfo. > > +# > > +# Copyright (c) 2017 Edgar Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> +# 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. + +bin_PROGRAMS = asinfo > > +man_MANS = asinfo.1 > > + > > +OS = linux > > + > > +AUTOMAKE_OPTIONS = subdir-objects > > + > > +AM_CFLAGS = $(WARN_CFLAGS) > > +AM_CPPFLAGS = -I$(builddir) \ > > + -I$(top_builddir)/$(OS) \ > > + -I$(top_srcdir)/$(OS) \ > > + -I$(top_builddir) \ > > + -I$(top_srcdir) > > +asinfo_CPPFLAGS = $(AM_CPPFLAGS) > > +asinfo_CFLAGS = $(AM_CFLAGS) > > + > > +asinfo_SOURCES = \ > Tabs after spaces. > > > + arch_interface.c \ > > + arch_interface.h \ > > + asinfo.c \ > > + dispatchers.c \ > > + dispatchers.h \ > > + ../../error_prints.c \ > > + ../../error_prints.h \ > > + ../../macros.h \ > > + requests_msgs.h \ > > + ../../xmalloc.c \ > > + ../../xmalloc.h \ > > + #end of asinfo_SOURCES > > diff --git a/tools/asinfo/arch_interface.c > > b/tools/asinfo/arch_interface.c new file mode 100644 > > index 00000000..6de6b830 > > --- /dev/null > > +++ b/tools/asinfo/arch_interface.c > > @@ -0,0 +1,888 @@ > > +/* > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> > > + * 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. > > + */ > > + > > +#include <stdio.h> > > +#include <stdlib.h> > > +#include <string.h> > > + > > +#include "arch_interface.h" > > +#include "defs.h" > > +#include "macros.h" > > +#include "xmalloc.h" > > + > > +/* Define these shorthand notations to simplify the syscallent > > files. */ +/* These flags could be useful to print group of > > syscalls */ +#define TD TRACE_DESC > > +#define TF TRACE_FILE > > +#define TI TRACE_IPC > > +#define TN TRACE_NETWORK > > +#define TP TRACE_PROCESS > > +#define TS TRACE_SIGNAL > > +#define TM TRACE_MEMORY > > +#define TST TRACE_STAT > > +#define TLST TRACE_LSTAT > > +#define TFST TRACE_FSTAT > > +#define TSTA TRACE_STAT_LIKE > > +#define TSF TRACE_STATFS > > +#define TFSF TRACE_FSTATFS > > +#define TSFA TRACE_STATFS_LIKE > > +#define NF SYSCALL_NEVER_FAILS > > +#define MA MAX_ARGS > > +#define SI STACKTRACE_INVALIDATE_CACHE > > +#define SE STACKTRACE_CAPTURE_ON_ENTER > > +#define CST COMPAT_SYSCALL_TYPES > Ugh. Looks like these shorthand definitions should be put in a > separate header. Ok, It makes sense > > > + > > +/* > > + * For the current functionality there is no need > > + * to use sen and (*sys_func)() fields in sysent struct > > + */ > > +#define SEN(syscall_name) 0, NULL > > + > > +/* dummy_sysent is purposed to set syscall_list field in > > + * inherited architectures */ > > +struct_sysent dummy_sysent[] = {}; > > + > > +/* ARCH_blackfin */ > > +struct_sysent blackfin_32bit_sysent[] = { > > + #include "bfin/syscallent.h" > > +}; > > +const int blackfin_32bit_usr1 = 0; > > +const int blackfin_32bit_usr2 = 0; > > +/* ARCH_ia64 */ > > +struct_sysent ia64_64bit_sysent[] = { > > + #include "ia64/syscallent.h" > > +}; > > +const int ia64_64bit_usr1 = SYS_socket_subcall; > > +const int ia64_64bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_m68k */ > > +struct_sysent m68k_32bit_sysent[] = { > > + #include "m68k/syscallent.h" > > +}; > > +const int m68k_32bit_usr1 = SYS_socket_subcall; > > +const int m68k_32bit_usr2 = 0; > > +/* ARCH_sparc64 64bit ABI */ > > +struct_sysent sparc64_64bit_sysent[] = { > > + #include "sparc64/syscallent.h" > > +}; > > +const int sparc64_64bit_usr1 = SYS_socket_subcall; > > +const int sparc64_64bit_usr2 = 0; > > +/* ARCH_sparc64 32bit ABI */ > > +struct_sysent sparc64_32bit_sysent[] = { > > + #include "sparc64/syscallent1.h" > > +}; > > +const int sparc64_32bit_usr1 = SYS_socket_subcall; > > +const int sparc64_32bit_usr2 = 0; > > +/* ARCH_sparc */ > > +struct_sysent sparc_32bit_sysent[] = { > > + #include "sparc/syscallent.h" > > +}; > > +const int sparc_32bit_usr1 = SYS_socket_subcall; > > +const int sparc_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_metag */ > > +struct_sysent metag_32bit_sysent[] = { > > + #include "metag/syscallent.h" > > +}; > > +const int metag_32bit_usr1 = 0; > > +const int metag_32bit_usr2 = 0; > > +/* ARCH_mips o32 ABI */ > > +#ifndef LINUX_MIPSO32 > > +# define LINUX_MIPSO32 1 > > +# define NOW_DEFINED 1 > > +#endif > > +struct_sysent mips_o32_sysent[] = { > > + #include "dummy.h" > > + #include "mips/syscallent-compat.h" > > + #include "mips/syscallent-o32.h" > > +}; > > +#ifdef NOW_DEFINED > > +# undef LINUX_MIPSO32 > > +# undef NOW_DEFINED > > +#endif > > +const int mips_o32_usr1 = SYS_socket_subcall; > > +const int mips_o32_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_mips n32 ABI */ > > +#ifndef LINUX_MIPSN32 > > +# define LINUX_MIPSN32 1 > > +# define NOW_DEFINED 1 > > +#endif > > +struct_sysent mips_n32_sysent[] = { > > + #include "dummy.h" > > + #include "mips/syscallent-compat.h" > > + #include "mips/syscallent-n32.h" > > +}; > > +#ifdef NOW_DEFINED > > +# undef LINUX_MIPSN32 > > +# undef NOW_DEFINED > > +#endif > > +const int mips_n32_usr1 = SYS_socket_subcall; > > +const int mips_n32_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_mips n64 ABI */ > > +#ifndef LINUX_MIPSN64 > > +# define LINUX_MIPSN64 1 > > +# define NOW_DEFINED 1 > > +#endif > > +struct_sysent mips_n64_sysent[] = { > > + #include "dummy.h" > > + #include "mips/syscallent-compat.h" > > + #include "mips/syscallent-n64.h" > > +}; > > +#ifdef NOW_DEFINED > > +# undef LINUX_MIPSN32 > > +# undef NOW_DEFINED > > +#endif > > +const int mips_n64_usr1 = SYS_socket_subcall; > > +const int mips_n64_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_alpha */ > > +struct_sysent alpha_64bit_sysent[] = { > > + #include "alpha/syscallent.h" > > +}; > > +const int alpha_64bit_usr1 = 0; > > +const int alpha_64bit_usr2 = 0; > > +/* ARCH_ppc */ > > +struct_sysent ppc_32bit_sysent[] = { > > + #include "powerpc/syscallent.h" > > +}; > > +const int ppc_32bit_usr1 = SYS_socket_subcall; > > +const int ppc_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_ppc64 64bit ABI */ > > +struct_sysent ppc64_64bit_sysent[] = { > > + #include "powerpc64/syscallent.h" > > +}; > > +const int ppc64_64bit_usr1 = SYS_socket_subcall; > > +const int ppc64_64bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_ppc64 32bit ABI */ > > +struct_sysent ppc64_32bit_sysent[] = { > > + #include "powerpc64/syscallent1.h" > > +}; > > +const int ppc64_32bit_usr1 = SYS_socket_subcall; > > +const int ppc64_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_arm OABI*/ > > +#ifdef __ARM_EABI__ > > +# undef __ARM_EABI__ > > +# define NOW_UNDEFINED 1 > > +#endif > > +struct_sysent arm_oabi_sysent[] = { > > + #include "arm/syscallent.h" > > +}; > > +const int arm_oabi_usr1 = SYS_socket_subcall; > > +const int arm_oabi_usr2 = ARM_FIRST_SHUFFLED_SYSCALL; > > +#undef ARM_FIRST_SHUFFLED_SYSCALL > > +#undef SYS_socket_subcall > > +#ifdef NOW_UNDEFINED > > +# define __ARM_EABI__ 1 > > +# undef NOW_UNDEFINED > > +#endif > > +/* ARCH_arm EABI*/ > > +#ifndef __ARM_EABI__ > > +# define __ARM_EABI__ 1 > > +# define NOW_DEFINED 1 > > +#endif > > +struct_sysent arm_eabi_sysent[] = { > > + #include "arm/syscallent.h" > > +}; > > +const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; > > +const int arm_eabi_usr2 = 0; > > +#undef ARM_FIRST_SHUFFLED_SYSCALL > > +#ifdef NOW_DEFINED > > +# undef __ARM_EABI__ > > +# undef NOW_DEFINED > > +#endif > > +/* ARCH_aarch64 64bit ABI */ > > +struct_sysent aarch64_64bit_sysent[] = { > > + #include "aarch64/syscallent.h" > > +}; > > +const int aarch64_64bit_usr1 = 0; > > +const int aarch64_64bit_usr2 = 0; > > +/* ARCH_aarch64 32bit ABI */ > > +#ifndef __ARM_EABI__ > > +# define __ARM_EABI__ 1 > > +# define NOW_DEFINED 1 > > +#endif > > +struct_sysent aarch64_32bit_sysent[] = { > > + #include "aarch64/syscallent1.h" > > +}; > > +const int aarch64_32bit_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; > > +const int aarch64_32bit_usr2 = ARM_LAST_SPECIAL_SYSCALL; > > +#undef ARM_FIRST_SHUFFLED_SYSCALL > > +#undef ARM_LAST_SPECIAL_SYSCALL > > +#ifdef NOW_DEFINED > > +# undef __ARM_EABI__ > > +# undef NOW_DEFINED > > +#endif > > +/* ARCH_avr32 */ > > +struct_sysent avr32_32bit_sysent[] = { > > + #include "avr32/syscallent.h" > > +}; > > +const int avr32_32bit_usr1 = 0; > > +const int avr32_32bit_usr2 = 0; > > +/* ARCH_arc */ > > +struct_sysent arc_32bit_sysent[] = { > > + #include "arc/syscallent.h" > > +}; > > +const int arc_32bit_usr1 = 0; > > +const int arc_32bit_usr2 = 0; > > +/* ARCH_s390 */ > > +struct_sysent s390_32bit_sysent[] = { > > + #include "s390/syscallent.h" > > +}; > > +const int s390_32bit_usr1 = SYS_socket_subcall; > > +const int s390_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_s390x */ > > +struct_sysent s390x_64bit_sysent[] = { > > + #include "s390x/syscallent.h" > > +}; > > +const int s390x_64bit_usr1 = SYS_socket_subcall; > > +const int s390x_64bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_hppa */ > > +struct_sysent hppa_32bit_sysent[] = { > > + #include "hppa/syscallent.h" > > +}; > > +const int hppa_32bit_usr1 = 0; > > +const int hppa_32bit_usr2 = 0; > > +/* ARCH_parisc */ > > +#define parisc_32bit_sysent dummy_sysent > > +const int parisc_32bit_usr1 = 0; > > +const int parisc_32bit_usr2 = 0; > > +/* ARCH_sh */ > > +struct_sysent sh_32bit_sysent[] = { > > + #include "sh/syscallent.h" > > +}; > > +const int sh_32bit_usr1 = SYS_socket_subcall; > > +const int sh_32bit_usr2 = 0; > > +/* ARCH_sh64 */ > > +struct_sysent sh64_64bit_sysent[] = { > > + #include "sh64/syscallent.h" > > +}; > > +const int sh64_64bit_usr1 = SYS_socket_subcall; > > +const int sh64_64bit_usr2 = 0; > > +/* ARCH_x86 */ > > +struct_sysent x86_32bit_sysent[] = { > > + #include "i386/syscallent.h" > > +}; > > +const int x86_32bit_usr1 = SYS_socket_subcall; > > +const int x86_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_i386 */ > > +#define i386_32bit_sysent dummy_sysent > > +const int i386_32bit_usr1 = 0; > > +const int i386_32bit_usr2 = 0; > > +/* ARCH_i486 */ > > +#define i486_32bit_sysent dummy_sysent > > +const int i486_32bit_usr1 = 0; > > +const int i486_32bit_usr2 = 0; > > +/* ARCH_i586 */ > > +#define i586_32bit_sysent dummy_sysent > > +const int i586_32bit_usr1 = 0; > > +const int i586_32bit_usr2 = 0; > > +/* ARCH_i686 */ > > +#define i686_32bit_sysent dummy_sysent > > +const int i686_32bit_usr1 = 0; > > +const int i686_32bit_usr2 = 0; > > +/* ARCH_x86_64 64bit ABI mode */ > > +struct_sysent x86_64_64bit_sysent[] = { > > + #include "x86_64/syscallent.h" > > +}; > > +const int x86_64_64bit_usr1 = 0; > > +const int x86_64_64bit_usr2 = 0; > > +/* ARCH_x86_64 32bit ABI mode */ > > +struct_sysent x86_64_32bit_sysent[] = { > > + #include "x86_64/syscallent1.h" > > +}; > > +const int x86_64_32bit_usr1 = SYS_socket_subcall; > > +const int x86_64_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_x86_64 x32 ABI mode */ > > +struct_sysent x86_64_x32_sysent[] = { > > + #include "x86_64/syscallent2.h" > > +}; > > +const int x86_64_x32_usr1 = 0; > > +const int x86_64_x32_usr2 = 0; > > +/* ARCH_amd64 */ > > +#define amd64_64bit_sysent dummy_sysent > > +const int amd64_64bit_usr1 = 0; > > +const int amd64_64bit_usr2 = 0; > > +/* ARCH_cris */ > > +struct_sysent cris_32bit_sysent[] = { > > + #include "crisv10/syscallent.h" > > +}; > > +const int cris_32bit_usr1 = SYS_socket_subcall; > > +const int cris_32bit_usr2 = 0; > > +/* ARCH_crisv10 */ > > +#define crisv10_32bit_sysent dummy_sysent > > +const int crisv10_32bit_usr1 = 0; > > +const int crisv10_32bit_usr2 = 0; > > +/* ARCH_crisv32 */ > > +struct_sysent crisv32_32bit_sysent[] = { > > + #include "crisv32/syscallent.h" > > +}; > > +const int crisv32_32bit_usr1 = SYS_socket_subcall; > > +const int crisv32_32bit_usr2 = 0; > > +#undef SYS_socket_subcall > > +/* ARCH_tile 64bit ABI mode */ > > +struct_sysent tile_64bit_sysent[] = { > > + #include "tile/syscallent.h" > > +}; > > +const int tile_64bit_usr1 = 0; > > +const int tile_64bit_usr2 = 0; > > +/* ARCH_tile 32bit ABI mode */ > > +struct_sysent tile_32bit_sysent[] = { > > + #include "tile/syscallent1.h" > > +}; > > +const int tile_32bit_usr1 = 0; > > +const int tile_32bit_usr2 = 0; > > +/* ARCH_microblaze */ > > +struct_sysent microblaze_32bit_sysent[] = { > > + #include "microblaze/syscallent.h" > > +}; > > +const int microblaze_32bit_usr1 = 0; > > +const int microblaze_32bit_usr2 = 0; > > +/* ARCH_nios2 */ > > +struct_sysent nios2_32bit_sysent[] = { > > + #include "nios2/syscallent.h" > > +}; > > +const int nios2_32bit_usr1 = 0; > > +const int nios2_32bit_usr2 = 0; > > +/* ARCH_openrisc */ > > +struct_sysent openrisc_32bit_sysent[] = { > > + #include "or1k/syscallent.h" > > +}; > > +const int openrisc_32bit_usr1 = 0; > > +const int openrisc_32bit_usr2 = 0; > > +/* ARCH_xtensa */ > > +struct_sysent xtensa_32bit_sysent[] = { > > + #include "xtensa/syscallent.h" > > +}; > > +const int xtensa_32bit_usr1 = 0; > > +const int xtensa_32bit_usr2 = 0; > > +/* ARCH_riscv 64bit ABI mode */ > > +struct_sysent riscv_64bit_sysent[] = { > > + #include "riscv/syscallent.h" > > +}; > > +const int riscv_64bit_usr1 = 0; > > +const int riscv_64bit_usr2 = 0; > > +/* ARCH_riscv 32bit ABI mode */ > > +struct_sysent riscv_32bit_sysent[] = { > > + #include "riscv/syscallent1.h" > > +}; > > +const int riscv_32bit_usr1 = 0; > > +const int riscv_32bit_usr2 = 0; > > I'd strongly prefer this code being generated. There's already too > much burden for adding a new architecture support. > > > + > > +#undef DEFINE_SYSCALLENT > > + > > +#undef SEN > > +#undef TD > > +#undef TF > > +#undef TI > > +#undef TN > > +#undef TP > > +#undef TS > > +#undef TM > > +#undef TST > > +#undef TLST > > +#undef TFST > > +#undef TSTA > > +#undef TSF > > +#undef TFSF > > +#undef TSFA > > +#undef NF > > +#undef MA > > +#undef SI > > +#undef SE > > +#undef CST > > + > > +#define ARCH_DESC_DEFINE(arch, base_arch, mode) \ > > + [ARCH_##arch##_##mode] = { \ > > + .arch_num = ARCH_##arch##_##mode, \ > > + .arch_name = #arch, \ > > + .arch_name_len = ARRAY_SIZE(#arch) > > - 1, \ > > + .arch_base_num = > > ARCH_##base_arch##_##mode, \ > > + .abi_mode = #mode, \ > > + .abi_mode_len = ARRAY_SIZE(#arch) - > > 1, \ > > + .max_scn = > > ARRAY_SIZE(arch##_##mode##_sysent), \ > > + .list_of_syscall = arch##_##mode##_sysent, \ > "syscall_list" sounds more natural. > > > + .user_num1 = &arch##_##mode##_usr1, > > \ > > + .user_num2 = &arch##_##mode##_usr2, > > \ > > + .flag = AD_FLAG_EMPTY \ > > + } > > + > > +/* Generate array of arch_descriptors for each architecture and > > mode */ +struct arch_descriptor architectures[] = { > > + ARCH_DESC_DEFINE(blackfin, blackfin, > > 32bit ), > > + ARCH_DESC_DEFINE(ia64, ia64, > > 64bit ), > > + ARCH_DESC_DEFINE(m68k, m68k, > > 32bit ), > > + ARCH_DESC_DEFINE(sparc64, sparc64, > > 64bit ), > > + ARCH_DESC_DEFINE(sparc64, sparc64, > > 32bit ), > > + ARCH_DESC_DEFINE(sparc, > > sparc, 32bit ), > > + ARCH_DESC_DEFINE(metag, > > metag, 32bit ), > > + ARCH_DESC_DEFINE(mips, mips, > > o32 ), > > + ARCH_DESC_DEFINE(mips, mips, > > n32 ), > > + ARCH_DESC_DEFINE(mips, mips, > > n64 ), > > + ARCH_DESC_DEFINE(alpha, > > alpha, 64bit ), > > + ARCH_DESC_DEFINE(ppc, ppc, > > 32bit ), > > + ARCH_DESC_DEFINE(ppc64, > > ppc64, 64bit ), > > + ARCH_DESC_DEFINE(ppc64, > > ppc64, 32bit ), > > + ARCH_DESC_DEFINE(arm, arm, > > oabi ), > > + ARCH_DESC_DEFINE(arm, arm, > > eabi ), > > + ARCH_DESC_DEFINE(aarch64, aarch64, > > 64bit ), > > + ARCH_DESC_DEFINE(aarch64, aarch64, > > 32bit ), > > + ARCH_DESC_DEFINE(avr32, > > avr32, 32bit ), > > + ARCH_DESC_DEFINE(arc, arc, > > 32bit ), > > + ARCH_DESC_DEFINE(s390, s390, > > 32bit ), > > + ARCH_DESC_DEFINE(s390x, > > s390x, 64bit ), > > + ARCH_DESC_DEFINE(hppa, hppa, > > 32bit ), > > + ARCH_DESC_DEFINE(parisc, hppa, > > 32bit ), > > + ARCH_DESC_DEFINE(sh, sh, > > 32bit ), > > + ARCH_DESC_DEFINE(sh64, sh64, > > 64bit ), > > + ARCH_DESC_DEFINE(x86, x86, > > 32bit ), > > + ARCH_DESC_DEFINE(i386, x86, > > 32bit ), > > + ARCH_DESC_DEFINE(i486, x86, > > 32bit ), > > + ARCH_DESC_DEFINE(i586, x86, > > 32bit ), > > + ARCH_DESC_DEFINE(i686, x86, > > 32bit ), > > + ARCH_DESC_DEFINE(x86_64, x86_64, > > 64bit ), > > + ARCH_DESC_DEFINE(x86_64, x86_64, > > 32bit ), > > + ARCH_DESC_DEFINE(x86_64, x86_64, > > x32 ), > > + ARCH_DESC_DEFINE(amd64, > > x86_64, 64bit ), > > + ARCH_DESC_DEFINE(cris, cris, > > 32bit ), > > + ARCH_DESC_DEFINE(crisv10, cris, > > 32bit ), > > + ARCH_DESC_DEFINE(crisv32, crisv32, > > 32bit ), > > + ARCH_DESC_DEFINE(tile, tile, > > 64bit ), > > + ARCH_DESC_DEFINE(tile, tile, > > 32bit ), > > + ARCH_DESC_DEFINE(microblaze, microblaze, > > 32bit ), > > + ARCH_DESC_DEFINE(nios2, > > nios2, 32bit ), > > + ARCH_DESC_DEFINE(openrisc, openrisc, > > 32bit ), > > + ARCH_DESC_DEFINE(xtensa, xtensa, > > 32bit ), > > + ARCH_DESC_DEFINE(riscv, > > riscv, 64bit ), > > + ARCH_DESC_DEFINE(riscv, > > riscv, 32bit ) > Looks like we definitely need list of personality names for each > architecture. When we don't have a several personalities for architecture, we just set the default bitness. > > > +}; > > + > > +/* To make architectures array usable for dispatchers.c */ > > +const int architectures_size = ARRAY_SIZE(architectures); > > + > > +#undef ARCH_DESC_DEFINE > > + > > +struct arch_service * > > +al_create(unsigned int capacity) > > +{ > > + struct arch_service *as = xcalloc(sizeof(*as), 1); > > + > > + if (capacity) > > + as->arch_list = xcalloc(sizeof(*(as->arch_list)), > > capacity); > > + as->capacity = capacity; > > + as->next_free = 0; > > + return as; > > +} > > + > > +int > > +al_push(struct arch_service *m, struct arch_descriptor *element) > > +{ > > + if (m->next_free >= m->capacity) > > + return -1; > > + m->arch_list[m->next_free] = element; > > + m->arch_list[m->next_free]->flag = AD_FLAG_EMPTY; > I'd prefer having arch descriptors immutable and mutable flag being > outside them, as a part of arch_service container. Is sounds reasonable. > > > + m->next_free++; > > + return 0; > > +} > > + > > +static inline int > > +al_is_index_ok(struct arch_service *m, unsigned index) { > > + if (index >= m->next_free) > > + return -1; > > + return 0; > > +} > > + > > +int > > +al_set_flag(struct arch_service *m, unsigned index, int flag) > > +{ > > + if (al_is_index_ok(m, index) == 0) { > > + m->arch_list[index]->flag = flag; > > + return 0; > > + } > > + return -1; > > +} > > + > > +struct arch_descriptor * > > +al_get(struct arch_service *m, unsigned index) > > +{ > > + if (al_is_index_ok(m, index) != 0) > > + return NULL; > > + return m->arch_list[index]; > > +} > > + > > +unsigned int > > +al_size(struct arch_service *m) > > +{ > > + return m->next_free; > > +} > > + > > +unsigned int > > +al_base_size(struct arch_service *m) > > +{ > > + int arch_size = al_size(m); > > + int i = 0; > > + unsigned count = 0; > > + > > + for (i = 0; i < arch_size; i++) > > + if (m->arch_list[i]->arch_num == > > + m->arch_list[i]->arch_base_num) > > + count++; > > + return count; > > +} > > + > > +void > > +al_free(struct arch_service *m) > > +{ > > + free(m->arch_list); > > + free(m); > > +} > > + > > +enum arch_type > > +al_arch_num(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->arch_num : ARCH_no_arch); > > +} > > + > > +const char * > > +al_arch_name(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->arch_name : NULL); > > +} > > + > > +int > > +al_arch_name_len(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->arch_name_len : -1); > > +} > > + > > +enum arch_type > > +al_arch_base_num(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->arch_base_num : ARCH_no_arch); > > +} > > + > > +const char * > > +al_abi_mode(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->abi_mode : NULL); > > +} > > + > > +int > > +al_abi_mode_len(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->abi_mode_len : -1); > > +} > > + > > +int > > +al_flag(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + > > + return (elem ? elem->flag : -1); > > +} > > + > > +int > > +al_syscall_impl(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + int i = 0; > > + int count = 0; > > + > > + if (elem == NULL) > > + return -1; > > + for (i = 0; i < elem->max_scn; i++) { > > + if (elem->list_of_syscall[i].sys_name && > > + !(elem->list_of_syscall[i].sys_flags & > > + TRACE_INDIRECT_SUBCALL)) > > + count++; > > + } > > + return count; > > +} > > + > > +/* This method is purposed to find base arch > > + * NOTE: base arch is the arch, where arch_num is equal to > > arch_base_num > > + * with default ABI mode */ > > +int > > +al_find_base_arch(struct arch_service *m, unsigned index) > > +{ > > + enum arch_type base_arch = ARCH_no_arch; > > + int arch_size = al_size(m); > > + int i = 0; > > + > > + /* If given arch meets conditions above then return this > > index */ > > + if (al_is_index_ok(m, index) != 0) > > + return -1; > > + /* Search base arch */ > > + base_arch = al_arch_base_num(m, index); > > + for (i = 0; i < arch_size; i++) > > + if ((strcmp(al_arch_name(m, index), > > al_arch_name(m, i)) == 0) > > + || (al_arch_base_num(m, i) == base_arch)) > > + return i; > > + return -1; > > +} > > + > > +/* This method is purposed to count the supported ABI modes for > > the given > > + arch > > + NOTE: Firstly, do not forget to find base arch */ > > +int > > +al_get_abi_modes(struct arch_service *m, unsigned index) > > +{ > > + const char *arch_name = al_arch_name(m, index); > > + int arch_size = al_size(m); > > + int i = 0; > > + int abi_count = 0; > > + > > + if (!arch_name) > > + return -1; > > + for (i = 0; i < arch_size; i++) > > + if (strcmp(arch_name, al_arch_name(m, i)) == 0) > > + abi_count++; > > + return abi_count; > > +} > > + > > +/* This method is purposed to check on uniqueness, in sense of > > arch name, > > + without taking into account ABI modes */ > > +int > > +al_is_arch_unique(struct arch_service *m, unsigned index) > > +{ > > + enum arch_type base_arch = ARCH_no_arch; > > + int arch_size = al_size(m); > > + int i = 0; > > + > > + if (al_arch_num(m, index) != al_arch_base_num(m, index) || > > + al_arch_num(m, index) == ARCH_no_arch) > > + return -1; > > + base_arch = al_arch_base_num(m, index); > > + for (i = 0; i < arch_size; i++) > > + if ((al_arch_num(m, i) == base_arch) && > > + (i != (int)index)) > > + return -1; > > + return 0; > > +} > > + > > > +enum impl_type > > +al_ipc_syscall(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + int i; > > + enum impl_type impl_buf = IMPL_int; > > + > > + for (i = 0; i < elem->max_scn; i++) { > > + if (elem->list_of_syscall[i].sys_name == NULL) > > + continue; > > + if (strcmp(elem->list_of_syscall[i].sys_name, > > "ipc") == 0) > > + impl_buf = IMPL_int; > > + /* It is enough to find just semop sybcall */ > > + if ((strcmp(elem->list_of_syscall[i].sys_name, > > "semop") == 0) > > + && !((elem->list_of_syscall[i].sys_flags & > > + TRACE_INDIRECT_SUBCALL))) { > > + if (impl_buf == IMPL_int) > > + impl_buf = IMPL_int_ext; > > + else > > + impl_buf = IMPL_ext; > > + } > > + } > > + return impl_buf; > > +} > > + > > +enum impl_type > > +al_sck_syscall(struct arch_service *m, unsigned index) > > +{ > > + struct arch_descriptor *elem = al_get(m, index); > > + int i; > > + enum impl_type impl_buf = IMPL_int; > > + > > + for (i = 0; i < elem->max_scn; i++) { > > + if (elem->list_of_syscall[i].sys_name == NULL) > > + continue; > > + if (strcmp(elem->list_of_syscall[i].sys_name, > > + "socketcall") == 0) > > + impl_buf = IMPL_int; > > + /* It is enough to find just socket sybcall */ > > + if ((strcmp(elem->list_of_syscall[i].sys_name, > > "socket") == 0) > > + && (!(elem->list_of_syscall[i].sys_flags & > > + TRACE_INDIRECT_SUBCALL))) { > > + if (impl_buf == IMPL_int) > > + impl_buf = IMPL_int_ext; > > + else > > + impl_buf = IMPL_ext; > > + } > > + } > > + return impl_buf; > > +} > For this, I think some generator similar to ioctlsort could be used, > which allows generating list of ID's of syscalls on different > architectures. Or simple wrapper for generate_sen.h, which allows > accessing them vis SEN_<arch>_<syscall> constants. To get rid of strcmp as I understand? > > > + > > +int al_find_arch(struct arch_service *m, enum arch_type a_type) > > +{ > > + int arch_size = al_size(m); > > + int i; > > + > > + for (i = 0; i < arch_size; i++) > > + if (al_arch_num(m, i) == a_type) > > + return i; > > + return -1; > > +} > > + > > +/* This method is purposed to find next one name of the same > > architecture. > > + For instance, x86_64 = amd64 */ > > +int > > +al_next_arch_name(struct arch_service *m, unsigned index) > > +{ > > + static int next_arch = -1; > > + int i = 0; > > + int arch_size = al_size(m); > > + > > + if (next_arch == -1) > > + next_arch = index; > > + else > > + next_arch++; > > + if (al_arch_num(m, index) != al_arch_base_num(m, index) || > > + al_arch_num(m, index) == ARCH_no_arch) > > + return -1; > > + for (i = next_arch; i < arch_size; i++) { > > + next_arch = -1; > > + if (strcmp(al_arch_name(m, index), al_arch_name(m, > > i)) == 0) > > + continue; > > + if (al_arch_base_num(m, index) == > > al_arch_base_num(m, i)) { > > + next_arch = i; > > + break; > > + } > > + break; > > + } > > + if (next_arch >= arch_size) > > + next_arch = -1; > > + return next_arch; > > +} > > + > > +//len could optimized > > +//arch_list_size 11 > > +void > > +al_dump(struct arch_service *m) > > +{ > > + const char *title[] = { > > + "N", > > + "Architecture name", > > + "ABI mode", > > + /* Implemented syscalls */ > > + "IMPL syscalls", > > + /* IPC implementation */ > > + "IPC IMPL", > > + /* SOCKET implementation */ > > + "SOCKET IMPL" > > + }; > > + const char *impl_st[] = { > > + "external", > > + "internal", > > + "int/ext" > > + }; > > + int i = 0; > > + int lbase_arch = 0; > > + int temp_len = 0; > > + int arch_number_col = 0; > > + int arch_name_col = strlen(title[1]); > > + int arch_abi_col = strlen(title[2]); > > + /* It is hard to imagine arch with more than 10^13 > > syscalls */ > Actually, it's difficult to have more than 2^32 syscalls. > > > + int arch_impl_sc_col = strlen(title[3]); > > + int arch_ipc_col = strlen(title[4]); > > + int arch_sck_col = strlen(title[5]); > > + int arch_size = al_size(m); > > + int arch_base_size = al_base_size(m); > > + int N = 0; > > + int next_name = 0; > > + char *arch_name_buf; > > + > > + /* Calculate length of the column with the number of > > architectures */ > > + for (i = 1; arch_base_size/i != 0; i *= 10) > > + arch_number_col++; > > + for (i = 0; i < arch_size; i++) { > > + /* Calculate length of the column with the > > + architectures name */ > > + if (al_is_arch_unique(m, i) == -1) > > + continue; > > + lbase_arch = al_find_base_arch(m, i); > > + temp_len = al_arch_name_len(m, lbase_arch); > > + while ((next_name = al_next_arch_name(m, > > lbase_arch)) != -1) { > > + temp_len += al_arch_name_len(m, next_name); > > + /* To take into account delim symbol */ > > + temp_len++; > > + } > > + if (temp_len > arch_name_col) { > > + arch_name_col = temp_len; > > + } > Braces can be omitted here. > > > + /* Calculate length of the column with the ABI > > mode */ > > + if (al_abi_mode_len(m, i) > arch_abi_col) > > + arch_abi_col = al_abi_mode_len(m, i); > > + > Stay empty line. > > > + } > The complexity of this loop frightens me. Is it n^3? Sure, it is disgusting, I have reduced complexity to n. > > > + arch_name_buf = xcalloc(arch_name_col, > > sizeof(*arch_name_buf)); > > + /* Output title */ > > + printf("| %*s | %*s | %*s | %*s | %*s | %*s |\n", > > + arch_number_col, title[0], arch_name_col, title[1], > > + arch_abi_col, title[2], arch_impl_sc_col, title[3], > > + arch_ipc_col, title[4], arch_sck_col, title[5]); > > + /* Output architectures */ > > + for (i = 0; i < arch_size; i++) { > > + if ((al_is_arch_unique(m, i) == -1) || > > + !(al_flag(m, i) & AD_FLAG_PRINT)) > > + continue; > > + printf("| %*u | ", arch_number_col, N + 1); > > + /* Put all the same arch back together */ > > + strcat(arch_name_buf, al_arch_name(m, i)); > > + lbase_arch = al_find_base_arch(m, i); > > + while ((next_name = al_next_arch_name(m, > > lbase_arch)) != -1) { > > + strcat(arch_name_buf, "/"); > > + strcat(arch_name_buf, al_arch_name(m, > > next_name)); > > + } > > + printf("%*s | ", arch_name_col, arch_name_buf); > > + printf("%*s | ", arch_abi_col, al_abi_mode(m, i)); > > + printf("%*d | ", arch_impl_sc_col, > > al_syscall_impl(m, i)); > > + printf("%*s | ", arch_ipc_col, > > impl_st[al_ipc_syscall(m, i)]); > > + printf("%*s |\n", arch_sck_col, > > impl_st[al_sck_syscall(m, i)]); > > + N++; > > + memset(arch_name_buf, 0, arch_name_col); > > + } > > + free(arch_name_buf); > > +} > > diff --git a/tools/asinfo/arch_interface.h > > b/tools/asinfo/arch_interface.h new file mode 100644 > > index 00000000..a7a6d320 > > --- /dev/null > > +++ b/tools/asinfo/arch_interface.h > > @@ -0,0 +1,184 @@ > > +/* > > + * The arch_interface.h is purposed to interact with the basic > > data structure > > + * based on arch_descriptor struct. Mainly this set of methods are > > used by > > + * arch_dispatcher. > > + * > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhm...@virtuozzo.com> > > + * 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 ASINFO_ARCH_INTERFACE > > +#define ASINFO_ARCH_INTERFACE > > + > > +#include "sysent.h" > > + > > +/* Type implementaion of syscall, internal means as a subcall, > > + external means a separate syscall, this enum is purposed for > > + well-known ipc and socket subcall group */ > > +enum impl_type { > > + IMPL_ext, > > + IMPL_int, > > + IMPL_int_ext > > +}; > > + > > +/* Names of architectures > > + * arch_type format name_arch = ARCH_ + kernel_arch/others_name + > > abi_mode */ +enum arch_type { > So, are these architecture types or architecture names? > > > + ARCH_blackfin_32bit, > > + ARCH_ia64_64bit, > > + ARCH_m68k_32bit, > > + ARCH_sparc64_64bit, > > + ARCH_sparc64_32bit, > > + ARCH_sparc_32bit, > > + ARCH_metag_32bit, > > + ARCH_mips_o32, > > + ARCH_mips_n32, > > + ARCH_mips_n64, > > + ARCH_alpha_64bit, > > + ARCH_ppc_32bit, > > + ARCH_ppc64_64bit, > > + ARCH_ppc64_32bit, > > + ARCH_arm_oabi, > > + ARCH_arm_eabi, > > + ARCH_aarch64_64bit, > > + ARCH_aarch64_32bit, > > + ARCH_avr32_32bit, > > + ARCH_arc_32bit, > > + ARCH_s390_32bit, > > + ARCH_s390x_64bit, > > + ARCH_hppa_32bit, > > + ARCH_parisc_32bit, > > + ARCH_sh_32bit, > > + ARCH_sh64_64bit, > > + ARCH_x86_32bit, > > + ARCH_i386_32bit, > > + ARCH_i486_32bit, > > + ARCH_i586_32bit, > > + ARCH_i686_32bit, > > + ARCH_x86_64_64bit, > > + ARCH_x86_64_32bit, > > + ARCH_x86_64_x32, > > + ARCH_amd64_64bit, > > + ARCH_cris_32bit, > > + ARCH_crisv10_32bit, > > + ARCH_crisv32_32bit, > > + ARCH_tile_64bit, > > + ARCH_tile_32bit, > > + ARCH_microblaze_32bit, > > + ARCH_nios2_32bit, > > + ARCH_openrisc_32bit, > > + ARCH_xtensa_32bit, > > + ARCH_riscv_64bit, > > + ARCH_riscv_32bit, > > + ARCH_no_arch > > +}; > > + > > +#define AD_FLAG_EMPTY 0 > > +/* Actually, this flag is purposed to hide some abi modes while > > printing in > > + one arch group > > + NOTE: arch group means base arch name + others */ > > +#define AD_FLAG_PRINT 1 > > + > > +struct arch_descriptor { > > + enum arch_type arch_num; > > + const char *arch_name; > > + const int arch_name_len; > > + enum arch_type arch_base_num; > > + //enum abi_type abi_mode; > > + const char *abi_mode; > > + const int abi_mode_len; > > + const int max_scn; > > + struct_sysent *list_of_syscall; > > + /* In the most cases these fields are purposed to store > > specific for > > + given arch constants, for instance, socket_subcall > > index etc */ > This sounds scary, taking into account the fact that these fields are > not used, actually. For now, yes, but later it will be used to find subcalls in syscallent array. > > > + const int *user_num1; > > + const int *user_num2; > > + /* User flags */ > > + int flag; > > +}; > > + > > +/* To provide push-back interface with arch_list */ > > +struct arch_service { > > + struct arch_descriptor **arch_list; > > + unsigned capacity; > > + unsigned next_free; > > +}; > > + > > +#define ARCH_LIST_DEFINE(name) \ > > + struct arch_service *(name) > > + > > +/* Push-back interface is purposed to simplify interaction with > > + arch_service struct > > + NOTE: al - architecture list */ > > + > > +/* base methods */ > > +struct arch_service *al_create(unsigned int capacity); > > + > > +int al_push(struct arch_service *m, struct arch_descriptor > > *element); + > > +int al_set_flag(struct arch_service *m, unsigned index, int flag); > > + > > +struct arch_descriptor *al_get(struct arch_service *m, unsigned > > index); + > > +unsigned int al_size(struct arch_service *m); > > + > > +unsigned int al_base_size(struct arch_service *m); > > + > > +void al_free(struct arch_service *m); > > + > > +/* methods returning fields with error check */ > > +enum arch_type al_arch_num(struct arch_service *m, unsigned index); > > + > > +const char *al_arch_name(struct arch_service *m, unsigned index); > > + > > +int al_arch_name_len(struct arch_service *m, unsigned index); > > + > > +enum arch_type al_arch_base_num(struct arch_service *m, unsigned > > index); + > > +const char *al_abi_mode(struct arch_service *m, unsigned index); > > + > > +int al_abi_mode_len(struct arch_service *m, unsigned index); > > + > > +int al_flag(struct arch_service *m, unsigned index); > > + > > +/* calculating methods */ > > +int al_syscall_impl(struct arch_service *m, unsigned index); > > + > > +int al_find_base_arch(struct arch_service *m, unsigned index); > > + > > +int al_get_abi_modes(struct arch_service *m, unsigned index); > > + > > +int al_is_arch_unique(struct arch_service *m, unsigned index); > > + > > +enum impl_type al_ipc_syscall(struct arch_service *m, unsigned > > index); + > > +enum impl_type al_sck_syscall(struct arch_service *m, unsigned > > index); + > > +int al_find_arch(struct arch_service *m, enum arch_type a_type); > > + > > +int al_next_arch_name(struct arch_service *m, unsigned index); > > + > > +void al_dump(struct arch_service *m); > > + > > +#endif /* !ASINFO_ARCH_INTERFACE */ > > diff --git a/tools/asinfo/asinfo.1 b/tools/asinfo/asinfo.1 > > new file mode 100644 > > index 00000000..e69de29b > > diff --git a/tools/asinfo/asinfo.c b/tools/asinfo/asinfo.c > > new file mode 100644 > > index 00000000..195c1d09 > > --- /dev/null > > +++ b/tools/asinfo/asinfo.c > > @@ -0,0 +1,196 @@ > > +/* > > + * The asinfo main source. The asinfo tool is purposed to operate > > + * with system calls and provide information about it. > > + * > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> > > + * 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. > > + */ > > + > > +#ifdef HAVE_CONFIG_H > > +# include "config.h" > > +#endif > > +#include <errno.h> > > +#include <limits.h> > > +#include <stdarg.h> > > +#include <stdbool.h> > > +#include <stdio.h> > > +#include <stdlib.h> > > +#include <string.h> > > + > > +#include "arch_interface.h" > > +#include "dispatchers.h" > > +#include "error_prints.h" > > +#include "macros.h" > > +#include "request_msgs.h" > > +#include "xmalloc.h" > > + > > +#ifndef HAVE_PROGRAM_INVOCATION_NAME > > +char *program_invocation_name; > > +#endif > > + > > +void > > +die(void) > > +{ > > + exit(1); > > +} > > + > > +static int > > +is_more1bit(unsigned int num) > > +{ > > + return !(num & (num - 1)); > > +} > Usually such function is called "is_power_of_two" or something like > that. > > In your case it's (or, more precisely, its inverse) probably should > be named "is_single_bit" or something like this. > > Note that this function return true for num == 0. Yes, I see, I called it this way, because I'd catch cases when there is one bit or no set bit, therefore names speak about it. > > > + > > +static unsigned > > +option_to_request(char *option) > > +{ > > + /* Convertion table to store string with options */ > > + const char *options[] = { > > + [SD_REQ_GET_NAME_BIT] = "get-name", > > + [SD_REQ_GET_NUMBER_BIT] = "get-num", > > + [SD_REQ_GET_NARGS_BIT] = "get-nargs", > > + [AD_REQ_SET_ARCH_BIT] = "set-arch", > > + [AD_REQ_GET_ARCH_BIT] = "get-arch", > > + [AD_REQ_LIST_ARCH_BIT] = "list-arch", > > + [ABD_REQ_SET_ABI] = "set-abi", > > + [ABD_REQ_GET_ABI] = "get-abi", > > + [ABD_REQ_LIST_ABI] = "list-abi", > Why last three do not have "_BIT" suffix? > > > + }; > > + unsigned i; > > + > > + for (i = 0; i < ARRAY_SIZE(options); i++) { > > + if (options[i] && strcmp(option, options[i]) == 0) > > + return i; > > + } > > + return UINT_MAX; > > +} > > + > > +static unsigned > > +command_dispatcher(int argc, char *argv[], char *args[]) > > +{ > > + int i; > > + unsigned final_req = 0; > > + unsigned temp_req = 0; > > + unsigned non_req_arg = (1 << AD_REQ_GET_ARCH_BIT) | > > + (1 << AD_REQ_LIST_ARCH_BIT) | > > + (1 << ABD_REQ_GET_ABI_BIT) | > > + (1 << ABD_REQ_LIST_ABI_BIT) | > > + (1 << SD_REQ_GET_LIST_BIT); > > + > > + if (!program_invocation_name || !*program_invocation_name) > > { > > + static char name[] = "asinfo"; > > + program_invocation_name = > > + (argv[0] && *argv[0]) ? argv[0] : name; > > + } > > + > > + /* Firstly, is is necessary to convert and make basic > > check */ > To convert what? > > > + for (i = 1; i < argc; i++) { > > + if ((temp_req = option_to_request(argv[i])) == > > UINT_MAX) > > + error_msg_and_help("unrecognized option > > '%s'", argv[i]); > > + if (final_req & (1 << temp_req)) > > + error_msg_and_help("option '%s' has been > > used more than " > > + "once", argv[i]); > > + if (!((1 << temp_req) & non_req_arg) && > > + ((i + 1 >= argc) || strlen(argv[i + 1]) == 0)) > > + error_msg_and_help("option '%s' requires " > > + "argument", argv[i]); > > + final_req |= (1 << temp_req); > > + if (!((1 << temp_req) & non_req_arg)) { > > + args[temp_req] = argv[i + 1]; > > + i++; > > + } > > + } > > + /* Secondly, final_req should be logically checked, > > + here the only error is 'mixed options' */ > > + /* More than one option from the one request group > > couldn't be set*/ > > + if ((is_more1bit(final_req & SD_REQ_MASK) == 0) || > > + (is_more1bit(final_req & AD_REQ_MASK) == 0) || > > + (is_more1bit(final_req & ABD_REQ_MASK) == 0) || > > + (is_more1bit(final_req & FD_REQ_MASK) == 0)) > > + error_msg_and_help("mixed options"); > This error message is quite uninformative. > > > + /* Check on mutually exclusive options chain */ > > + /* If at least one syscall option has been typed, therefore > > + arch_options could be only empty or set-arch and > > + abi_option could be only empty or set-abi */ > > + if ((final_req & SD_REQ_MASK) && > > + (((final_req & AD_REQ_MASK) && > > + !(final_req & (1 << AD_REQ_SET_ARCH_BIT))) || > > + ((final_req & ABD_REQ_MASK) && > > + !(final_req & (1 << ABD_REQ_SET_ABI_BIT))))) > > + error_msg_and_help("mixed options"); > This too. > > > + > > + /* list-arch couldn't be used with any abi options */ > > + if ((final_req & (1 << AD_REQ_LIST_ARCH_BIT) && > > + (final_req & ABD_REQ_MASK))) > > + error_msg_and_help("mixed options"); > And this. > > > + > > + return final_req; > > +} > > + > > +int > > +main(int argc, char *argv[]) > > +{ > > + ARCH_LIST_DEFINE(arch_list); > > + /* This array is purposed to store arguments for options > > in the > > + most convinient way */ > "convenient" > > > + char **input_args = xcalloc(sizeof(*input_args), > > REQ_LAST_BIT); > > + unsigned reqs; > > + int ret = 0; > > + > > + /* command_dispatcher turn */ > > + reqs = command_dispatcher(argc, argv, input_args); > > + if (reqs == 0) > > + error_msg_and_help("must have OPTIONS"); > > + > > + /* arch_dispatcher turn */ > > + arch_list = arch_dispatcher(reqs, > > input_args[AD_REQ_SET_ARCH]); > > + if (arch_list == NULL) > > + error_msg_and_help("unrecognized architecture > > '%s'", > > + input_args[AD_REQ_SET_ARCH]); > > + /* abi_dispatcher turn */ > > + ret = abi_dispatcher(arch_list, reqs, > > input_args[ABD_REQ_SET_ABI]); > > + if (ret != 0) > > + error_msg_and_help("unrecognized ABI mode '%s'", > > + input_args[ABD_REQ_SET_ABI]); > > + /* syscall_dispatcher work */ > > +#if 0 > > + SYSCALL_LIST_DEFINE(syscall_list); > > + syscall_list = syscall_dispatcher(arch_list, requests, > > + input_args[IS_OWNrequests & > > SD_REQ_MASK]); > > + if (syscall_list[0].sys_name != NULL) { > > + printf("%s\n", syscall_list[0].sys_name); > > + } else { > > + error_msg_and_help("unrecognized syscall number > > '%s'", > > + input_args[fsbit_num(requests & > > SD_REQ_MASK)]); > > + } > > +#endif > > + /* If we want to get info about just architectures thus we > > dump just > > + info about archs, otherwise only about syscalls */ > > + if (!(reqs & SD_REQ_MASK)) > > + al_dump(arch_list); > > + else > > + //sl_dump > > + error_msg_and_die("syscall dispatcher isn't > > supported for now"); > > + return 0; > > +} > > diff --git a/tools/asinfo/dispatchers.c b/tools/asinfo/dispatchers.c > > new file mode 100644 > > index 00000000..101f9f14 > > --- /dev/null > > +++ b/tools/asinfo/dispatchers.c > > @@ -0,0 +1,242 @@ > > +/* > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> > > + * 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. > > + */ > > + > > +#ifdef HAVE_CONFIG_H > > +# include "config.h" > > +#endif > > +#include <stdlib.h> > > +#include <stdio.h> > > +#include <string.h> > > +#include <sys/utsname.h> > > + > > +#include "arch_interface.h" > > +#include "dispatchers.h" > > +#include "macros.h" > > +#include "request_msgs.h" > > +#include "sysent.h" > > +#include "xmalloc.h" > > + > > +extern struct arch_descriptor architectures[]; > > +extern const int architectures_size; > > + > > +struct sc_base_info * > > +syscall_dispatcher(struct arch_service *arch, int request_type, > > + const char *data) > > +{ > > + SYSCALL_LIST_DEFINE(syscall_list); > > + > > + if (request_type & (1 << SD_REQ_GET_NAME_BIT)) { > > + long int nsys; > > + char *endptr; > > + nsys = strtol(data, &endptr, 10); > > + if (*endptr != '\0' || nsys < 0 || > > + nsys >= arch->arch_list[0]->max_scn) { > > + goto fail; > > + } > > + SYSCALL_LIST_ALLOC(syscall_list, 1); > > + syscall_list[0].sys_name = > > + > > arch->arch_list[0]->list_of_syscall[nsys].sys_name; > > + goto done; > > + } > > + > > +fail: > > + SYSCALL_LIST_ALLOC(syscall_list, 0); > > +done: > > + return syscall_list; > > +} > > + > > +static int > > +form_arch_list(struct arch_service **arch, char *arch_str) > > +{ > > + ARCH_LIST_DEFINE(a_full_list) = > > al_create(architectures_size); > > + int arch_match = -1; > > + char *match_pointer = NULL; > > + int al_size_ret = 0; > > + int al_size_full = 0; > > + int i; > > + > > + if (arch_str == NULL) > > + return -1; > > + /* Firstly, generate full list of arch to simplify firther > > work */ > > + for (i = 0; i < architectures_size; i++) > > + al_push(a_full_list, &architectures[i]); > > + al_size_full = al_size(a_full_list); > > + /* Here we find the best match in architecture list */ > > + for (i = 0; i < al_size_full; i++) { > > + match_pointer = strstr(arch_str, > > al_arch_name(a_full_list, i)); > > + if (match_pointer == NULL || match_pointer != > > arch_str) > > + continue; > > + if (arch_match == -1 || > > + al_arch_name_len(a_full_list, i) > > > + al_arch_name_len(a_full_list, arch_match)) > > + arch_match = i; > > + } > > + if (arch_match == -1) > > + goto fail; > > + /* Now we find all ABI modes related to the architecture > > and its other > > + names */ > > + /* Firstly, find the base arch */ > > + arch_match = al_find_base_arch(a_full_list, arch_match); > > + /* Secondly, it is necessary to calculate size of arch > > list */ > > + al_size_ret = al_get_abi_modes(a_full_list, arch_match); > > + while ((i = al_next_arch_name(a_full_list, arch_match)) != > > -1) > > + al_size_ret++; > > + if (al_size_ret == 0) > > + goto fail; > > + /* Finally, Create arch_list and fill it */ > > + *arch = al_create(al_size_ret); > > + for (i = arch_match; i < (arch_match + al_size_ret); i++) > > + al_push(*arch, &architectures[i]); > > + > > + free(a_full_list); > > + return 0; > > +fail: > > + free(a_full_list); > > + return -1; > > +} > > + > > +struct arch_service * > > +arch_dispatcher(unsigned request_type, char *arch) > > +{ > > + struct utsname info_uname; > > + int i; > > + ARCH_LIST_DEFINE(arch_list) = NULL; > > + > > + /* If user don't type any option in ARCH_REQ group, it > > means > > + get current arch */ > > + if ((request_type & (1 << AD_REQ_GET_ARCH_BIT)) || > > + (!(request_type & AD_REQ_MASK))) { > > + uname(&info_uname); > > + if (form_arch_list(&arch_list, info_uname.machine) > > == -1) > > + goto fail; > > + goto done; > > + } > > + > > + if (request_type & (1 << AD_REQ_SET_ARCH_BIT)) { > > + if (form_arch_list(&arch_list, arch) == -1) > > + goto fail; > > + goto done; > > + } > > + > > + if ((request_type & (1 << AD_REQ_LIST_ARCH_BIT))) { > > + arch_list = al_create(architectures_size); > > + for (i = 0; i < architectures_size; i++) { > > + al_push(arch_list, &(architectures[i])); > > + al_set_flag(arch_list, i, AD_FLAG_PRINT); > > + } > > + goto done; > > + } > > +fail: > > + arch_list = NULL; > > +done: > > + return arch_list; > > +} > > + > > +int > > +abi_dispatcher(struct arch_service *a_serv, unsigned request_type, > > char *abi) +{ > > + int i = 0; > > + enum arch_type arch_num = ARCH_no_arch; > > + int abi_modes = 0; > > + int arch_size = 0; > > + int flag = 0; > > + > > + if (a_serv == NULL) > > + return -1; > > + arch_size = al_size(a_serv); > > + abi_modes = al_get_abi_modes(a_serv, 0); > > + /* The strace package could be compiled as 32bit app on > > 64bit > > + architecture, therefore asinfo has to detect it and > > print out > > + corresponding personality. Frankly speaking, it is > > necessary to > > + detect strace package personality */ > > + if ((request_type & (1 << ABD_REQ_GET_ABI_BIT)) || > > + (!(request_type & ABD_REQ_MASK))) { > > + arch_num = al_arch_num(a_serv, 0); > > + switch (arch_num) { > > + case ARCH_x86_64_64bit: > > + al_set_flag(a_serv, al_find_arch(a_serv, > > +#if defined(X86_64) > > + ARCH_x86_64_64bit > > +#elif defined(X32) > > + ARCH_x86_64_x32 > > +#else > > + ARCH_x86_64_32bit > > +#endif > > + ), AD_FLAG_PRINT); > > + break; > > + case ARCH_arm_oabi: > > + al_set_flag(a_serv, al_find_arch(a_serv, > > +#if defined(__ARM_EABI__) > > + ARCH_arm_eabi > > +#else > > + ARCH_arm_oabi > > +#endif > > + ), AD_FLAG_PRINT); > > + break; > > + case ARCH_mips_o32: > > + al_set_flag(a_serv, al_find_arch(a_serv, > > +#if defined(LINUX_MIPSO32) > > + ARCH_mips_o32 > > +#elif defined(LINUX_MIPSN32) > > + ARCH_mips_n32 > > +#else > > + ARCH_mips_n64 > > +#endif > > + ), AD_FLAG_PRINT); > > + break; > > + default: > > + /* Other cases should be printed using > > default rule: > > + print first ABI mode + other arch names > > */ > > + al_set_flag(a_serv, 0, AD_FLAG_PRINT); > > + for (i = abi_modes; i < arch_size; i++) > > + al_set_flag(a_serv, i, > > AD_FLAG_PRINT); > > + } > > + goto done; > > + } > > + > > + if (request_type & (1 << ABD_REQ_LIST_ABI_BIT)) { > > + for (i = 0; i < abi_modes; i++) > > + al_set_flag(a_serv, i, AD_FLAG_PRINT); > > + goto done; > > + } > > + > > + if (request_type & (1 << ABD_REQ_SET_ABI_BIT)) { > > + if (abi == NULL) > > + goto fail; > > + for (i = 0; i < abi_modes; i++) > > + if (strcmp(abi, al_abi_mode(a_serv, i)) == > > 0) { > > + al_set_flag(a_serv, i, > > AD_FLAG_PRINT); > > + flag = 1; > > + } > > + if (!flag) > > + goto fail; > > + } > > +done: > > + return 0; > > +fail: > > + return -1; > > +} > > diff --git a/tools/asinfo/dispatchers.h b/tools/asinfo/dispatchers.h > > new file mode 100644 > > index 00000000..dc76feb8 > > --- /dev/null > > +++ b/tools/asinfo/dispatchers.h > > @@ -0,0 +1,60 @@ > > +/* > > + * The dispatchers.h contains all necessary functions to perform > > main > > + * work in the asinfo tool. > > + * > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> > > + * 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_ASINFO_COM_SCALLENT > > +#define STRACE_ASINFO_COM_SCALLENT > > + > > +#include "arch_interface.h" > > +#include "request_msgs.h" > > +#include "sysent.h" > > + > > +#define SYSCALL_LIST_DEFINE(name) \ > > + struct sc_base_info *(name) > > + > > +#define SYSCALL_LIST_ALLOC(name, size) \ > > + (name) = xcalloc(sizeof(*(name)), (size + 1)) > > + > > +/* The main interaction with low-level structures, such as for now, > > + * struct_sysent, is happening here, the remaining processing > > should > > + * be done on the other levels. > > + */ > > +struct sc_base_info *syscall_dispatcher(struct arch_service *arch, > > + int request_type, > > + const char *arg); > > + > > +/* The function is purposed to provide correct list of > > architectures > > + */ > > +struct arch_service *arch_dispatcher(unsigned request_type, char* > > arch); + > > +/* Final filtering based on personality */ > > +int abi_dispatcher(struct arch_service *a_serv, unsigned > > request_type, > > + char *abi); > > + > > +#endif /* !STRACE_ASINFO_COM_SCALLENT */ > > diff --git a/tools/asinfo/request_msgs.h > > b/tools/asinfo/request_msgs.h new file mode 100644 > > index 00000000..895b043c > > --- /dev/null > > +++ b/tools/asinfo/request_msgs.h > > @@ -0,0 +1,115 @@ > > +/* > > + * The request_msgs are messages used by dispatchers in asinfo > > tool to > > + * operate with static data base. > > + * > > + * Copyright (c) 2017 Edgar A. Kaziakhmedov > > <edgar.kaziakhme...@virtuozzo.com> > > + * 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_ASINFO_REQ_MSGS > > +#define STRACE_ASINFO_REQ_MSGS > > + > > +/* Request types for syscall_dispatcher, > > + * arch_dispatcher, and filter_dispatcher, > > + * which, in turn, could be combined > > + */ > > +enum syscall_req_bit { > > + SD_REQ_GET_NAME_BIT, > > + SD_REQ_GET_NUMBER_BIT, > > + SD_REQ_GET_NARGS_BIT, > > + SD_REQ_GET_PROTO_BIT, > > + SD_REQ_GET_KERNEL_BIT, > > + SD_REQ_GET_LIST_BIT, > > + > > + SYSCALL_REQ_BIT_LAST > > +}; > > + > > +enum arch_req_bit { > > + AD_REQ_SET_ARCH_BIT = SYSCALL_REQ_BIT_LAST, > > + AD_REQ_GET_ARCH_BIT, > > + AD_REQ_LIST_ARCH_BIT, > > + > > + ARCH_REQ_BIT_LAST > > +}; > > + > > +enum abi_req_bit { > > + ABD_REQ_SET_ABI_BIT = ARCH_REQ_BIT_LAST, > > + ABD_REQ_GET_ABI_BIT, > > + ABD_REQ_LIST_ABI_BIT, > > + > > + ABD_REQ_BIT_LAST > > +}; > > + > > +enum fd_req_bit { > > + FD_REQ_SET_BASE_FILTER_BIT = ABD_REQ_BIT_LAST, > > + > > + FD_REQ_BIT_LAST > > +}; > > + > > +#define ENUM_FLAG(name) name = name##_BIT > Looks like I've made a mistake when wrote a code snippet example, > there should be a bit shift by amount of bits from the bit > enumeration: > > #define ENUM_FLAG(name) name = 1 << name##_BIT > > > +enum req_type { > > + ENUM_FLAG(SD_REQ_GET_NAME), > > + ENUM_FLAG(SD_REQ_GET_NUMBER), > > + ENUM_FLAG(SD_REQ_GET_NARGS), > > + ENUM_FLAG(SD_REQ_GET_PROTO), > > + ENUM_FLAG(SD_REQ_GET_KERNEL), > > + ENUM_FLAG(SD_REQ_GET_LIST), > > + ENUM_FLAG(AD_REQ_SET_ARCH), > > + ENUM_FLAG(AD_REQ_GET_ARCH), > > + ENUM_FLAG(AD_REQ_LIST_ARCH), > > + ENUM_FLAG(ABD_REQ_SET_ABI), > > + ENUM_FLAG(ABD_REQ_GET_ABI), > > + ENUM_FLAG(ABD_REQ_LIST_ABI), > > + ENUM_FLAG(FD_REQ_SET_BASE_FILTER), > > +}; > > +#undef ENUM_FLAG > > + > > +#define BITMASK(hi, lo) ((1 << (hi)) - (1 << (lo))) > > +#define REQ_LAST_BIT FD_REQ_BIT_LAST /* Can be used in input_args > > calloc*/ +#define SD_REQ_MASK BITMASK(SYSCALL_REQ_BIT_LAST, 0) > > +#define AD_REQ_MASK BITMASK(ARCH_REQ_BIT_LAST, > > SYSCALL_REQ_BIT_LAST) +#define ABD_REQ_MASK > > BITMASK(ABD_REQ_BIT_LAST, ARCH_REQ_BIT_LAST) +#define FD_REQ_MASK > > BITMASK(FD_REQ_BIT_LAST, ABD_REQ_BIT_LAST) + > > +/* SD_REQ_GET_NAME, SD_REQ_GET_NUMBER */ > > +struct sc_base_info { > > + int sys_number; > > + const char *sys_name; > > + int sys_flags; > > +}; > > + > > +/* SD_REQ_GET_NARGS */ > > +struct sc_nargs { > > + struct sc_base_info sys_bi; > > + int nargs; > > +}; > > + > > +/* FD_SET_BASE_FILTER */ > > +struct sc_filter { > > + struct sc_base_info sys_bi; > > + int filter_options; > > +}; > > + > > +#endif /* !STRACE_ASINFO_REQ_MSGS */ > > -- > > 2.11.0 > > % ./asinfo -h > ./asinfo: unrecognized option '-h' > Try './asinfo -h' for more information. > > > The implementation of architecture name aliases looks pretty > convoluted. The same for arch dispatcher, especially in > form_arch_list part. It's quite difficult to evaluate tool's > functionality without any user manual. > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > _______________________________________________ > Strace-devel mailing list > Strace-devel@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/strace-devel
pgpddIUt3Umnf.pgp
Description: OpenPGP digital signature
------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________ Strace-devel mailing list Strace-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/strace-devel