You can subscribe to this list here.
| 2000 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
(5) |
Oct
(1) |
Nov
|
Dec
(2) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2001 |
Jan
(3) |
Feb
(1) |
Mar
(62) |
Apr
(29) |
May
(4) |
Jun
|
Jul
(11) |
Aug
(30) |
Sep
(8) |
Oct
(31) |
Nov
(2) |
Dec
(13) |
| 2002 |
Jan
(4) |
Feb
(3) |
Mar
(12) |
Apr
(2) |
May
(7) |
Jun
(2) |
Jul
(7) |
Aug
(5) |
Sep
(4) |
Oct
(8) |
Nov
(5) |
Dec
(17) |
| 2003 |
Jan
(24) |
Feb
(19) |
Mar
(19) |
Apr
(22) |
May
(18) |
Jun
(16) |
Jul
(21) |
Aug
(48) |
Sep
(31) |
Oct
(45) |
Nov
(52) |
Dec
(54) |
| 2004 |
Jan
(71) |
Feb
(60) |
Mar
(54) |
Apr
(50) |
May
(88) |
Jun
(76) |
Jul
(62) |
Aug
(35) |
Sep
(20) |
Oct
(37) |
Nov
(66) |
Dec
(45) |
| 2005 |
Jan
(12) |
Feb
(5) |
Mar
(11) |
Apr
(6) |
May
(6) |
Jun
(6) |
Jul
(29) |
Aug
(61) |
Sep
(17) |
Oct
(45) |
Nov
(34) |
Dec
(17) |
| 2006 |
Jan
(13) |
Feb
(10) |
Mar
(15) |
Apr
(7) |
May
(13) |
Jun
(24) |
Jul
(12) |
Aug
(9) |
Sep
(17) |
Oct
(61) |
Nov
(58) |
Dec
(77) |
| 2007 |
Jan
(67) |
Feb
(61) |
Mar
(54) |
Apr
(93) |
May
(104) |
Jun
(131) |
Jul
(187) |
Aug
(116) |
Sep
(66) |
Oct
(41) |
Nov
(56) |
Dec
(19) |
| 2008 |
Jan
(19) |
Feb
(65) |
Mar
(127) |
Apr
(170) |
May
(137) |
Jun
(160) |
Jul
(168) |
Aug
(139) |
Sep
(104) |
Oct
(51) |
Nov
(69) |
Dec
(126) |
| 2009 |
Jan
(55) |
Feb
(148) |
Mar
(87) |
Apr
(74) |
May
(151) |
Jun
(121) |
Jul
(111) |
Aug
(97) |
Sep
(107) |
Oct
(177) |
Nov
(101) |
Dec
(84) |
| 2010 |
Jan
(55) |
Feb
(45) |
Mar
(114) |
Apr
(140) |
May
(152) |
Jun
(132) |
Jul
(115) |
Aug
(118) |
Sep
(105) |
Oct
(32) |
Nov
(26) |
Dec
(44) |
| 2011 |
Jan
(36) |
Feb
(138) |
Mar
(80) |
Apr
(34) |
May
(52) |
Jun
(72) |
Jul
(27) |
Aug
(119) |
Sep
(77) |
Oct
(71) |
Nov
(58) |
Dec
(50) |
| 2012 |
Jan
(59) |
Feb
(55) |
Mar
(82) |
Apr
(81) |
May
(31) |
Jun
(8) |
Jul
(13) |
Aug
(8) |
Sep
(10) |
Oct
(44) |
Nov
(13) |
Dec
(15) |
| 2013 |
Jan
(28) |
Feb
(72) |
Mar
(35) |
Apr
(14) |
May
(162) |
Jun
(55) |
Jul
(39) |
Aug
(20) |
Sep
(25) |
Oct
(15) |
Nov
(84) |
Dec
(14) |
| 2014 |
Jan
(31) |
Feb
(102) |
Mar
(112) |
Apr
(106) |
May
(105) |
Jun
(87) |
Jul
(36) |
Aug
(112) |
Sep
(31) |
Oct
(23) |
Nov
(68) |
Dec
(42) |
| 2015 |
Jan
(46) |
Feb
(131) |
Mar
(267) |
Apr
(48) |
May
(27) |
Jun
(42) |
Jul
(41) |
Aug
(41) |
Sep
(28) |
Oct
(22) |
Nov
(27) |
Dec
(45) |
| 2016 |
Jan
(55) |
Feb
(55) |
Mar
(363) |
Apr
(125) |
May
(173) |
Jun
(159) |
Jul
(69) |
Aug
(111) |
Sep
(130) |
Oct
(115) |
Nov
(26) |
Dec
(70) |
| 2017 |
Jan
(78) |
Feb
(43) |
Mar
(249) |
Apr
(130) |
May
(35) |
Jun
(436) |
Jul
(293) |
Aug
(423) |
Sep
(81) |
Oct
(16) |
Nov
(35) |
Dec
(110) |
| 2018 |
Jan
(67) |
Feb
(36) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Masatake Y. <ya...@re...> - 2017-12-18 04:25:06
|
I'm planning to link strace with libiberty for mangling C++ symbol appearted in stack trace enabled with -k option. Both the names, xmalloc and xcalloc, are already used in the library. They are conflicts the functions having the same names in strace. Newly introduced macors(strace_calloc and strace_malloc) rename the names defined in strace side for avoiding the confliction. * xmalloc.h (strace_calloc, strace_malloc): New macros. Signed-off-by: Masatake YAMATO <ya...@re...> --- xmalloc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xmalloc.h b/xmalloc.h index d1feeb91..89234e20 100644 --- a/xmalloc.h +++ b/xmalloc.h @@ -36,6 +36,8 @@ #include <stddef.h> #include "gcc_compat.h" +#define xcalloc strace_calloc +#define xmalloc strace_malloc void *xcalloc(size_t nmemb, size_t size) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1, 2)); void *xmalloc(size_t size) ATTRIBUTE_MALLOC ATTRIBUTE_ALLOC_SIZE((1)); -- 2.14.3 |
|
From: Stan C. <sc...@re...> - 2017-12-12 21:13:35
|
Ping. Thanks. |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:03:09
|
This set of tests cover all possible cases in asinfo tool. However,
as asinfo uses some libraries provided by strace (such as basic_filters)
there is no need to test them again in asinfo context.
Also, the set of syscalls for specific architecture (hence, its number) might
be expanded in the future, so to overcome this obstacle and avoid duplication
of the same strings reference output ptintings are stored in
ref_asinfo_output.h file.
As for syscall-related checks, tests use old syscalls as samples, so their
numbers and names can't be changed.
* configure.ac (AC_CONFIG_FILES): Add tests Makefile to be generated.
* tools/asinfo/Makefile.am (SUBDIRS): Add tests dir.
* tools/asinfo/tests/Makefile.m: New file.
* tools/asinfo/tests/init.sh: New file. Main subroutines for tests.
* tools/asinfo/tests/ref_asinfo_output.h: New file.
* tools/asinfo/tests/com_disp_wrong_keys.c: Likewise.
* tools/asinfo/tests/com_disp_wrong_keys.test: Likewise.
* tools/asinfo/tests/format_output.c: Likewise.
* tools/asinfo/tests/format_output.test: Likewise.
* tools/asinfo/tests/get_arch_abi.c: Likewise.
* tools/asinfo/tests/get_arch_abi.test: Likewise.
* tools/asinfo/tests/get_sname.c: Likewise.
* tools/asinfo/tests/get_sname.test: Likewise.
* tools/asinfo/tests/get_snum.c: Likewise.
* tools/asinfo/tests/get_snum.test: Likewise.
* tools/asinfo/tests/list_arch.c: Likewise.
* tools/asinfo/tests/list_arch.test: Likewise.
* tools/asinfo/tests/multiarch_get_sname.c: Likewise.
* tools/asinfo/tests/multiarch_get_sname.test: Likewise.
* tools/asinfo/tests/multiarch_get_snum.c: Likewise.
* tools/asinfo/tests/multiarch_get_snum.test: Likewise.
* tools/asinfo/tests/set_abi.c: Likewise.
* tools/asinfo/tests/set_abi.test: Likewise.
* tools/asinfo/tests/set_arch.c: Likewise.
* tools/asinfo/tests/set_arch.test: Likewise.
* tools/asinfo/tests/set_mult_abi.c: Likewise.
* tools/asinfo/tests/set_mult_abi.test: Likewise.
* tools/asinfo/tests/set_mult_arch.c: Likewise.
* tools/asinfo/tests/set_mult_arch.test: Likewise.
* tools/asinfo/tests/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
configure.ac | 1 +
tools/asinfo/Makefile.am | 2 +
tools/asinfo/tests/.gitignore | 16 +++
tools/asinfo/tests/Makefile.am | 67 +++++++++++
tools/asinfo/tests/com_disp_wrong_keys.c | 42 +++++++
tools/asinfo/tests/com_disp_wrong_keys.test | 32 +++++
tools/asinfo/tests/format_output.c | 17 +++
tools/asinfo/tests/format_output.test | 8 ++
tools/asinfo/tests/get_arch_abi.c | 180 ++++++++++++++++++++++++++++
tools/asinfo/tests/get_arch_abi.test | 7 ++
tools/asinfo/tests/get_sname.c | 26 ++++
tools/asinfo/tests/get_sname.test | 12 ++
tools/asinfo/tests/get_snum.c | 26 ++++
tools/asinfo/tests/get_snum.test | 12 ++
tools/asinfo/tests/init.sh | 97 +++++++++++++++
tools/asinfo/tests/list_arch.c | 49 ++++++++
tools/asinfo/tests/list_arch.test | 7 ++
tools/asinfo/tests/multiarch_get_sname.c | 27 +++++
tools/asinfo/tests/multiarch_get_sname.test | 12 ++
tools/asinfo/tests/multiarch_get_snum.c | 39 ++++++
tools/asinfo/tests/multiarch_get_snum.test | 12 ++
tools/asinfo/tests/ref_asinfo_output.h | 42 +++++++
tools/asinfo/tests/set_abi.c | 9 ++
tools/asinfo/tests/set_abi.test | 7 ++
tools/asinfo/tests/set_arch.c | 11 ++
tools/asinfo/tests/set_arch.test | 7 ++
tools/asinfo/tests/set_mult_abi.c | 11 ++
tools/asinfo/tests/set_mult_abi.test | 7 ++
tools/asinfo/tests/set_mult_arch.c | 12 ++
tools/asinfo/tests/set_mult_arch.test | 7 ++
30 files changed, 804 insertions(+)
create mode 100644 tools/asinfo/tests/.gitignore
create mode 100644 tools/asinfo/tests/Makefile.am
create mode 100644 tools/asinfo/tests/com_disp_wrong_keys.c
create mode 100755 tools/asinfo/tests/com_disp_wrong_keys.test
create mode 100644 tools/asinfo/tests/format_output.c
create mode 100755 tools/asinfo/tests/format_output.test
create mode 100644 tools/asinfo/tests/get_arch_abi.c
create mode 100755 tools/asinfo/tests/get_arch_abi.test
create mode 100644 tools/asinfo/tests/get_sname.c
create mode 100755 tools/asinfo/tests/get_sname.test
create mode 100644 tools/asinfo/tests/get_snum.c
create mode 100755 tools/asinfo/tests/get_snum.test
create mode 100644 tools/asinfo/tests/init.sh
create mode 100644 tools/asinfo/tests/list_arch.c
create mode 100755 tools/asinfo/tests/list_arch.test
create mode 100644 tools/asinfo/tests/multiarch_get_sname.c
create mode 100755 tools/asinfo/tests/multiarch_get_sname.test
create mode 100644 tools/asinfo/tests/multiarch_get_snum.c
create mode 100755 tools/asinfo/tests/multiarch_get_snum.test
create mode 100644 tools/asinfo/tests/ref_asinfo_output.h
create mode 100644 tools/asinfo/tests/set_abi.c
create mode 100755 tools/asinfo/tests/set_abi.test
create mode 100644 tools/asinfo/tests/set_arch.c
create mode 100755 tools/asinfo/tests/set_arch.test
create mode 100644 tools/asinfo/tests/set_mult_abi.c
create mode 100755 tools/asinfo/tests/set_mult_abi.test
create mode 100644 tools/asinfo/tests/set_mult_arch.c
create mode 100755 tools/asinfo/tests/set_mult_arch.test
diff --git a/configure.ac b/configure.ac
index 79690ba1..3e846be1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -911,6 +911,7 @@ AC_CONFIG_FILES([Makefile
tools/asinfo/asinfo.1
tools/Makefile
tools/asinfo/Makefile
+ tools/asinfo/tests/Makefile
strace.spec
debian/changelog])
AC_OUTPUT
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
index f2b23e74..9f78b733 100644
--- a/tools/asinfo/Makefile.am
+++ b/tools/asinfo/Makefile.am
@@ -25,6 +25,8 @@
# (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 = . tests
+
bin_PROGRAMS = asinfo
man_MANS = asinfo.1
diff --git a/tools/asinfo/tests/.gitignore b/tools/asinfo/tests/.gitignore
new file mode 100644
index 00000000..592d7b61
--- /dev/null
+++ b/tools/asinfo/tests/.gitignore
@@ -0,0 +1,16 @@
+*.dir
+*.log
+*.o
+*.trs
+set_arch
+set_mult_arch
+list_arch
+set_abi
+set_mult_abi
+get_arch_abi
+get_sname
+get_snum
+com_disp_wrong_keys
+multiarch_get_sname
+multiarch_get_snum
+format_output
diff --git a/tools/asinfo/tests/Makefile.am b/tools/asinfo/tests/Makefile.am
new file mode 100644
index 00000000..0eae4674
--- /dev/null
+++ b/tools/asinfo/tests/Makefile.am
@@ -0,0 +1,67 @@
+# Automake input for asinfo tests.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+OS = linux
+AM_COLOR_TESTS = always
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = $(ARCH_MFLAGS) \
+ -I$(builddir)/../ \
+ -I$(builddir) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)
+AM_LDFLAGS = $(ARCH_MFLAGS)
+
+check_PROGRAMS = set_arch set_mult_arch list_arch set_abi set_mult_abi \
+ get_arch_abi get_sname get_snum com_disp_wrong_keys \
+ multiarch_get_sname multiarch_get_snum format_output
+TESTS = set_arch.test set_mult_arch.test list_arch.test set_abi.test \
+ set_mult_abi.test get_arch_abi.test get_sname.test get_snum.test \
+ com_disp_wrong_keys.test multiarch_get_sname.test \
+ multiarch_get_snum.test format_output.test
+
+set_arch_SOURCES = set_arch.c
+set_mult_arch_SOURCES = set_mult_arch.c
+list_arch_SOURCES = list_arch.c
+set_abi_SOURCES = set_abi.c
+set_mult_abi_SOURCES = set_mult_abi.c
+get_arch_abi_SOURCES = get_arch_abi.c
+get_sname_SOURCES = get_sname.c
+get_snum_SOURCES = get_snum.c
+com_disp_wrong_keys_SOURCES = com_disp_wrong_keys.c
+multiarch_get_sname_SOURCES = multiarch_get_sname.c
+multiarch_get_snum_SOURCES = multiarch_get_snum.c
+format_output_SOURCES = format_output.c
+
+EXTRA_DIST = $(TESTS) \
+ ref_asinfo_output.h \
+ init.sh
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ -rm -rf -- $(TESTS:.test=.dir)
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.c b/tools/asinfo/tests/com_disp_wrong_keys.c
new file mode 100644
index 00000000..9dcb3ee2
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+#define TRY_HELP "Try \'../../asinfo -h\' for more information."
+
+int
+main(int argc, char *argv[])
+{
+ puts("../../asinfo: unrecognized option \'--set-ar\'\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--get-arch\' has been used more than "
+ "once\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--set-arch\' requires argument\n"
+ TRY_HELP "\n"
+ "../../asinfo: argument \'aarch64,\' of \'--set-arch\' parameter "
+ "has a wrong format\n"
+ TRY_HELP "\n"
+ "../../asinfo: exclusive parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: wrong parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: \'--list-arch\' cannot be used with any ABI "
+ "parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI parameters could be used only with "
+ "architecture parameter\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI modes cannot be automatically detected for "
+ "multiple architectures\n"
+ TRY_HELP "\n"
+ "../../asinfo: each architecture needs respective ABI mode, "
+ "and vice versa\n"
+ TRY_HELP "\n"
+ "../../asinfo: first set main output syscall characteristics\n"
+ TRY_HELP "\n"
+ "../../asinfo: raw data implies existing data\n"
+ TRY_HELP "\n"
+ "../../asinfo: must have OPTIONS\n"
+ TRY_HELP);
+ return 0;
+}
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.test b/tools/asinfo/tests/com_disp_wrong_keys.test
new file mode 100755
index 00000000..ba725ab5
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.test
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+#Unrecognized option
+run_asinfo --set-ar > $LOG
+#More than once param
+run_asinfo --get-arch --get-arch >> $LOG
+#Requiring argument
+run_asinfo --set-arch >> $LOG
+#Wrong format
+run_asinfo --set-arch aarch64, >> $LOG
+#More than one option in one group
+run_asinfo --get-arch --set-arch arm >> $LOG
+#syscall and list-arch
+run_asinfo --list-arch --get-sname all >> $LOG
+#list-arch and abi params
+run_asinfo --list-arch --list-abi >> $LOG
+#abi params without arch params
+run_asinfo --list-abi >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm --set-abi all,all,all >> $LOG
+#nargs should be used together with other options from syscall group
+run_asinfo --set-arch x86_64 --set-abi x32 --nargs >> $LOG
+#raw check
+run_asinfo --raw >> $LOG
+#empty input
+run_asinfo >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/format_output.c b/tools/asinfo/tests/format_output.c
new file mode 100644
index 00000000..870b8445
--- /dev/null
+++ b/tools/asinfo/tests/format_output.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts(
+"| N | Architecture name | ABI mode | IMPL syscalls | IPC IMPL | SOCKET IMPL |\n"
+"| 1 | avr32 | 32bit | 329 | external | external |"
+ );
+ puts(
+"| | | x86_64 | x86_64 | x86_64 |\n"
+"| N | Snum | 64bit | x32 | 32bit |\n"
+"| 1 | 1 | write | write | - |\n"
+"| 2 | 4 | - | - | write |");
+ return 0;
+}
diff --git a/tools/asinfo/tests/format_output.test b/tools/asinfo/tests/format_output.test
new file mode 100755
index 00000000..6addc6e9
--- /dev/null
+++ b/tools/asinfo/tests/format_output.test
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch avr32 --list-abi > $LOG
+run_asinfo --set-arch x86_64 --list-abi --get-snum write >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_arch_abi.c b/tools/asinfo/tests/get_arch_abi.c
new file mode 100644
index 00000000..e73aa0ca
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.c
@@ -0,0 +1,180 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "ref_asinfo_output.h"
+
+static inline void
+print_cannot_detect(char *arch_name)
+{
+ printf("../../asinfo: ABI mode cannot be automatically detected for "
+ "non-target architecture \'%s\'\n", arch_name);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct utsname buf;
+ uname(&buf);
+#if defined(bfin)
+ puts("1" BFIN_32bit_STR);
+ return 0;
+#endif
+#if defined(IA64)
+ puts("1" IA64_64bit_STR);
+ return 0;
+#endif
+#if defined(M68K)
+ puts("1" M68K_32bit_STR);
+#endif
+#if defined(SPARC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(SPARC)
+ puts("1" SPARC_32bit_STR);
+ return 0;
+#endif
+#if defined(METAG)
+ puts("1" METAG_32bit_STR);
+ return 0;
+#endif
+#if defined(MIPS)
+ if (strstr(buf.machine, "mips64")) {
+ puts(
+#if defined(LINUX_MIPSO32)
+ "1" MIPS64_O32_STR
+#elif defined(LINUX_MIPSN32)
+ "1" MIPS64_N32_STR
+#elif defined(LINUX_MIPSN64)
+ "1" MIPS64_N64_STR
+#endif
+ );
+ return 0;
+ }
+ if (strstr(buf.machine, "mips")) {
+ puts("1" MIPS_O32_STR);
+ return 0;
+ }
+#endif
+#if defined(ALPHA)
+ puts("1" ALPHA_64bit_STR);
+ return 0;
+#endif
+#if defined(POWERPC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(POWERPC)
+ puts("1" PPC_32bit_STR);
+ return 0;
+#endif
+#if defined(ARM)
+ if (strstr(buf.machine, "arm")) {
+ puts(
+#if defined(__ARM_EABI__) || !defined(ENABLE_ARM_OABI)
+ "1" ARM_eabi_STR
+#else
+ "1" ARM_oabi_STR
+#endif
+ );
+ return 0;
+ }
+#endif
+#if defined(AARCH64)
+ puts(
+#if defined(__ARM_EABI__)
+ "1" AARCH64_eabi_STR
+#else
+ "1" AARCH64_64bit_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(AVR32)
+ puts("1" AVR32_32bit_STR);
+ return 0;
+#endif
+#if defined(ARC)
+ puts("1" ARC_32bit_STR);
+ return 0;
+#endif
+#if defined(S390)
+ puts("1" S390_32bit_STR);
+ return 0;
+#endif
+#if defined(S390X)
+ puts("1" S390X_64bit_STR);
+ return 0;
+#endif
+#if defined(HPPA)
+ puts("1" PARISC_32bit_STR);
+ return 0;
+#endif
+#if defined(SH64)
+ puts("1" SH64_64bit_STR);
+ return 0;
+#endif
+#if defined(SH)
+ puts("1" SH_32bit_STR);
+ return 0;
+#endif
+#if defined(X86_64) || defined(X32)
+ puts(
+#if defined(X86_64)
+ "1" X86_64_64bit_STR
+#elif defined(X32)
+ "1" X86_64_X32_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(I386)
+ if (strstr(buf.machine, "64"))
+ puts("1" X86_64_32bit_STR);
+ else
+ puts("1" X86_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV10)
+ puts("1" CRISV10_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV32)
+ puts("1" CRISV32_32bit_STR);
+ return 0;
+#endif
+#if defined(TILE)
+ puts(
+#if defined(__tilepro__)
+ "1" TILE_64bit_STR
+#else
+ "1" TILE_32bit_STR
+#endif
+ );
+#endif
+#if defined(MICROBLAZE)
+ puts("1" MICROBLAZE_32bit_STR);
+ return 0;
+#endif
+#if defined(NIOS2)
+ puts("1" NIOS2_32bit_STR);
+ return 0;
+#endif
+#if defined(OR1K)
+ puts("1" OR1K_32bit_STR);
+ return 0;
+#endif
+#if defined(XTENSA)
+ puts("1" XTENSA_32bit_STR);
+ return 0;
+#endif
+#if defined(RISCV)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+ printf("../../asinfo: architecture \'%s\' is unsupported\n",
+ buf.machine);
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_arch_abi.test b/tools/asinfo/tests/get_arch_abi.test
new file mode 100755
index 00000000..d320c067
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --get-arch --raw > "$LOG"
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_sname.c b/tools/asinfo/tests/get_sname.c
new file mode 100644
index 00000000..5edd7877
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;\n"
+ "2;pwrite64;18;\n"
+ "3;pwritev;296;\n"
+ "4;pwritev2;328;\n"
+ "5;write;1;\n"
+ "6;writev;20;\n"
+ //--get-sname write,read
+ "1;read;0;\n"
+ "2;write;1;\n"
+ //--get-sname 1
+ "1;write;1;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_sname.test b/tools/asinfo/tests/get_sname.test
new file mode 100755
index 00000000..2bff806e
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_snum.c b/tools/asinfo/tests/get_snum.c
new file mode 100644
index 00000000..ada19312
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;\n"
+ //--get-snum /write
+ "1;1;write;\n"
+ "2;18;pwrite64;\n"
+ "3;20;writev;\n"
+ "4;296;pwritev;\n"
+ "5;311;process_vm_writev;\n"
+ "6;328;pwritev2;\n"
+ //--get-snum write,read
+ "1;0;read;\n"
+ "2;1;write;\n"
+ //--get-snum 1
+ "1;1;write;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_snum.test b/tools/asinfo/tests/get_snum.test
new file mode 100755
index 00000000..02dceca4
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/init.sh b/tools/asinfo/tests/init.sh
new file mode 100644
index 00000000..1ab105d9
--- /dev/null
+++ b/tools/asinfo/tests/init.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# Copyright (c) 2011-2017 The strace developers.
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+ME_="${0##*/}"
+LOG="log"
+OUT="out"
+EXP="exp"
+ASINFO="../../asinfo"
+
+fail_() { warn_ "$ME_: failed test: $*"; exit 1; }
+warn_() { printf >&2 '%s\n' "$*"; }
+
+run_prog()
+{
+ if [ $# -eq 0 ]; then
+ set -- "../$NAME"
+ fi
+ args="$*"
+ "$@" || {
+ rc=$?
+ if [ $rc != 0 ]; then
+ fail_ "$args failed with code $rc"
+ fi
+ }
+}
+
+
+dump_log_and_fail_with()
+{
+ cat < "$LOG" >&2
+ fail_ "$*"
+}
+
+run_asinfo()
+{
+ args="$*"
+ $ASINFO "$@" 2>&1
+}
+
+match_diff()
+{
+ local output expected error
+ if [ $# -eq 0 ]; then
+ output="$LOG"
+ else
+ output="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ expected="$srcdir/$NAME.expected"
+ else
+ expected="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ error="$STRACE $args output mismatch"
+ else
+ error="$1"; shift
+ fi
+
+ diff -u -- "$expected" "$output" ||
+ fail_ "$error"
+}
+
+NAME="${ME_%.test}"
+TESTDIR="$NAME.dir"
+rm -rf -- "$TESTDIR"
+mkdir -- "$TESTDIR"
+cd "$TESTDIR"
+case "$srcdir" in
+ /*) ;;
+ *) srcdir="../$srcdir" ;;
+esac
+
diff --git a/tools/asinfo/tests/list_arch.c b/tools/asinfo/tests/list_arch.c
new file mode 100644
index 00000000..a8b91553
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" BFIN_32bit_STR"\n"
+ "2" IA64_64bit_STR"\n"
+ "3" M68K_32bit_STR"\n"
+ "4" SPARC64_64bit_STR"\n"
+ "5" SPARC64_32bit_STR"\n"
+ "6" SPARC_32bit_STR"\n"
+ "7" METAG_32bit_STR"\n"
+ "8" MIPS64_N64_STR"\n"
+ "9" MIPS64_N32_STR"\n"
+ "10" MIPS64_O32_STR"\n"
+ "11" MIPS_O32_STR"\n"
+ "12" ALPHA_64bit_STR"\n"
+ "13" PPC64_64bit_STR"\n"
+ "14" PPC64_32bit_STR"\n"
+ "15" PPC_32bit_STR"\n"
+ "16" AARCH64_64bit_STR"\n"
+ "17" AARCH64_eabi_STR"\n"
+ "18" ARM_oabi_STR"\n"
+ "19" ARM_eabi_STR"\n"
+ "20" AVR32_32bit_STR"\n"
+ "21" ARC_32bit_STR"\n"
+ "22" S390X_64bit_STR"\n"
+ "23" S390_32bit_STR"\n"
+ "24" PARISC_32bit_STR"\n"
+ "25" SH64_64bit_STR"\n"
+ "26" SH_32bit_STR"\n"
+ "27" X86_64_64bit_STR"\n"
+ "28" X86_64_X32_STR"\n"
+ "29" X86_64_32bit_STR"\n"
+ "30" X86_32bit_STR"\n"
+ "31" CRISV10_32bit_STR"\n"
+ "32" CRISV32_32bit_STR"\n"
+ "33" TILE_64bit_STR"\n"
+ "34" TILE_32bit_STR"\n"
+ "35" TILEPRO_32bit_STR"\n"
+ "36" MICROBLAZE_32bit_STR"\n"
+ "37" NIOS2_32bit_STR"\n"
+ "38" OR1K_32bit_STR"\n"
+ "39" XTENSA_32bit_STR"\n"
+ "40" RISCV_64bit_STR"\n"
+ "41" RISCV_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/list_arch.test b/tools/asinfo/tests/list_arch.test
new file mode 100755
index 00000000..263d69df
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --list-arch --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_sname.c b/tools/asinfo/tests/multiarch_get_sname.c
new file mode 100644
index 00000000..53d219a9
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;1;4;4;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;540;348;348;\n"
+ "2;pwrite64;18;18;181;181;\n"
+ "3;pwritev;296;535;334;334;\n"
+ "4;pwritev2;328;547;379;379;\n"
+ "5;write;1;1;4;4;\n"
+ "6;writev;20;516;146;146;\n"
+ //--get-sname write,read
+ "1;read;0;0;3;3;\n"
+ "2;write;1;1;4;4;\n"
+ //--get-sname 1
+ "1;exit;-;-;1;1;\n"
+ "2;write;1;1;-;-;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_sname.test b/tools/asinfo/tests/multiarch_get_sname.test
new file mode 100755
index 00000000..0ff7bb92
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_snum.c b/tools/asinfo/tests/multiarch_get_snum.c
new file mode 100644
index 00000000..27658d20
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ //--get-snum /write
+ "1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ "3;18;pwrite64;pwrite64;-;-;\n"
+ "4;20;writev;-;-;-;\n"
+ "5;146;-;-;writev;writev;\n"
+ "6;181;-;-;pwrite64;pwrite64;\n"
+ "7;296;pwritev;-;-;-;\n"
+ "8;311;process_vm_writev;-;-;-;\n"
+ "9;328;pwritev2;-;-;-;\n"
+ "10;334;-;-;pwritev;pwritev;\n"
+ "11;348;-;-;process_vm_writev;process_vm_writev;\n"
+ "12;379;-;-;pwritev2;pwritev2;\n"
+ "13;516;-;writev;-;-;\n"
+ "14;535;-;pwritev;-;-;\n"
+ "15;540;-;process_vm_writev;-;-;\n"
+ "16;547;-;pwritev2;-;-;\n"
+ //--get-snum write,read
+ "1;0;read;read;-;-;\n"
+ "2;1;write;write;-;-;\n"
+ "3;3;-;-;read;read;\n"
+ "4;4;-;-;write;write;\n"
+ //--get-snum 1
+ "1;1;write;write;exit;exit;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_snum.test b/tools/asinfo/tests/multiarch_get_snum.test
new file mode 100755
index 00000000..364903a6
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/ref_asinfo_output.h b/tools/asinfo/tests/ref_asinfo_output.h
new file mode 100644
index 00000000..bc5fce4c
--- /dev/null
+++ b/tools/asinfo/tests/ref_asinfo_output.h
@@ -0,0 +1,42 @@
+/* Reference output strings for asinfo tool which are necessary for tests */
+#define BFIN_32bit_STR ";blackfin/bfin;32bit;391;external;external;"
+#define IA64_64bit_STR ";ia64;64bit;707;external;external;"
+#define M68K_32bit_STR ";m68k;32bit;378;internal;internal;"
+#define SPARC64_64bit_STR ";sparc64;64bit;340;internal;internal;"
+#define SPARC64_32bit_STR ";sparc64;32bit;358;internal;internal;"
+#define SPARC_32bit_STR ";sparc;32bit;358;internal;internal;"
+#define METAG_32bit_STR ";metag;32bit;280;external;external;"
+#define MIPS64_N64_STR ";mips64/mips64le;n64;1000;int/ext;int/ext;"
+#define MIPS64_N32_STR ";mips64/mips64le;n32;1004;int/ext;int/ext;"
+#define MIPS64_O32_STR ";mips64/mips64le;o32;1039;internal;internal;"
+#define MIPS_O32_STR ";mips/mipsle;o32;1039;internal;internal;"
+#define ALPHA_64bit_STR ";alpha;64bit;442;external;external;"
+#define PPC64_64bit_STR ";ppc64/ppc64le/powerpc64;64bit;374;int/ext;int/ext;"
+#define PPC64_32bit_STR ";ppc64/ppc64le/powerpc64;32bit;383;int/ext;int/ext;"
+#define PPC_32bit_STR ";ppc/ppcle/powerpc;32bit;383;int/ext;int/ext;"
+#define AARCH64_64bit_STR ";aarch64/arm64;64bit;332;external;external;"
+#define AARCH64_eabi_STR ";aarch64/arm64;eabi;400;external;external;"
+#define ARM_oabi_STR ";arm;oabi;400;int/ext;int/ext;"
+#define ARM_eabi_STR ";arm;eabi;400;external;external;"
+#define AVR32_32bit_STR ";avr32;32bit;329;external;external;"
+#define ARC_32bit_STR ";arc;32bit;281;external;external;"
+#define S390X_64bit_STR ";s390x;64bit;326;internal;internal;"
+#define S390_32bit_STR ";s390;32bit;359;internal;internal;"
+#define PARISC_32bit_STR ";parisc/hppa;32bit;349;external;external;"
+#define SH64_64bit_STR ";sh64;64bit;382;int/ext;int/ext;"
+#define SH_32bit_STR ";sh;32bit;374;internal;internal;"
+#define X86_64_64bit_STR ";x86_64/amd64/EM64T;64bit;333;external;external;"
+#define X86_64_X32_STR ";x86_64/amd64/EM64T;x32;369;external;external;"
+#define X86_64_32bit_STR ";x86_64/amd64/EM64T;32bit;381;internal;internal;"
+#define X86_32bit_STR ";x86/i386/i486/i586/i686;32bit;381;internal;internal;"
+#define CRISV10_32bit_STR ";cris/crisv10;32bit;355;internal;internal;"
+#define CRISV32_32bit_STR ";crisv32;32bit;355;internal;internal;"
+#define TILE_64bit_STR ";tile/tilegx;64bit;278;external;external;"
+#define TILE_32bit_STR ";tile/tilegx;32bit;278;external;external;"
+#define TILEPRO_32bit_STR ";tilepro;32bit;278;external;external;"
+#define MICROBLAZE_32bit_STR ";microblaze;32bit;395;external;external;"
+#define NIOS2_32bit_STR ";nios2;32bit;277;external;external;"
+#define OR1K_32bit_STR ";openrisc/or1k;32bit;277;external;external;"
+#define XTENSA_32bit_STR ";xtensa;32bit;325;external;external;"
+#define RISCV_64bit_STR ";riscv;64bit;276;external;external;"
+#define RISCV_32bit_STR ";riscv;32bit;276;external;external;"
diff --git a/tools/asinfo/tests/set_abi.c b/tools/asinfo/tests/set_abi.c
new file mode 100644
index 00000000..b74e0ccb
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_abi.test b/tools/asinfo/tests/set_abi.test
new file mode 100755
index 00000000..70b1f429
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_arch.c b/tools/asinfo/tests/set_arch.c
new file mode 100644
index 00000000..05f44b79
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" X86_64_X32_STR "\n"
+ "3" X86_64_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_arch.test b/tools/asinfo/tests/set_arch.test
new file mode 100755
index 00000000..e9a102c6
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --list-abi --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_abi.c b/tools/asinfo/tests/set_mult_abi.c
new file mode 100644
index 00000000..4107fabb
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" AARCH64_64bit_STR "\n"
+ "3" AARCH64_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_abi.test b/tools/asinfo/tests/set_mult_abi.test
new file mode 100755
index 00000000..555c27ca
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,aarch64 --set-abi 64bit,all --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_arch.c b/tools/asinfo/tests/set_mult_arch.c
new file mode 100644
index 00000000..ed8d66df
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" AARCH64_64bit_STR "\n"
+ "2" AARCH64_eabi_STR "\n"
+ "3" ARM_oabi_STR "\n"
+ "4" ARM_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_arch.test b/tools/asinfo/tests/set_mult_arch.test
new file mode 100755
index 00000000..d0152d60
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch aarch64,arm --list-abi --raw >> $LOG
+match_diff "$LOG" "$EXP"
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:03:06
|
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 448a9cb3..8ae25fbd 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ Noteworthy changes in release ?.?? (????-??-??) * Bug fixes * Fixed multi-personality support in cross builds. +* New tools + * Added asinfo tool, that is purposed to provide information about + system calls and architectures. + Noteworthy changes in release 4.20 (2017-11-13) =============================================== -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:03:05
|
As asinfo detects ABI mode based on userspace environment in biarch
systems, add asinfo only to strace package.
* debian/control (strace, strace-udeb): Add asinfo decription.
* debian/strace.install: Add path to asinfo binary.
* debian/strace.manpages: Add path to asinfo man.
* strace.spec.in (%files): Add asinfo binary.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
debian/control | 6 ++++++
debian/strace.install | 1 +
debian/strace.manpages | 1 +
strace.spec.in | 7 +++++--
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/debian/control b/debian/control
index 92cdc204..f47b36a1 100644
--- a/debian/control
+++ b/debian/control
@@ -20,6 +20,9 @@ Description: System call tracer
System calls and signals are events that happen at the user/kernel
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
+ .
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
Package: strace64
Architecture: i386 powerpc s390 sparc
@@ -54,5 +57,8 @@ Description: System call tracer
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
.
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
+ .
This is a stripped down package intended for debugging use in the Debian
installer.
diff --git a/debian/strace.install b/debian/strace.install
index 30b0a6b0..1e2401bb 100644
--- a/debian/strace.install
+++ b/debian/strace.install
@@ -1,2 +1,3 @@
build/strace usr/bin
strace-log-merge usr/bin
+build/tools/asinfo/asinfo usr/bin
diff --git a/debian/strace.manpages b/debian/strace.manpages
index d3b94482..cd0be9eb 100644
--- a/debian/strace.manpages
+++ b/debian/strace.manpages
@@ -1,2 +1,3 @@
strace.1
strace-log-merge.1
+build/tools/asinfo/asinfo.1
diff --git a/strace.spec.in b/strace.spec.in
index 41b69d0e..cbd15995 100644
--- a/strace.spec.in
+++ b/strace.spec.in
@@ -21,7 +21,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -36,7 +37,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -92,6 +94,7 @@ echo 'END OF TEST SUITE INFORMATION'
%{?suse_version:%defattr(-,root,root)}
%doc CREDITS ChangeLog ChangeLog-CVS COPYING NEWS README
%{_bindir}/strace
+${_bindir}/asinfo
%{_bindir}/strace-log-merge
%{_mandir}/man1/*
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:03:04
|
Since arch_definitions.h contains full description about architectures, arch_includes.h and arch_personalities.h can be generated. * tools/asinfo/gen_asinfo_files.sh: New file. * bootstrap: Add it. * tools/asinfo/arch_includes.h: Delete it. * tools/asinfo/arch_personalities.h: Likewise. * tools/asinfo/Makefile.am: Include Makemodule.am. (asinfo_SOURCES): Add $(ARCH_AUX_FILES). * tools/asinfo/README-arch: New README explaining how to add new architecture/ABI to asinfo tool. * tools/asinfo/.gitignore: Add generated files. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- bootstrap | 1 + configure.ac | 5 + tools/asinfo/.gitignore | 3 + tools/asinfo/Makefile.am | 6 +- tools/asinfo/README-arch | 38 ++++++ tools/asinfo/arch_includes.h | 272 ------------------------------------ tools/asinfo/arch_personalities.h | 36 ----- tools/asinfo/asinfo.1.in | 280 ++++++++++++++++++++++++++++++++++++++ tools/asinfo/gen_asinfo_files.sh | 160 ++++++++++++++++++++++ 9 files changed, 491 insertions(+), 310 deletions(-) create mode 100644 tools/asinfo/README-arch delete mode 100644 tools/asinfo/arch_includes.h delete mode 100644 tools/asinfo/arch_personalities.h create mode 100644 tools/asinfo/asinfo.1.in create mode 100755 tools/asinfo/gen_asinfo_files.sh diff --git a/bootstrap b/bootstrap index a9cadf53..da06de3b 100755 --- a/bootstrap +++ b/bootstrap @@ -4,6 +4,7 @@ ./xlat/gen.sh ./tests/gen_pure_executables.sh ./tests/gen_tests.sh +./tools/asinfo/gen_asinfo_files.sh for m in m32 mx32; do tests=tests-$m diff --git a/configure.ac b/configure.ac index 0492bd8b..79690ba1 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AC_INIT([strace], [https://strace.io]) m4_define([copyright_year], m4_esyscmd([./copyright-year-gen .year])) m4_define([manpage_date], m4_esyscmd([./file-date-gen strace.1.in])) +m4_define([asinfo_manpage_date], m4_esyscmd([./file-date-gen tools/asinfo/asinfo.1.in])) AC_COPYRIGHT([Copyright (c) 1999-]copyright_year[ The strace developers.]) AC_CONFIG_SRCDIR([strace.c]) AC_CONFIG_AUX_DIR([.]) @@ -67,6 +68,9 @@ AC_SUBST([COPYRIGHT_YEAR], [copyright_year]) AC_DEFINE([MANPAGE_DATE], "[manpage_date]", [Date]) AC_SUBST([MANPAGE_DATE], [manpage_date]) +AC_DEFINE([ASINFO_MANPAGE_DATE], "[asinfo_manpage_date]", [Date]) +AC_SUBST([ASINFO_MANPAGE_DATE], [asinfo_manpage_date]) + AC_MSG_CHECKING([for supported architecture]) arch_m32= arch_mx32= @@ -904,6 +908,7 @@ AC_CONFIG_FILES([Makefile tests-mx32/Makefile strace.1 strace-log-merge.1 + tools/asinfo/asinfo.1 tools/Makefile tools/asinfo/Makefile strace.spec diff --git a/tools/asinfo/.gitignore b/tools/asinfo/.gitignore index 09400c47..3254269c 100644 --- a/tools/asinfo/.gitignore +++ b/tools/asinfo/.gitignore @@ -1,2 +1,5 @@ +arch_includes.h +arch_personalities.h asinfo asinfo.1 +Makemodule.am diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am index 5051766e..f2b23e74 100644 --- a/tools/asinfo/Makefile.am +++ b/tools/asinfo/Makefile.am @@ -38,6 +38,9 @@ AM_CPPFLAGS = -I$(builddir) \ -I$(top_srcdir)/$(OS) \ -I$(top_builddir) \ -I$(top_srcdir) + +include Makemodule.am + asinfo_CPPFLAGS = $(AM_CPPFLAGS) asinfo_CFLAGS = $(AM_CFLAGS) asinfo_LDFLAGS = @@ -47,10 +50,9 @@ asinfo_LDADD = -L$(top_srcdir) \ asinfo_SOURCES = \ arch_definitions.h \ - arch_includes.h \ arch_interface.c \ + $(ARCH_AUX_FILES) \ arch_interface.h \ - arch_personalities.h \ asinfo.c \ dispatchers.c \ dispatchers.h \ diff --git a/tools/asinfo/README-arch b/tools/asinfo/README-arch new file mode 100644 index 00000000..6b73aa01 --- /dev/null +++ b/tools/asinfo/README-arch @@ -0,0 +1,38 @@ +This file describes the storage format of arch_definitions.h + +Storage format: +/* [ARCH_SPECIFIC_DEFINE],[ACONST1,ACONST2] */ +ARCH_DESC_DEFINE(ARCH_NAME,ARCH_ABI,PASS({COMPAT_PERS1,COMPAT_PERS2,...}),\ +PASS({ALIAS1,ALIAS2,...})) + +ARCH_SPECIFIC_DEFINE: +One syscallent.h header can contain several set of system calls for each +compatible mode. And specific set can be switched by passing particular +definition. +So ARCH_SPECIFIC_DEFINE allows to forward a given definition, where +!ARCH_SPECIFIC_DEFINE forwards undefined. +If it is not required, left empty. + +ACONST1,ACONST2: +It could be used to store architecture specific constants and pass them to code. +If is is not required each one must be set to zero. + +ARCH_NAME: +The main name of architecture will be used to generate the personality +constants. +The personality constant is equal to ARCH_+\$ARCH_ABI+_+\$ARCH_NAME. + +ARCH_ABI: +Application binary interface for a given architecture, i.e. 32bit, 64bit, oabi, +eabi, o32 etc. + +COMPAT_PERS1,COMPAT_PERS2,...: +Compatible mode for a given architecture. It should be one of personality +constants. +If is is not required, left empty. + +ALIAS1,ALIAS2,...: +Other name of the same architecture, like x86 and i386. At least one alias +must to be set as it shows the name of architecture while printing. +If current ARCH_NAME is just the compatible ABI mode, left empty. + diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h deleted file mode 100644 index e73a8328..00000000 --- a/tools/asinfo/arch_includes.h +++ /dev/null @@ -1,272 +0,0 @@ -/* ARCH_blackfin */ -static const struct_sysent blackfin_32bit_sysent[] = { - #include "bfin/syscallent.h" -}; -static const int blackfin_32bit_usr1 = 0; -const int blackfin_32bit_usr2 = 0; -/* ARCH_ia64 */ -struct_sysent ia64_64bit_sysent[] = { - #include "ia64/syscallent.h" -}; -static const int ia64_64bit_usr1 = 0; -static const int ia64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_m68k */ -static const struct_sysent m68k_32bit_sysent[] = { - #include "m68k/syscallent.h" -}; -static const int m68k_32bit_usr1 = 0; -static const int m68k_32bit_usr2 = 0; -/* ARCH_sparc64 64bit ABI */ -static const struct_sysent sparc64_64bit_sysent[] = { - #include "sparc64/syscallent.h" -}; -static const int sparc64_64bit_usr1 = 0; -static const int sparc64_64bit_usr2 = 0; -/* ARCH_sparc and 32bit ABI */ -static const struct_sysent sparc_32bit_sysent[] = { - #include "sparc/syscallent.h" -}; -static const int sparc_32bit_usr1 = 0; -static const int sparc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_metag */ -static const struct_sysent metag_32bit_sysent[] = { - #include "metag/syscallent.h" -}; -static const int metag_32bit_usr1 = 0; -static const int metag_32bit_usr2 = 0; -/* ARCH_mips n64 ABI */ -#ifndef LINUX_MIPSN64 -# define LINUX_MIPSN64 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n64_usr1 = 0; -static const int mips64_n64_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips n32 ABI */ -#ifndef LINUX_MIPSN32 -# define LINUX_MIPSN32 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n32_usr1 = 0; -static const int mips64_n32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips o32 ABI */ -#ifndef LINUX_MIPSO32 -# define LINUX_MIPSO32 1 -# define NOW_DEFINED 1 -#endif -static const 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 -static const int mips_o32_usr1 = 0; -static const int mips_o32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_alpha */ -static const struct_sysent alpha_64bit_sysent[] = { - #include "alpha/syscallent.h" -}; -static const int alpha_64bit_usr1 = 0; -static const int alpha_64bit_usr2 = 0; -/* ARCH_ppc64 64bit ABI */ -static const struct_sysent ppc64_64bit_sysent[] = { - #include "powerpc64/syscallent.h" -}; -static const int ppc64_64bit_usr1 = 0; -static const int ppc64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_ppc and 32bit */ -static const struct_sysent ppc_32bit_sysent[] = { - #include "powerpc/syscallent.h" -}; -static const int ppc_32bit_usr1 = 0; -static const int ppc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_aarch64 64bit ABI */ -static const struct_sysent aarch64_64bit_sysent[] = { - #include "aarch64/syscallent.h" -}; -static const int aarch64_64bit_usr1 = 0; -static const int aarch64_64bit_usr2 = 0; -/* ARCH_arm OABI*/ -#ifdef __ARM_EABI__ -# undef __ARM_EABI__ -# define NOW_UNDEFINED 1 -#endif -static const struct_sysent arm_oabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL; -#undef ARM_FIRST_SHUFFLED_SYSCALL -#undef ARM_LAST_SPECIAL_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 -static const struct_sysent arm_eabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_eabi_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 */ -static const struct_sysent avr32_32bit_sysent[] = { - #include "avr32/syscallent.h" -}; -static const int avr32_32bit_usr1 = 0; -static const int avr32_32bit_usr2 = 0; -/* ARCH_arc */ -static const struct_sysent arc_32bit_sysent[] = { - #include "arc/syscallent.h" -}; -static const int arc_32bit_usr1 = 0; -static const int arc_32bit_usr2 = 0; -/* ARCH_s390x */ -static const struct_sysent s390x_64bit_sysent[] = { - #include "s390x/syscallent.h" -}; -static const int s390x_64bit_usr1 = 0; -static const int s390x_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_s390 */ -static const struct_sysent s390_32bit_sysent[] = { - #include "s390/syscallent.h" -}; -static const int s390_32bit_usr1 = 0; -static const int s390_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_hppa */ -static const struct_sysent hppa_32bit_sysent[] = { - #include "hppa/syscallent.h" -}; -static const int hppa_32bit_usr1 = 0; -static const int hppa_32bit_usr2 = 0; -/* ARCH_sh64 */ -static const struct_sysent sh64_64bit_sysent[] = { - #include "sh64/syscallent.h" -}; -static const int sh64_64bit_usr1 = 0; -static const int sh64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_sh */ -static const struct_sysent sh_32bit_sysent[] = { - #include "sh/syscallent.h" -}; -static const int sh_32bit_usr1 = 0; -static const int sh_32bit_usr2 = 0; -/* ARCH_x86_64 64bit ABI mode */ -static const struct_sysent x86_64_64bit_sysent[] = { - #include "x86_64/syscallent.h" -}; -static const int x86_64_64bit_usr1 = 0; -static const int x86_64_64bit_usr2 = 0; -/* ARCH_x86_64 x32 ABI mode */ -static const struct_sysent x86_64_x32_sysent[] = { - #include "x86_64/syscallent2.h" -}; -static const int x86_64_x32_usr1 = 0; -static const int x86_64_x32_usr2 = 0; -/* ARCH_x86 */ -static const struct_sysent x86_32bit_sysent[] = { - #include "i386/syscallent.h" -}; -static const int x86_32bit_usr1 = 0; -static const int x86_32bit_usr2 = 0; -/* ARCH_cris */ -static struct_sysent cris_32bit_sysent[] = { - #include "crisv10/syscallent.h" -}; -static const int cris_32bit_usr1 = 0; -static const int cris_32bit_usr2 = 0; -/* ARCH_crisv32 */ -static const struct_sysent crisv32_32bit_sysent[] = { - #include "crisv32/syscallent.h" -}; -static const int crisv32_32bit_usr1 = 0; -static const int crisv32_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_tile 64bit ABI mode */ -static const struct_sysent tile_64bit_sysent[] = { - #include "tile/syscallent.h" -}; -static const int tile_64bit_usr1 = 0; -static const int tile_64bit_usr2 = 0; -/* ARCH_tile 32bit ABI mode */ -static const struct_sysent tile_32bit_sysent[] = { - #include "tile/syscallent1.h" -}; -static const int tile_32bit_usr1 = 0; -static const int tile_32bit_usr2 = 0; -/* ARCH_microblaze */ -static const struct_sysent microblaze_32bit_sysent[] = { - #include "microblaze/syscallent.h" -}; -static const int microblaze_32bit_usr1 = 0; -static const int microblaze_32bit_usr2 = 0; -/* ARCH_nios2 */ -static const struct_sysent nios2_32bit_sysent[] = { - #include "nios2/syscallent.h" -}; -static const int nios2_32bit_usr1 = 0; -static const int nios2_32bit_usr2 = 0; -/* ARCH_openrisc */ -struct_sysent openrisc_32bit_sysent[] = { - #include "or1k/syscallent.h" -}; -static const int openrisc_32bit_usr1 = 0; -static const int openrisc_32bit_usr2 = 0; -/* ARCH_xtensa */ -static const struct_sysent xtensa_32bit_sysent[] = { - #include "xtensa/syscallent.h" -}; -static const int xtensa_32bit_usr1 = 0; -static const int xtensa_32bit_usr2 = 0; -/* ARCH_riscv 64bit ABI mode */ -static const struct_sysent riscv_64bit_sysent[] = { - #include "riscv/syscallent.h" -}; -static const int riscv_64bit_usr1 = 0; -static const int riscv_64bit_usr2 = 0; -/* ARCH_riscv 32bit ABI mode */ -static const struct_sysent riscv_32bit_sysent[] = { - #include "riscv/syscallent1.h" -}; -static const int riscv_32bit_usr1 = 0; -static const int riscv_32bit_usr2 = 0; diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h deleted file mode 100644 index 9499c5aa..00000000 --- a/tools/asinfo/arch_personalities.h +++ /dev/null @@ -1,36 +0,0 @@ -ARCH_no_pers, -ARCH_blackfin_32bit, -ARCH_ia64_64bit, -ARCH_m68k_32bit, -ARCH_sparc64_64bit, -ARCH_sparc_32bit, -ARCH_metag_32bit, -ARCH_mips64_n64, -ARCH_mips64_n32, -ARCH_mips_o32, -ARCH_alpha_64bit, -ARCH_ppc64_64bit, -ARCH_ppc_32bit, -ARCH_aarch64_64bit, -ARCH_arm_oabi, -ARCH_arm_eabi, -ARCH_avr32_32bit, -ARCH_arc_32bit, -ARCH_s390x_64bit, -ARCH_s390_32bit, -ARCH_hppa_32bit, -ARCH_sh64_64bit, -ARCH_sh_32bit, -ARCH_x86_64_64bit, -ARCH_x86_64_x32, -ARCH_x86_32bit, -ARCH_cris_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 diff --git a/tools/asinfo/asinfo.1.in b/tools/asinfo/asinfo.1.in new file mode 100644 index 00000000..009c69ed --- /dev/null +++ b/tools/asinfo/asinfo.1.in @@ -0,0 +1,280 @@ +.\" Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...> +.\" Copyright (c) 1996-2017 The strace developers. +.\" 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. + +.\" Required option. +.de OR +. ie \\n(.$-1 \ +. RI "\fB\\$1\fP" "\ \\$2" +. el \ +. BR "\\$1" +.. +.TH ASINFO 1 "@ASINFO_MANPAGE_DATE@" "strace package @VERSION@" +.SH NAME +asinfo \- advanced system call information tool +.SH SYNOPSIS +.SY asinfo +.BR "" \fR[{ +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" } +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR]\fR] +.BR "" { +.BR "" { +.OR \-\-get\-sname expr +.BR "" | +.OR \-\-get\-snum expr +.BR "" } +.OP \-\-nargs +.BR "" } +.OP "\-\-raw" +.YS +.SY asinfo +.BR "" { +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" | +.OR \-\-list\-arch +.BR "" } +.BD "" [ +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR] +.OP "\-\-raw" + +.SH DESCRIPTION +.B asinfo +is a useful tool, which aimed to provide information about system calls, +architectures, and application binary interfaces (ABIs). In the simplest +case it provides mapping from system call name to number and reverse. +The main advantage of tool is it can work in single/multi arch modes with +the opportunity to show discrepancies in system call characteristics. +Also, the single arch mode allows program to take a guess about the +current architecture and ABI, if they are not specified. Furthermore, +.B asinfo +provides convenient filtering for selecting system calls. + +.SH OPTIONS +.SS "Architecture parameters" +.TP 7 +.BI "\-\-set\-arch " arch +Specify architecture/architectures manually. The format of the +.I arch +expression is: +.RS 9 +.IP +\fIarch1\/\fR[\fB,\fIarch2\/\fR]... +.RE +.IP +.TP +.B \-\-get\-arch +Select achitecture based on the current machine. +.TP +.B \-\-list-arch +Print out all supported architectures. +Combined use with any ABI option is permitted. +.SS "ABI parameters" +.TP 7 +.BI "\-\-set\-abi " abi +Specify ABI/ABIs manually. The format of the experession is: +.RS 9 +.IP +\fIabi1\/\fR[\fB,\fIabi2\/\fR]... +.RE +.IP +.IP +Note that ABI should be selected for each corresponding architecture. +In addition, the special value +.B all +allows to choose all ABIs for the respective architecture. +.TP +.B "\-\-list\-abi " +Select all ABIs for the chosen architecture/architectures. +.IP +If ABI parameters are not used and only single architecture is selected, tool +will take a guess about ABI based on the strace package build. +.SS "System call parameters" +.TP 7 +.BI "\-\-get\-sname " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out name of system calls and numbers for each architecture/ABI. +.TP +.BI "\-\-get\-snum " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out number of system calls and names for each architecture/ABI. +.TP +.B \-\-nargs +Switch the second output system call characteristic to number of arguments. +.SS Output formatting +.TP 7 +.B "\-\-raw" +Reset alignment and remove titles, use ';' as a delimiter. +.SS Miscellaneous +.TP 7 +.B \-h +Print the help summary. +.TP +.B \-v +Print the version number. + +.SH "FILTERING EXPRESSION" +A filtering expression is a pattern that describes a set of syscall names, +syscall numbers, and syscall group. The format of the expression is: +.RS 2 +.IP +[\fB!\fR][\fB?\fR]\,\fIvalue1\/\fR[\fB,\fR[\fB?\fR]\,\fIvalue2\/\fR]... +.RE +.LP +where +.I value +is a symbol or number. Using an exclamation mark negates the set of values. +For example, +.BR \fIvalue\fR = write +means print strictly the write system call. By contrast, +.BR \fIvalue\fR = !write +means to dump every system call except write. Question mark before the +syscall qualification allows suppression of error in case no syscalls matched +the qualification provided, that can be particularly useful in multiarch mode, +when system call is not presented in all selected architectures. In addition, +the special values +.B all +and +.B none +have the obvious meanings. +.LP +Note that some shells use the exclamation point for history +expansion even inside quoted arguments. If so, you must escape +the exclamation point with a backslash. +.SS "Strict match" +.TP 7 +.B \fIvalue\fR=\,\fIset\fR +Print out only the specified set of system calls. For example, +.BR \fIvalue\fR = open,close,read,write +means to only show those four system calls. +.SS "Regex match" +.TP 7 +.B \fIvalue\fR=/\,\fIregex\fR +Show only those system calls that match the +.IR regex . +You can use +.B POSIX +Extended Regular Expression syntax (see +.BR regex (7)). +.SS "Class match" +.TP 7 +.BR \fIvalue\fR = %file +.TQ +.BR \fIvalue\fR = file " (deprecated)" +Show all system calls which take a file name as an argument. You +can think of this as an abbreviation for +.BR \fIvalue\fR = open,stat,chmod,unlink,... +Furthermore, using the abbreviation will ensure that you don't +accidentally forget to include a call like +.B lstat +in the list. +.PP +.BR \fIvalue\fR = %process +.TQ +.BR \fIvalue\fR = process " (deprecated)" +Show all system calls which involve process management. +.PP +.BR \fIvalue\fR = %network +.TQ +.BR \fIvalue\fR = network " (deprecated)" +Show all the network related system calls. +.PP +.BR \fIvalue\fR = %signal +.TQ +.BR \fIvalue\fR = signal " (deprecated)" +Show all signal related system calls. +.PP +.BR \fIvalue\fR = %ipc +.TQ +.BR \fIvalue\fR = ipc " (deprecated)" +Show all IPC related system calls. +.PP +.BR \fIvalue\fR = %desc +.TQ +.BR \fIvalue\fR = desc " (deprecated)" +Show all file descriptor related system calls. +.PP +.BR \fIvalue\fR = %memory +.TQ +.BR \fIvalue\fR = memory " (deprecated)" +Show all memory mapping related system calls. +.TP +.BR \fIvalue\fR = %stat +Show stat syscall variants. +.TP +.BR \fIvalue\fR = %lstat +Show lstat syscall variants. +.TP +.BR \fIvalue\fR = %fstat +Show fstat and fstatat syscall variants. +.TP +.BR \fIvalue\fR = %%stat +Show syscalls used for requesting file status (stat, lstat, fstat, fstatat, +statx, and their variants). +.TP +.BR \fIvalue\fR = %statfs +Show statfs, statfs64, statvfs, osf_statfs, and osf_statfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /^(.*_)?statv?fs +regular expression. +.TP +.BR \fIvalue\fR = %fstatfs +Show fstatfs, fstatfs64, fstatvfs, osf_fstatfs, and osf_fstatfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /fstatv?fs +regular expression. +.TP +.BR \fIvalue\fR = %%statfs +Show syscalls related to file system statistics (statfs-like, fstatfs-like, +and ustat). The same effect can be achieved with +.BR \fIvalue\fR = /statv?fs|fsstat|ustat +regular expression. + +.SH "EXIT STATUS" +On success, +.B asinfo +returns 0. Otherwise, in case of wrong input or no matches found, 1. + +.SH "REPORTING BUGS" +Problems with +.B asinfo +should be reported to the +.B strace +mailing list at <str...@li...>. + +.SH "SEE ALSO" +.BR strace (1) diff --git a/tools/asinfo/gen_asinfo_files.sh b/tools/asinfo/gen_asinfo_files.sh new file mode 100755 index 00000000..bd7b33ae --- /dev/null +++ b/tools/asinfo/gen_asinfo_files.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# +# Code generator simplifies addition of new architecture to asinfo tool +# +# Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...> +# 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. + +cur_pers="" + +gen_pers_line() +{ + local out_file="$1" + local line="$2" + local arch_abi="" + + LC_COLLATE=C + arch_abi="$(printf %s "${line}" | + sed 's/ARCH_DESC_DEFINE(//' | cut -d, -f 1,2 | + sed 's/,/_/g')" + cur_pers="${arch_abi}" + echo "ARCH_${arch_abi}," >> "${out_file}" +} + +gen_includes_block() +{ + local out_file="$1" + local line="$2" + local def is_def includes include nums num count + + ( + LC_COLLATE=C + echo "/* ${cur_pers} */" + def="$(printf %s "${line#*\*}" | cut -d] -f 1 | sed 's/.*[][]//g')" + #Generate define construction + if [ "${def#!}" != "" ] && [ $(printf %.1s "${def}") = "!" ]; then + cat <<-EOF + #ifdef ${def#!} + # undef ${def#!} + # define ${def#!}_DUMMY_UNDEFINE + #endif + EOF + is_def="def" + else if [ "${def#!}" != "" ]; then + cat <<-EOF + #ifndef ${def} + # define ${def} + # define ${def}_DUMMY_DEFINE + #endif + EOF + is_def="undef" + fi + fi + #Generate includes + includes="$(printf %s "${line#*\*}" | cut -d] -f 2 | sed 's/.*[][]//g')" + echo "static const struct_sysent ${cur_pers}_sysent[] = {" + for include in $(echo "${includes}" | sed "s/,/ /g") + do + echo " #include \"${include}\"" + done + echo "};" + #Undefine definitions, if it is required + if [ "${is_def}" = "def" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_UNDEFINE + # define ${def#!} 1 + # undef ${def#!}_DUMMY_UNDEFINE + #endif + EOF + else if [ "${is_def}" = "undef" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_DEFINE + # undef ${def#!} + # undef ${def#!}_DUMMY_DEFINE + #endif + EOF + fi + fi + #Generate arch specific numbers + nums="$(printf %s "${line#*\*}" | cut -d] -f 3 | sed 's/.*[][]//g')" + count=1 + for num in $(echo "${nums}" | sed "s/,/ /g") + do + echo "static const int ${cur_pers}_usr${count} = ${num};" + count=$((count+1)) + case "${num}" in + *[A-Za-z_]*) echo "#undef ${num}" ;; + *) ;; + esac + done + if [ $count -eq 1 ]; then + echo "static const int ${cur_pers}_usr${count} = 0;" + fi + echo "#undef SYS_socket_subcall" + ) >> "${out_file}" + echo "${def}" >> "${out_file}" +} + +main() +{ + set -- "${0%/*}" "${0%/*}" + + local input="$1" + local output="$2" + local defs_file="arch_definitions.h" + local pers_file="arch_personalities.h" + local includes_file="arch_includes.h" + local pline="" + + echo "ARCH_no_pers," > "${output}/${pers_file}" + echo -n > "${output}/${includes_file}" + + #Main work + while read line; do + line="$(printf %s "${line}" | sed 's/[[:space:]]//g')" + if $(printf %s "${line}" | + grep -F "ARCH_DESC_DEFINE" > /dev/null); then + gen_pers_line "${output}/${pers_file}" "${line}" + fi + if $(printf %s "${pline}" | grep -F "/*" > /dev/null); then + gen_includes_block "${output}/${includes_file}"\ + "${pline}" + fi + pline="${line}" + done < "${input}/${defs_file}" + #Makemodule.am + ( + printf "ARCH_AUX_FILES = ${includes_file} ${pers_file}" + echo + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${includes_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${pers_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + ) > "${output}/Makemodule.am" +} + +main "$@" -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:03:01
|
The main purpose of this query tool is to present all information concluded
at sysent.h files in a convenient way.
The asinfo tool has the following staged architecture:
(command dispatcher)->(architecture dispatcher)->
(abi dispatcher)->(system call dispatcher).
Each dispatcher accepts proccesed data from the previous one.
This point can be illustrated by the following example:
$ asinfo --get-arch --get-sname write
First of all, arch_dispatcher will return the current architecture, based on
uname return value, after that in case of no options for abi_dispatcher,
it perceives empty parameter as get-abi parameter and returns ABI mode set at
compile time of strace package. Therefore, syscall_dispatcher accepts this
architecture/ABI and works with specific set of system calls. It is worth
mentioning that it supports all architectures/ABIs supported by strace.
Also, tool can work in multi-arch mode. for instance:
$ ./tools/asinfo/asinfo --set-arch mips64,mips --set-abi n64,all
--get-snum 100,8,ipc
For more info, use asinfo -h.
* Makefile.am (SUBDIRS): Add tools directory.
* configure.ac (AC_CONFIG_FILES): Add Makefiles.
* tools/Makefile.am: New file.
* tools/asinfo/Makefile.am: Likewise.
* tools/asinfo/dispatchers.h: New file. Prototype abi_dispatcher,
arch_dispatcher, and syscall_dispatcher.
* tools/asinfo/dispatchers.c: New file. Implement them.
* tools/asinfo/error_interface.h: New file. Introduce error_service to
improve informativeness of output errors. Prototype methods to work with
error_service.
* tools/asinfo/error_interface.c: New file. Implement it.
* tools/asinfo/arch_interface.h: New file. Introduce struct
arch_descriptor. Introduce arch_service. Prototype methods to simplify
work with the arch_service.
* tools/asinfo/arch_interface.c: New file. Implement it.
* tools/asinfo/syscall_interface.h: New file. Introduce syscall_service.
Prototype methods to simplify work with syscall_service.
* tools/asinfo/syscall_interface.c: New file. Implement it.
* tools/asinfo/request_msgs.h: New file. Introduce main requests.
* tools/asinfo/asinfo.c: New file. Implement support of all options.
Implement usage. Implement version.
* tools/asinfo/arch_definitions.h: New file. Introduce useful storage
for architectures.
* tools/asinfo/arch_includes.h: New file.
* tools/asinfo/personalities.h: Likewise.
* tools/asinfo/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
Makefile.am | 2 +-
configure.ac | 2 +
tools/Makefile.am | 28 ++
tools/asinfo/.gitignore | 2 +
tools/asinfo/Makefile.am | 62 ++++
tools/asinfo/arch_definitions.h | 70 ++++
tools/asinfo/arch_includes.h | 272 +++++++++++++++
tools/asinfo/arch_interface.c | 654 ++++++++++++++++++++++++++++++++++++
tools/asinfo/arch_interface.h | 162 +++++++++
tools/asinfo/arch_personalities.h | 36 ++
tools/asinfo/asinfo.c | 331 ++++++++++++++++++
tools/asinfo/dispatchers.c | 244 ++++++++++++++
tools/asinfo/dispatchers.h | 48 +++
tools/asinfo/error_interface.c | 110 ++++++
tools/asinfo/error_interface.h | 95 ++++++
tools/asinfo/request_msgs.h | 93 ++++++
tools/asinfo/syscall_interface.c | 684 ++++++++++++++++++++++++++++++++++++++
tools/asinfo/syscall_interface.h | 142 ++++++++
18 files changed, 3036 insertions(+), 1 deletion(-)
create mode 100644 tools/Makefile.am
create mode 100644 tools/asinfo/.gitignore
create mode 100644 tools/asinfo/Makefile.am
create mode 100644 tools/asinfo/arch_definitions.h
create mode 100644 tools/asinfo/arch_includes.h
create mode 100644 tools/asinfo/arch_interface.c
create mode 100644 tools/asinfo/arch_interface.h
create mode 100644 tools/asinfo/arch_personalities.h
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/error_interface.c
create mode 100644 tools/asinfo/error_interface.h
create mode 100644 tools/asinfo/request_msgs.h
create mode 100644 tools/asinfo/syscall_interface.c
create mode 100644 tools/asinfo/syscall_interface.h
diff --git a/Makefile.am b/Makefile.am
index e90c7809..1c9c3dac 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 strace-log-merge.1
diff --git a/configure.ac b/configure.ac
index 729ef3f7..0492bd8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -904,6 +904,8 @@ AC_CONFIG_FILES([Makefile
tests-mx32/Makefile
strace.1
strace-log-merge.1
+ 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 <edg...@vi...>
+# 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/.gitignore b/tools/asinfo/.gitignore
new file mode 100644
index 00000000..09400c47
--- /dev/null
+++ b/tools/asinfo/.gitignore
@@ -0,0 +1,2 @@
+asinfo
+asinfo.1
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
new file mode 100644
index 00000000..5051766e
--- /dev/null
+++ b/tools/asinfo/Makefile.am
@@ -0,0 +1,62 @@
+# Automake input for asinfo.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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_LDFLAGS =
+asinfo_LDADD = -L$(top_srcdir) \
+ -L$(top_builddir) \
+ -lcommon
+
+asinfo_SOURCES = \
+ arch_definitions.h \
+ arch_includes.h \
+ arch_interface.c \
+ arch_interface.h \
+ arch_personalities.h \
+ asinfo.c \
+ dispatchers.c \
+ dispatchers.h \
+ error_interface.c \
+ error_interface.h \
+ request_msgs.h \
+ syscall_interface.c \
+ syscall_interface.h \
+ #end of asinfo_SOURCES
diff --git a/tools/asinfo/arch_definitions.h b/tools/asinfo/arch_definitions.h
new file mode 100644
index 00000000..37103160
--- /dev/null
+++ b/tools/asinfo/arch_definitions.h
@@ -0,0 +1,70 @@
+/* [],[bfin/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(blackfin, 32bit, PASS({}), PASS({"blackfin", "bfin"}) ),
+/* [],[ia64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ia64, 64bit, PASS({}), PASS({"ia64"}) ),
+/* [],[m68k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(m68k, 32bit, PASS({}), PASS({"m68k"}) ),
+/* [],[sparc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc64, 64bit, PASS({ARCH_sparc_32bit}), PASS({"sparc64"}) ),
+/* [],[sparc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc, 32bit, PASS({}), PASS({"sparc"}) ),
+/* [],[metag/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(metag, 32bit, PASS({}), PASS({"metag"}) ),
+/* [LINUX_MIPSN64],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n64.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n64, PASS({ARCH_mips64_n32, ARCH_mips_o32}), PASS({"mips64", "mips64le"}) ),
+/* [LINUX_MIPSN32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n32.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n32, PASS({ARCH_mips_o32}), PASS({}) ),
+/* [LINUX_MIPSO32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-o32.h],[0,0] */
+ARCH_DESC_DEFINE(mips, o32, PASS({}), PASS({"mips", "mipsle"}) ),
+/* [],[alpha/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(alpha, 64bit, PASS({}), PASS({"alpha"}) ),
+/* [],[powerpc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc64, 64bit, PASS({ARCH_ppc_32bit}), PASS({"ppc64", "ppc64le", "powerpc64"}) ),
+/* [],[powerpc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc, 32bit, PASS({}), PASS({"ppc", "ppcle", "powerpc"}) ),
+/* [],[aarch64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(aarch64, 64bit, PASS({ARCH_arm_eabi}), PASS({"aarch64", "arm64"}) ),
+/* [!__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, oabi, PASS({ARCH_arm_eabi}), PASS({"arm"}) ),
+/* [__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, eabi, PASS({}), PASS({}) ),
+/* [],[avr32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(avr32, 32bit, PASS({}), PASS({"avr32"}) ),
+/* [],[arc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(arc, 32bit, PASS({}), PASS({"arc"}) ),
+/* [],[s390x/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390x, 64bit, PASS({}), PASS({"s390x"}) ),
+/* [],[s390/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390, 32bit, PASS({}), PASS({"s390"}) ),
+/* [],[hppa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(hppa, 32bit, PASS({}), PASS({"parisc", "hppa"}) ),
+/* [],[sh64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh64, 64bit, PASS({}), PASS({"sh64"}) ),
+/* [],[sh/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh, 32bit, PASS({}), PASS({"sh"}) ),
+/* [],[x86_64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, 64bit, PASS({ARCH_x86_64_x32, ARCH_x86_32bit}), PASS({"x86_64", "amd64", "EM64T"}) ),
+/* [],[x86_64/syscallent2.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, x32, PASS({ARCH_x86_32bit}), PASS({}) ),
+/* [],[i386/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86, 32bit, PASS({}), PASS({"x86", "i386", "i486", "i586", "i686"}) ),
+/* [],[crisv10/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(cris, 32bit, PASS({}), PASS({"cris", "crisv10"}) ),
+/* [],[crisv32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(crisv32, 32bit, PASS({}), PASS({"crisv32"}) ),
+/* [],[tile/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 64bit, PASS({ARCH_tile_32bit}), PASS({"tile", "tilegx"}) ),
+/* [],[tile/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 32bit, PASS({}), PASS({"tilepro"}) ),
+/* [],[microblaze/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(microblaze, 32bit, PASS({}), PASS({"microblaze"}) ),
+/* [],[nios2/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(nios2, 32bit, PASS({}), PASS({"nios2"}) ),
+/* [],[or1k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(openrisc, 32bit, PASS({}), PASS({"openrisc", "or1k"}) ),
+/* [],[xtensa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(xtensa, 32bit, PASS({}), PASS({"xtensa"}) ),
+/* [],[riscv/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 64bit, PASS({ARCH_riscv_32bit}), PASS({"riscv"}) ),
+/* [],[riscv/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 32bit, PASS({}), PASS({}) )
diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h
new file mode 100644
index 00000000..e73a8328
--- /dev/null
+++ b/tools/asinfo/arch_includes.h
@@ -0,0 +1,272 @@
+/* ARCH_blackfin */
+static const struct_sysent blackfin_32bit_sysent[] = {
+ #include "bfin/syscallent.h"
+};
+static const int blackfin_32bit_usr1 = 0;
+const int blackfin_32bit_usr2 = 0;
+/* ARCH_ia64 */
+struct_sysent ia64_64bit_sysent[] = {
+ #include "ia64/syscallent.h"
+};
+static const int ia64_64bit_usr1 = 0;
+static const int ia64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_m68k */
+static const struct_sysent m68k_32bit_sysent[] = {
+ #include "m68k/syscallent.h"
+};
+static const int m68k_32bit_usr1 = 0;
+static const int m68k_32bit_usr2 = 0;
+/* ARCH_sparc64 64bit ABI */
+static const struct_sysent sparc64_64bit_sysent[] = {
+ #include "sparc64/syscallent.h"
+};
+static const int sparc64_64bit_usr1 = 0;
+static const int sparc64_64bit_usr2 = 0;
+/* ARCH_sparc and 32bit ABI */
+static const struct_sysent sparc_32bit_sysent[] = {
+ #include "sparc/syscallent.h"
+};
+static const int sparc_32bit_usr1 = 0;
+static const int sparc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_metag */
+static const struct_sysent metag_32bit_sysent[] = {
+ #include "metag/syscallent.h"
+};
+static const int metag_32bit_usr1 = 0;
+static const int metag_32bit_usr2 = 0;
+/* ARCH_mips n64 ABI */
+#ifndef LINUX_MIPSN64
+# define LINUX_MIPSN64 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n64_usr1 = 0;
+static const int mips64_n64_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips n32 ABI */
+#ifndef LINUX_MIPSN32
+# define LINUX_MIPSN32 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n32_usr1 = 0;
+static const int mips64_n32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips o32 ABI */
+#ifndef LINUX_MIPSO32
+# define LINUX_MIPSO32 1
+# define NOW_DEFINED 1
+#endif
+static const 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
+static const int mips_o32_usr1 = 0;
+static const int mips_o32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_alpha */
+static const struct_sysent alpha_64bit_sysent[] = {
+ #include "alpha/syscallent.h"
+};
+static const int alpha_64bit_usr1 = 0;
+static const int alpha_64bit_usr2 = 0;
+/* ARCH_ppc64 64bit ABI */
+static const struct_sysent ppc64_64bit_sysent[] = {
+ #include "powerpc64/syscallent.h"
+};
+static const int ppc64_64bit_usr1 = 0;
+static const int ppc64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_ppc and 32bit */
+static const struct_sysent ppc_32bit_sysent[] = {
+ #include "powerpc/syscallent.h"
+};
+static const int ppc_32bit_usr1 = 0;
+static const int ppc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_aarch64 64bit ABI */
+static const struct_sysent aarch64_64bit_sysent[] = {
+ #include "aarch64/syscallent.h"
+};
+static const int aarch64_64bit_usr1 = 0;
+static const int aarch64_64bit_usr2 = 0;
+/* ARCH_arm OABI*/
+#ifdef __ARM_EABI__
+# undef __ARM_EABI__
+# define NOW_UNDEFINED 1
+#endif
+static const struct_sysent arm_oabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL;
+#undef ARM_FIRST_SHUFFLED_SYSCALL
+#undef ARM_LAST_SPECIAL_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
+static const struct_sysent arm_eabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_eabi_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 */
+static const struct_sysent avr32_32bit_sysent[] = {
+ #include "avr32/syscallent.h"
+};
+static const int avr32_32bit_usr1 = 0;
+static const int avr32_32bit_usr2 = 0;
+/* ARCH_arc */
+static const struct_sysent arc_32bit_sysent[] = {
+ #include "arc/syscallent.h"
+};
+static const int arc_32bit_usr1 = 0;
+static const int arc_32bit_usr2 = 0;
+/* ARCH_s390x */
+static const struct_sysent s390x_64bit_sysent[] = {
+ #include "s390x/syscallent.h"
+};
+static const int s390x_64bit_usr1 = 0;
+static const int s390x_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_s390 */
+static const struct_sysent s390_32bit_sysent[] = {
+ #include "s390/syscallent.h"
+};
+static const int s390_32bit_usr1 = 0;
+static const int s390_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_hppa */
+static const struct_sysent hppa_32bit_sysent[] = {
+ #include "hppa/syscallent.h"
+};
+static const int hppa_32bit_usr1 = 0;
+static const int hppa_32bit_usr2 = 0;
+/* ARCH_sh64 */
+static const struct_sysent sh64_64bit_sysent[] = {
+ #include "sh64/syscallent.h"
+};
+static const int sh64_64bit_usr1 = 0;
+static const int sh64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_sh */
+static const struct_sysent sh_32bit_sysent[] = {
+ #include "sh/syscallent.h"
+};
+static const int sh_32bit_usr1 = 0;
+static const int sh_32bit_usr2 = 0;
+/* ARCH_x86_64 64bit ABI mode */
+static const struct_sysent x86_64_64bit_sysent[] = {
+ #include "x86_64/syscallent.h"
+};
+static const int x86_64_64bit_usr1 = 0;
+static const int x86_64_64bit_usr2 = 0;
+/* ARCH_x86_64 x32 ABI mode */
+static const struct_sysent x86_64_x32_sysent[] = {
+ #include "x86_64/syscallent2.h"
+};
+static const int x86_64_x32_usr1 = 0;
+static const int x86_64_x32_usr2 = 0;
+/* ARCH_x86 */
+static const struct_sysent x86_32bit_sysent[] = {
+ #include "i386/syscallent.h"
+};
+static const int x86_32bit_usr1 = 0;
+static const int x86_32bit_usr2 = 0;
+/* ARCH_cris */
+static struct_sysent cris_32bit_sysent[] = {
+ #include "crisv10/syscallent.h"
+};
+static const int cris_32bit_usr1 = 0;
+static const int cris_32bit_usr2 = 0;
+/* ARCH_crisv32 */
+static const struct_sysent crisv32_32bit_sysent[] = {
+ #include "crisv32/syscallent.h"
+};
+static const int crisv32_32bit_usr1 = 0;
+static const int crisv32_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_tile 64bit ABI mode */
+static const struct_sysent tile_64bit_sysent[] = {
+ #include "tile/syscallent.h"
+};
+static const int tile_64bit_usr1 = 0;
+static const int tile_64bit_usr2 = 0;
+/* ARCH_tile 32bit ABI mode */
+static const struct_sysent tile_32bit_sysent[] = {
+ #include "tile/syscallent1.h"
+};
+static const int tile_32bit_usr1 = 0;
+static const int tile_32bit_usr2 = 0;
+/* ARCH_microblaze */
+static const struct_sysent microblaze_32bit_sysent[] = {
+ #include "microblaze/syscallent.h"
+};
+static const int microblaze_32bit_usr1 = 0;
+static const int microblaze_32bit_usr2 = 0;
+/* ARCH_nios2 */
+static const struct_sysent nios2_32bit_sysent[] = {
+ #include "nios2/syscallent.h"
+};
+static const int nios2_32bit_usr1 = 0;
+static const int nios2_32bit_usr2 = 0;
+/* ARCH_openrisc */
+struct_sysent openrisc_32bit_sysent[] = {
+ #include "or1k/syscallent.h"
+};
+static const int openrisc_32bit_usr1 = 0;
+static const int openrisc_32bit_usr2 = 0;
+/* ARCH_xtensa */
+static const struct_sysent xtensa_32bit_sysent[] = {
+ #include "xtensa/syscallent.h"
+};
+static const int xtensa_32bit_usr1 = 0;
+static const int xtensa_32bit_usr2 = 0;
+/* ARCH_riscv 64bit ABI mode */
+static const struct_sysent riscv_64bit_sysent[] = {
+ #include "riscv/syscallent.h"
+};
+static const int riscv_64bit_usr1 = 0;
+static const int riscv_64bit_usr2 = 0;
+/* ARCH_riscv 32bit ABI mode */
+static const struct_sysent riscv_32bit_sysent[] = {
+ #include "riscv/syscallent1.h"
+};
+static const int riscv_32bit_usr1 = 0;
+static const int riscv_32bit_usr2 = 0;
diff --git a/tools/asinfo/arch_interface.c b/tools/asinfo/arch_interface.c
new file mode 100644
index 00000000..8e02ffd0
--- /dev/null
+++ b/tools/asinfo/arch_interface.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 <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. */
+#include "sysent_shorthand_defs.h"
+
+/* For the current functionality there is no need
+ to use sen and (*sys_func)() fields in sysent struct */
+#define SEN(syscall_name) 0, NULL
+
+/* Generated file based on arch_definitions.h */
+#include "arch_includes.h"
+
+/* Now undef them since short defines cause wicked namespace pollution. */
+#include "sysent_shorthand_undefs.h"
+
+#define PASS(...) __VA_ARGS__
+#define ARCH_DESC_DEFINE(arch, mode, comp_pers, arch_aliases) \
+ [ARCH_##arch##_##mode] = { \
+ .pers = ARCH_##arch##_##mode, \
+ .arch_name = arch_aliases, \
+ .abi_mode = #mode, \
+ .abi_mode_len = ARRAY_SIZE(#arch) - 1, \
+ .compat_pers = comp_pers, \
+ .max_scn = ARRAY_SIZE(arch##_##mode##_sysent), \
+ .syscall_list = arch##_##mode##_sysent, \
+ .user_num1 = &arch##_##mode##_usr1, \
+ .user_num2 = &arch##_##mode##_usr2, \
+ }
+
+/* Generate array of arch_descriptors for each personality */
+const struct arch_descriptor architectures[] = {
+ #include "arch_definitions.h"
+};
+
+#undef ARCH_DESC_DEFINE
+#undef PASS
+
+struct arch_service *
+al_create(unsigned capacity)
+{
+ ARCH_LIST_DEFINE(as) = NULL;
+
+ if (!capacity)
+ return NULL;
+ as = xcalloc(sizeof(*as), 1);
+ as->arch_list = xcalloc(sizeof(*(as->arch_list)), capacity);
+ as->flag = xcalloc(sizeof(*(as->flag)), capacity);
+ as->in_aname = xcalloc(sizeof(*(as->in_aname)), capacity);
+ as->err = es_create();
+ as->capacity = capacity;
+ as->next_free = 0;
+ return as;
+}
+
+int
+al_push(struct arch_service *m, const struct arch_descriptor *element)
+{
+ if (m->next_free >= m->capacity)
+ return -1;
+ m->arch_list[m->next_free] = element;
+ m->flag[m->next_free] = AD_FLAG_EMPTY;
+ 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->flag[index] = flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_add_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] | flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_sub_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] & ~flag;
+ return 0;
+ }
+ return -1;
+}
+
+const 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;
+}
+
+void
+al_free(struct arch_service *m)
+{
+ int i;
+ int size = al_size(m);
+
+ for (i = 0; i < size; i++)
+ if (al_in_aname(m, i) != NULL)
+ free(al_in_aname(m, i));
+ free(m->arch_list);
+ free(m->flag);
+ free(m->in_aname);
+ es_free(m->err);
+ free(m);
+}
+
+struct error_service *al_err(struct arch_service *m)
+{
+ return m->err;
+}
+
+enum arch_pers
+al_pers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->pers : ARCH_no_pers);
+}
+
+const char **
+al_arch_name(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (const char **)elem->arch_name : NULL);
+}
+
+enum arch_pers *
+al_cpers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (enum arch_pers *)elem->compat_pers : NULL);
+}
+
+const char *
+al_abi_mode(struct arch_service *m, unsigned index)
+{
+ const 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)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->abi_mode_len : -1);
+}
+
+int
+al_flag(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->flag[index] : -1);
+}
+
+int
+al_set_in_aname(struct arch_service *m, unsigned index, char *aname)
+{
+ int status = al_is_index_ok(m, index);
+
+ if (status)
+ return -1;
+ m->in_aname[index] = aname;
+ return 0;
+}
+
+char *
+al_in_aname(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->in_aname[index] : NULL);
+}
+
+int
+al_psize(struct arch_service *m)
+{
+ int i;
+ int a_size = al_size(m);
+ int psize = 0;
+
+ for (i = 0; i < a_size; i++)
+ if (al_flag(m, i) & AD_FLAG_PRINT)
+ psize++;
+ return psize;
+}
+
+int
+al_arch_name_len(struct arch_service *m, unsigned index, int delim_len)
+{
+ const char **arch_name = NULL;
+ int i;
+ int final_len = 0;
+
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ for (i = 0; (arch_name[i] != NULL) && (i < MAX_ALIASES); i++) {
+ final_len += strlen(arch_name[i]);
+ final_len += delim_len;
+ }
+ final_len -= delim_len;
+ return final_len;
+}
+
+int
+al_syscall_impl(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name &&
+ !(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ count++;
+ }
+ return count;
+}
+
+/* This method is purposed to count the supported ABI modes for the given
+ arch */
+int
+al_get_abi_modes(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+ int i = 0;
+ int abi_count = 1;
+
+ if (!elem)
+ return -1;
+ for (i = 0; i < MAX_ALT_ABIS; i++)
+ if (elem->compat_pers[i] != ARCH_no_pers)
+ abi_count++;
+ return abi_count;
+}
+
+/* This method is purposed to find next one name of the same architecture.
+ For instance, x86_64 = amd64 */
+const char *
+al_next_alias(struct arch_service *m, unsigned index)
+{
+ static int next_alias = -1;
+ static const char **arch_name = NULL;
+ static unsigned lindex = 0;
+
+ if (lindex != index) {
+ lindex = index;
+ next_alias = -1;
+ }
+ if (al_pers(m, index) == ARCH_no_pers)
+ return NULL;
+ if (next_alias == -1) {
+ next_alias = 0;
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ } else
+ next_alias++;
+ if (next_alias >= MAX_ALIASES || arch_name[next_alias] == NULL) {
+ next_alias = -1;
+ return NULL;
+ }
+ return arch_name[next_alias];
+}
+
+/* This method is purposed to return next one compat personality of the
+ same architecture */
+enum arch_pers
+al_next_cpers(struct arch_service *m, unsigned index)
+{
+ static int next_pers = -1;
+ enum arch_pers *a_pers = al_cpers(m, index);
+ static unsigned lindex = 0;
+
+ if (al_pers(m, index) == ARCH_no_pers)
+ return ARCH_no_pers;
+ if (lindex != index) {
+ lindex = index;
+ next_pers = -1;
+ }
+ if (next_pers == -1)
+ next_pers = 0;
+ else
+ next_pers++;
+ if (next_pers >= MAX_ALT_ABIS ||
+ a_pers[next_pers] == ARCH_no_pers) {
+ next_pers = -1;
+ return ARCH_no_pers;
+ }
+ return a_pers[next_pers];
+}
+
+enum impl_type
+al_ipc_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just semop sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "semop")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+enum impl_type
+al_sck_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just socket sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "socket")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+/* This method is purposed to create extended list of architectures */
+struct arch_service *
+al_create_filled(void)
+{
+ static const int architectures_size = ARRAY_SIZE(architectures) - 1;
+ ARCH_LIST_DEFINE(as) = al_create(architectures_size);
+ ARCH_LIST_DEFINE(f_as);
+ enum arch_pers cpers;
+ int esize = 0;
+ const char **arch_name = NULL;
+ int i;
+
+ /* Push and calculate size of extended table */
+ for (i = 0; i < architectures_size; i++) {
+ al_push(as, &(architectures[i + 1]));
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] != NULL)
+ esize += al_get_abi_modes(as, i);
+ }
+ f_as = al_create(esize);
+ /* Fill extended teble */
+ for (i = 0; i < architectures_size; i++) {
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] == NULL)
+ continue;
+ al_push(f_as, al_get(as, i));
+ al_add_flag(f_as, al_size(f_as) - 1, AD_FLAG_MPERS);
+ while ((cpers = al_next_cpers(as, i)) != ARCH_no_pers)
+ al_push(f_as, &(architectures[cpers]));
+ }
+ free(as);
+ return f_as;
+}
+
+/* To look up arch in arch_descriptor array */
+int
+al_mark_matches(struct arch_service *m, char *arch_str)
+{
+ int arch_match = -1;
+ char *match_pointer = NULL;
+ const char *a_name = NULL;
+ int al_size_full = al_size(m);
+ unsigned prev_arch_len = 0;
+ int i;
+ int a_abi;
+ char *in_aname;
+
+ if (arch_str == NULL)
+ return -1;
+ /* Here we find the best match for arch_str in architecture list.
+ Best match means here that we have to find the longest name of
+ architecture in a_full_list with arch_str substring, beginning
+ from the first letter */
+ for (i = 0; i < al_size_full; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_MPERS))
+ continue;
+ while ((a_name = al_next_alias(m, i)) != NULL) {
+ match_pointer = strstr(arch_str, a_name);
+ if (match_pointer == NULL || match_pointer != arch_str)
+ continue;
+ if (arch_match == -1 ||
+ strlen(a_name) > prev_arch_len) {
+ prev_arch_len = strlen(a_name);
+ arch_match = i;
+ }
+ }
+ }
+ if (arch_match == -1)
+ return -1;
+ /* Now we find all ABI modes related to the architecture */
+ if ((a_abi = al_get_abi_modes(m, arch_match)) == -1)
+ return -1;
+ for (i = arch_match; i < (arch_match + a_abi); i++) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ in_aname = xcalloc(sizeof(*in_aname), strlen(arch_str) + 1);
+ strcpy(in_aname, arch_str);
+ al_set_in_aname(m, i, in_aname);
+ }
+ return 0;
+}
+
+/* Join all architectures from 'f' and architectures with AD_FLAG_PRINT
+ from 's' arch_service structures */
+struct arch_service *
+al_join_print(struct arch_service *f, struct arch_service *s)
+{
+ int size1 = (f ? al_size(f) : 0);
+ int psize2 = al_psize(s);
+ int size2 = al_size(s);
+ int i;
+ int start_point = 0;
+ ARCH_LIST_DEFINE(final) = al_create(size1 + psize2);
+
+ for (i = 0; i < size2; i++)
+ if (al_flag(s, i) & AD_FLAG_PRINT) {
+ start_point = i;
+ break;
+ }
+ for (i = 0; i < size1; i++) {
+ al_push(final, al_get(f, i));
+ al_set_flag(final, i, al_flag(f, i));
+ al_set_in_aname(final, i, al_in_aname(f, i));
+ al_set_in_aname(f, i, NULL);
+ }
+ for (i = 0; i < psize2; i++) {
+ al_push(final, al_get(s, start_point + i));
+ al_set_flag(final, size1 + i , al_flag(s, start_point + i));
+ al_set_in_aname(final, size1 + i,
+ al_in_aname(s, start_point + i));
+ al_set_in_aname(s, start_point + i, NULL);
+ al_sub_flag(s, start_point + i, AD_FLAG_PRINT);
+ }
+ if (f)
+ al_free(f);
+ return final;
+}
+
+/* To avoid duplication of for(;;) construction */
+void
+al_unmark_all(struct arch_service *m, int flag)
+{
+ int a_size = al_size(m);
+ int i;
+
+ for (i = 0; i < a_size; i++)
+ al_sub_flag(m, i, flag);
+}
+
+/* Select one compatible personality in range of one architecture */
+int
+al_mark_pers4arch(struct arch_service *m, unsigned index, const char *abi_mode)
+{
+ unsigned i = index;
+
+ while (!(al_flag(m, i) & AD_FLAG_MPERS) || (i == index)) {
+ if (strcmp(abi_mode, "all") == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ i++;
+ if ((al_is_index_ok(m, i)) ||
+ (al_flag(m, i) & AD_FLAG_MPERS))
+ return 0;
+ else
+ continue;
+ }
+ if (strcmp(al_abi_mode(m, i), abi_mode) == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ return 0;
+ }
+ i++;
+ }
+ return -1;
+}
+
+void
+al_dump(struct arch_service *m, int is_raw)
+{
+ static const char *title[] = {
+ "N",
+ "Architecture name",
+ "ABI mode",
+ /* Implemented syscalls */
+ "IMPL syscalls",
+ /* IPC implementation */
+ "IPC IMPL",
+ /* SOCKET implementation */
+ "SOCKET IMPL"
+ };
+ int title_len[] = {
+ 0,
+ strlen(title[1]),
+ strlen(title[2]),
+ strlen(title[3]),
+ strlen(title[4]),
+ strlen(title[5]),
+ };
+ static const char *impl_st[] = {
+ "external",
+ "internal",
+ "int/ext"
+ };
+ static const char *delim = "/";
+ int i = 0;
+ int N = 0;
+ int temp_len = 0;
+ int arch_size = al_size(m);
+ int arch_psize = al_psize(m);
+ const char *next_alias = NULL;
+ char *whole_arch_name;
+
+ /* Calculate length of the column with the number of architectures */
+ for (i = 1; arch_psize/i != 0; i *= 10)
+ title_len[0]++;
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ /* Calculate length of the column with the
+ architectures name */
+ temp_len = al_arch_name_len(m, i, strlen(delim));
+ if (temp_len > title_len[1])
+ title_len[1] = temp_len;
+ /* Calculate length of the column with the ABI mode */
+ if (al_abi_mode_len(m, i) > title_len[2])
+ title_len[2] = al_abi_mode_len(m, i);
+ }
+
+ whole_arch_name = xcalloc(title_len[1], sizeof(*whole_arch_name));
+ /* Output title */
+ if (!is_raw)
+ printf("| %*s | %*s | %*s | %*s | %*s | %*s |\n",
+ title_len[0], title[0], title_len[1], title[1],
+ title_len[2], title[2], title_len[3], title[3],
+ title_len[4], title[4], title_len[5], title[5]);
+ /* Output architectures */
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ N++;
+ memset(whole_arch_name, 0, title_len[1]);
+ /* Put all the same arch back together */
+ next_alias = al_next_alias(m, i);
+ strcat(whole_arch_name, next_alias);
+ while ((next_alias = al_next_alias(m, i)) != NULL) {
+ strcat(whole_arch_name, delim);
+ strcat(whole_arch_name, next_alias);
+ }
+ if (is_raw) {
+ printf("%u;%s;%s;%d;%s;%s;\n", N, whole_arch_name,
+ al_abi_mode(m, i), al_syscall_impl(m, i),
+ impl_st[al_ipc_syscall(m, i)],
+ impl_st[al_ipc_syscall(m, i)]);
+ continue;
+ }
+ printf("| %*u | ", title_len[0], N);
+ printf("%*s | ", title_len[1], whole_arch_name);
+ printf("%*s | ", title_len[2], al_abi_mode(m, i));
+ printf("%*d | ", title_len[3], al_syscall_impl(m, i));
+ printf("%*s | ", title_len[4], impl_st[al_ipc_syscall(m, i)]);
+ printf("%*s |\n", title_len[5], impl_st[al_sck_syscall(m, i)]);
+ }
+ free(whole_arch_name);
+}
diff --git a/tools/asinfo/arch_interface.h b/tools/asinfo/arch_interface.h
new file mode 100644
index 00000000..1e7123fc
--- /dev/null
+++ b/tools/asinfo/arch_interface.h
@@ -0,0 +1,162 @@
+/*
+ * 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 <edg...@vi...>
+ * 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_H
+#define ASINFO_ARCH_INTERFACE_H
+
+#include "error_interface.h"
+#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 personalities
+ * arch_pers = ARCH_ + kernel_kernel/other_name + abi_mode */
+enum arch_pers {
+ #include "arch_personalities.h"
+};
+
+#define MAX_ALIASES 6
+#define MAX_ALT_ABIS 3
+
+struct arch_descriptor {
+ enum arch_pers pers;
+ const char *arch_name[MAX_ALIASES];
+ const char *abi_mode;
+ const int abi_mode_len;
+ enum arch_pers compat_pers[MAX_ALT_ABIS];
+ const int max_scn;
+ const struct_sysent *syscall_list;
+ /* In the most cases these fields are purposed to store specific for
+ given arch constants, for instance, ARM_FIRST_SHUFFLED_SYSCALL */
+ const int *user_num1;
+ const int *user_num2;
+};
+
+#define AD_FLAG_EMPTY 0
+/* to hide some abi modes belonging to one architecture */
+#define AD_FLAG_PRINT (1 << 0)
+/* main personality, like x86_64 64bit */
+#define AD_FLAG_MPERS (1 << 1)
+
+/* To provide push-back interface with arch_list */
+struct arch_service {
+ /* immutable field */
+ const struct arch_descriptor **arch_list;
+ /* User flags for each arch_descriptor */
+ int *flag;
+ /* To support conformity between ABI and ARCH */
+ char **in_aname;
+ struct error_service *err;
+ 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 capacity);
+
+int al_push(struct arch_service *m, const struct arch_descriptor *element);
+
+int al_set_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_add_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_sub_flag(struct arch_service *m, unsigned index, int flag);
+
+const struct arch_descriptor *al_get(struct arch_service *m, unsigned index);
+
+unsigned int al_size(struct arch_service *m);
+
+void al_free(struct arch_service *m);
+
+struct error_service *al_err(struct arch_service *m);
+
+/* methods returning fields with error check */
+enum arch_pers al_pers(struct arch_service *m, unsigned index);
+
+const char **al_arch_name(struct arch_service *m, unsigned index);
+
+enum arch_pers *al_cpers(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);
+
+int al_set_in_aname(struct arch_service *m, unsigned index, char *aname);
+
+char *al_in_aname(struct arch_service *m, unsigned index);
+
+/* calculating methods */
+int al_psize(struct arch_service *m);
+
+int al_arch_name_len(struct arch_service *m, unsigned index, int delim_len);
+
+int al_syscall_impl(struct arch_service *m, unsigned index);
+
+int al_get_abi_modes(struct arch_service *m, unsigned index);
+
+const char *al_next_alias(struct arch_service *m, unsigned index);
+
+enum arch_pers al_next_cpers(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);
+
+struct arch_service *al_create_filled(void);
+
+int al_mark_matches(struct arch_service *m, char *arch_str);
+
+struct arch_service *al_join_print(struct arch_service *f,
+ struct arch_service *s);
+
+void al_unmark_all(struct arch_service *m, int flag);
+
+int al_mark_pers4arch(struct arch_service *m, unsigned index,
+ const char *abi_mode);
+
+void al_dump(struct arch_service *m, int is_raw);
+
+#endif /* !ASINFO_ARCH_INTERFACE_H */
diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h
new file mode 100644
index 00000000..9499c5aa
--- /dev/null
+++ b/tools/asinfo/arch_personalities.h
@@ -0,0 +1,36 @@
+ARCH_no_pers,
+ARCH_blackfin_32bit,
+ARCH_ia64_64bit,
+ARCH_m68k_32bit,
+ARCH_sparc64_64bit,
+ARCH_sparc_32bit,
+ARCH_metag_32bit,
+ARCH_mips64_n64,
+ARCH_mips64_n32,
+ARCH_mips_o32,
+ARCH_alpha_64bit,
+ARCH_ppc64_64bit,
+ARCH_ppc_32bit,
+ARCH_aarch64_64bit,
+ARCH_arm_oabi,
+ARCH_arm_eabi,
+ARCH_avr32_32bit,
+ARCH_arc_32bit,
+ARCH_s390x_64bit,
+ARCH_s390_32bit,
+ARCH_hppa_32bit,
+ARCH_sh64_64bit,
+ARCH_sh_32bit,
+ARCH_x86_64_64bit,
+ARCH_x86_64_x32,
+ARCH_x86_32bit,
+ARCH_cris_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
diff --git a/tools/asinfo/asinfo.c b/tools/asinfo/asinfo.c
new file mode 100644
index 00000000..9b1ac9e5
--- /dev/null
+++ b/tools/asinfo/asinfo.c
@@ -0,0 +1,331 @@
+/*
+ * 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 <edg...@vi...>
+ * 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 <ctype.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_interface.h"
+#include "error_prints.h"
+#include "macros.h"
+#include "request_msgs.h"
+#include "syscall_interface.h"
+#include "xmalloc.h"
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
+
+static void
+usage(void)
+{
+ puts(
+ "usage: asinfo (--set-arch arch | --get-arch | --list-arch)\n"
+ " [--set-abi abi | --list-abi] [--raw]\n"
+ " or: asinfo [(--set-arch arch | --get-arch) [--set-abi abi | --list-abi]]\n"
+ " ((--get-sname expr | --get-snum expr) [--nargs]) [--raw]\n"
+ "\n"
+ "Architecture:\n"
+ " --set-arch arch use architecture ARCH for further work\n"
+ " argument format: arch1,arch2,...\n"
+ " --get-arch use architecture returned by uname for further work\n"
+ " --list-arch print out all architectures supported by strace\n"
+ " (combined use list-arch and any ABI option is permitted)\n"
+ "\n"
+ "ABI:\n"
+ " --set-abi abi use application binary interface ABI for further work\n"
+ " ('all' can be used as ABI to use all compatible personalities\n"
+ " for corresponding architecture)\n"
+ " argument format: abi1,abi2,...\n"
+ " --list-abi use all ABIs for specified architecture\n"
+ "\n"
+ "System call:\n"
+ " --get-sname expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall name | snum1 | snum2 | ...\n"
+ " --get-snum expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall number | sname1 | sname2 | ...\n"
+ " --nargs change output format as follows:\n"
+ " | N | syscall name or number | nargs1 | sname2 | ...\n"
+ "\n"
+ "Output formatting:\n"
+ " --raw reset alignment and remove titles, use ';' as a delimiter\n"
+ "\n"
+ "Miscellaneous:\n"
+ " -h print help message\n"
+ " -v print version");
+ exit(0);
+}
+
+static void
+print_version(void)
+{
+ printf("asinfo (%s package) -- version %s\n"
+ "Copyright (c) 1991-%s The strace developers <%s>.\n"
+ "This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+ PACKAGE_NAME, PACKAGE_VERSION, COPYRIGHT_YEAR, PACKAGE_URL);
+ exit(0);
+}
+
+void
+die(void)
+{
+ exit(1);
+}
+
+static int
+is_more1bit(unsigned int num)
+{
+ return !(num & (num - 1));
+}
+
+static unsigned
+strpar2req(char *option)
+{
+ /* Convertion table to store string with options */
+ static const char *options[] = {
+ [SD_REQ_GET_SNAME_BIT] = "--get-sname",
+ [SD_REQ_GET_SNUM_BIT] = "--get-snum",
+ [SD_REQ_NARGS_BIT] = "--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_BIT] = "--set-abi",
+ [ABD_REQ_LIST_ABI_BIT] = "--list-abi",
+ [SERV_REQ_RAW_BIT] = "--raw",
+ [SERV_REQ_HELP_BIT] = "-h",
+ [SERV_REQ_VERSION_BIT] = "-v"
+ };
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(options); i++) {
+ if (options[i] && strcmp(option, options[i]) == 0)
+ return i;
+ }
+ return SERV_REQ_ERROR_BIT;
+}
+
+static char **
+arg2list(char *argument)
+{
+ int i;
+ int len = strlen(argument);
+ int occur = 1;
+ char **arg_list;
+
+ for (i = 0; i < len; i++) {
+ if (argument[i] == ',') {
+ if (i == 0 || i == len - 1 || argument[i + 1] == ',')
+ return NULL;
+ occur++;
+ }
+ }
+ arg_list = xcalloc(sizeof(*arg_list), occur + 1);
+ for (i = 0; i < occur; i++) {
+ arg_list[i] = argument;
+ argument = strchr(argument, ',');
+ if (argument) {
+ *argument = '\0';
+ argument++;
+ }
+ }
+ return arg_list;
+}
+
+/* The purpose of this function is to convert input parameters to number with
+ set bits, where each bit means specific work mode. Moreover, it checks input
+ for correctness and outputs error messages in case of wrong input */
+static unsigned
+command_dispatcher(int argc, char *argv[], char **args[])
+{
+ int i;
+ unsigned final_req = 0;
+ unsigned temp_req = 0;
+ int mult_arch = 0;
+ int mult_abi = 0;
+ unsigned non_req_arg = AD_REQ_GET_ARCH | AD_REQ_LIST_ARCH |
+ ABD_REQ_LIST_ABI | SD_REQ_NARGS |
+ SERV_REQ_RAW;
+
+ if (!program_invocation_name || !*program_invocation_name) {
+ static char name[] = "asinfo";
+ program_invocation_name =
+ (argv[0] && *argv[0]) ? argv[0] : name;
+ }
+
+ /* Try to find help or version parameter first */
+ for (i = 1; i < argc; i++) {
+ if (strpar2req(argv[i]) == SERV_REQ_HELP_BIT)
+ usage();
+ if (strpar2req(argv[i]) == SERV_REQ_VERSION_BIT)
+ print_version();
+ }
+ /* For now, is is necessary to convert string parameter to number of
+ request and make basic check */
+ for (i = 1; i < argc; i++) {
+ if ((temp_req = strpar2req(argv[i])) == SERV_REQ_ERROR_BIT)
+ error_msg_and_help("unrecognized option '%s'",
+ argv[i]);
+ if (final_req & 1 << temp_req)
+ error_msg_and_help("parameter '%s' has been used "
+ "more than once", argv[i]);
+ if (!((1 << temp_req) & non_req_arg) &&
+ (i + 1 >= argc || strlen(argv[i + 1]) == 0 ||
+ strpar2req(argv[i + 1]) != SERV_REQ_ERROR_BIT))
+ error_msg_and_help("parameter '%s' requires "
+ "argument", argv[i]);
+ final_req |= 1 << temp_req;
+ if (!((1 << temp_req) & non_req_arg)) {
+ if ((1 << temp_req) & SD_REQ_MASK) {
+ args[temp_req] = &argv[i + 1];
+ i++;
+ continue;
+ }
+ if ((args[temp_req] = arg2list(argv[i + 1])) != NULL) {
+ i++;
+ continue;
+ }
+ error_msg_and_help("argument '%s' of '%s' parameter "
+ "has a wrong format",
+ argv[i + 1], argv[i]);
+ }
+ }
+ /* Count our multuarchness */
+ if (args[AD_REQ_SET_ARCH_BIT])
+ while (args[AD_REQ_SET_ARCH_BIT][mult_arch] != NULL)
+ mult_arch++;
+ if (args[ABD_REQ_SET_ABI_BIT])
+ while (args[ABD_REQ_SET_ABI_BIT][mult_abi] != NULL)
+ mult_abi++;
+ /* final_req should be logically checked */
+ /* More than one option from one request group couldn't be set */
+ if ((is_more1bit(final_req & SD_REQ_MASK & ~SD_REQ_NARGS) == 0) ||
+ (is_more1bit(final_req & AD_REQ_MASK) == 0) ||
+ (is_more1bit(final_req & ABD_REQ_MASK) == 0))
+ error_msg_and_help("exclusive parameters");
+ /* Check on mutually exclusive options chain */
+ /* If at least one syscall option has been typed, therefore
+ arch_options couldn't be list-arch and
+ abi_option couldn't be list-abi */
+ if ((final_req & SD_REQ_MASK) &&
+ (((final_req & AD_REQ_MASK) && (final_req & AD_REQ_LIST_ARCH))))
+ error_msg_and_help("wrong parameters");
+ /* list-arch couldn't be used with any abi options */
+ if ((final_req & AD_REQ_LIST_ARCH) &&
+ (final_req & ABD_REQ_MASK))
+ error_msg_and_help("'--list-arch' cannot be used with any "
+ "ABI parameters");
+ /* ABI requests could be used just in a combination with arch
+ requests */
+ if ((final_req & ABD_REQ_MASK) &&
+ !(final_req & AD_REQ_MASK))
+ error_msg_and_help("ABI parameters could be used only with "
+ "architecture parameter");
+ /* set-abi must be used in case of multiple arch */
+ if ((mult_arch > 1) && !(final_req & ABD_REQ_MASK))
+ error_msg_and_help("ABI modes cannot be automatically "
+ "detected for multiple "
+ "architectures");
+ /* set-abi and set-arch have to take the same number of args */
+ if ((final_req & AD_REQ_SET_ARCH) && (final_req & ABD_REQ_SET_ABI) &&
+ (mult_arch != mult_abi))
+ error_msg_and_help("each architecture needs respective "
+ "ABI mode, and vice versa");
+ /* --nargs cannot be used alone */
+ if ((final_req & SD_REQ_NARGS) &&
+ !(final_req & SD_REQ_MASK & ~SD_REQ_NARGS))
+ error_msg_and_help("first set main output syscall "
+ "characteristics");
+ /* raw should not be single */
+ if (final_req == SERV_REQ_RAW)
+ error_msg_and_help("raw data implies existing data");
+ return final_req;
+}
+
+static char *
+seek_sc_arg(char **input_args[])
+{
+ int i;
+
+ for (i = SD_REQ_GET_SNAME_BIT; i < SYSCALL_REQ_BIT_LAST; i++)
+ if (input_args[i] != NULL)
+ return input_args[i][0];
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ ARCH_LIST_DEFINE(arch_list);
+ SYSCALL_LIST_DEFINE(sc_list);
+ /* This array is purposed to store arguments for options in the
+ most convenient way */
+ char ***in_args = xcalloc(sizeof(*in_args), REQ_LAST_BIT);
+ unsigned reqs;
+
+ /* command_dispatcher turn */
+ reqs = command_dispatcher(argc, argv, in_args);
+ if (reqs == 0)
+ error_msg_and_help("must have OPTIONS");
+
+ /* arch_dispatcher turn */
+ arch_list = arch_dispatcher(reqs, in_args[AD_REQ_SET_ARCH_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* abi_dispatcher turn */
+ abi_dispatcher(arch_list, reqs, in_args[ABD_REQ_SET_ABI_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* syscall_dispatcher turn */
+ sc_list = syscall_dispatcher(arch_list, reqs, seek_sc_arg(in_args));
+ if (es_error(ss_err(sc_list)))
+ perror_msg_and_die("%s", es_get_serror(ss_err(sc_list)));
+ /* If we want to get info about only architectures thus we print out
+ architectures, otherwise system calls */
+ if (!(reqs & SD_REQ_MASK))
+ al_dump(arch_list, reqs & SERV_REQ_RAW);
+ else
+ ss_dump(sc_list, reqs & SERV_REQ_RAW);
+ return 0;
+}
diff --git a/tools/asinfo/dispatchers.c b/tools/asinfo/dispatchers.c
new file mode 100644
index 00000000..ec0f20f9
--- /dev/null
+++ b/tools/asinfo/dispatchers.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 "syscall_interface.h"
+#include "sysent.h"
+#include "xmalloc.h"
+
+struct arch_service *
+arch_dispatcher(unsigned request_type, char *arch[])
+{
+ struct utsname info_uname;
+ int i;
+ ARCH_LIST_DEFINE(arch_list) = al_create_filled();
+ ARCH_LIST_DEFINE(arch_final) = NULL;
+
+ /* If user don't type any option in ARCH_REQ group, it means
+ get current arch */
+ if ((request_type & AD_REQ_GET_ARCH) ||
+ (!(request_type & AD_REQ_MASK))) {
+ uname(&info_uname);
+ if (al_mark_matches(arch_list, info_uname.machine) == -1) {
+ es_set_error(al_err(arch_list), AD_UNSUP_ARCH);
+ es_set_option(al_err(arch_list), info_uname.machine,
+ NULL, NULL);
+ goto fail;
+ }
+ /* Cut off useless archs */
+ arch_final = al_join_print(arch_final, arch_list);
+ al_unmark_all(arch_final, AD_FLAG_P...
[truncated message content] |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:02:55
|
As asinfo requires some strace source files to work, it is neccessary to group them into separate static library. * Makefile.am (strace_SOURCES): Delete basic_filters.c, error_prints.c, error_prints.h, filter.h, macros.h, number_set.c, number_set.h, string_to_uint.h, string_to_uint.c, sysent_shorthand_defs.h, sysent_shorthand_undefs, xmalloc.c and xmalloc.h. (libcommon_SOURCES): Add them. (strace_LDADD): Add libcommon.a. (noinst_LIBRARIES): Likewise. * .gitignore: Add libcommon.a. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- .gitignore | 1 + Makefile.am | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 94a0be39..30938836 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ /ioctlent[012].h /ioctls_all[012].h /ioctlsort[012] +/libcommon.a /libmpers-m32.a /libmpers-mx32.a /libstrace.a diff --git a/Makefile.am b/Makefile.am index c04125ec..e90c7809 100644 --- a/Makefile.am +++ b/Makefile.am @@ -83,12 +83,31 @@ libstrace_a_SOURCES = \ upoke.c \ # end of libstrace_a_SOURCES +strace_LDADD += libcommon.a +noinst_LIBRARIES += libcommon.a +libcommon_a_CPPFLAGS = $(strace_CPPFLAGS) +libcommon_a_CFLAGS = $(strace_CFLAGS) +libcommon_a_SOURCES = \ + basic_filters.c \ + error_prints.c \ + error_prints.h \ + filter.h \ + macros.h \ + number_set.c \ + number_set.h \ + string_to_uint.h \ + string_to_uint.c \ + sysent_shorthand_defs.h \ + sysent_shorthand_undefs.h \ + xmalloc.c \ + xmalloc.h \ + #end of libcommon_a_SOURCES + strace_SOURCES = \ access.c \ affinity.c \ aio.c \ alpha.c \ - basic_filters.c \ bind.c \ bjm.c \ block.c \ @@ -116,8 +135,6 @@ strace_SOURCES = \ dyxlat.c \ empty.h \ epoll.c \ - error_prints.c \ - error_prints.h \ evdev.c \ eventfd.c \ execve.c \ @@ -137,7 +154,6 @@ strace_SOURCES = \ file_handle.c \ file_ioctl.c \ filter_qualify.c \ - filter.h \ flock.c \ flock.h \ fs_x_ioctl.c \ @@ -176,7 +192,6 @@ strace_SOURCES = \ lookup_dcookie.c \ loop.c \ lseek.c \ - macros.h \ mem.c \ membarrier.c \ memfd_create.c \ @@ -210,8 +225,6 @@ strace_SOURCES = \ nsfs.h \ nsig.h \ numa.c \ - number_set.c \ - number_set.h \ oldstat.c \ open.c \ or1k_atomic.c \ @@ -291,15 +304,11 @@ strace_SOURCES = \ statx.c \ statx.h \ strace.c \ - string_to_uint.h \ - string_to_uint.c \ supported_personalities.h \ swapon.c \ syscall.c \ sysctl.c \ sysent.h \ - sysent_shorthand_defs.h \ - sysent_shorthand_undefs.h \ sysinfo.c \ syslog.c \ sysmips.c \ @@ -324,8 +333,6 @@ strace_SOURCES = \ xattr.c \ xlat.c \ xlat.h \ - xmalloc.c \ - xmalloc.h \ # end of strace_SOURCES if USE_LIBUNWIND -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 14:02:53
|
Some relative paths don't work in Makefile.am when we move building directory, so v12 fixes it allowing make-dist to be run properly. Changelog: v13 * voluntaristic reason v12 * Add libcommon.a for sharing sources between strace and asinfo. * Make polished patches. * Add .dir to clean. * Make make-dist working with asinfo. * Expand .gitignore lists. v11 * Add tests * Fix issues in dispatcher.c file. v10 * Add asinfo binary to deb/rpm build. * Add '--raw' parameter to print out without formating. * Update MAN page and usage. * Fix issues and typos. v9 * Add MAN page. * Add script to generate source code describing architecture. * Use new number_set API. * Fix issues and typos. * Fix broken make dist with regard to asinfo. v8 * Add multiarch mode for syscall_dispatcher, which allows to show descrepancy in syscall numbers/name/arguments (number). * Add syscall filtering(as in strace). * Fix issues and typos. * Refine push back interface for syscall_service. * Refine push back interface for arch_service. v7 * Introduce multiarch mode for arch_dispatcher and abi_dispatcher. * Introduce new arch_description storage (arch_definitions.h). * Fix issues and typos. v6 * Adapt syscall dispatcher to the new program architecture. * Implement usage. * Refine command_dispatcher. * Fix issues and typos. v5,v4,v3 * Add command_dispatcher * Introduce syscall_dispatcher(raw version). * Introduce push back interface for syscall_service. * Fix issues and typos. v2 * Refine arch_dispatcher. * Introduce abi_dispatcher. * Add all architectures/ABIs supported by strace. * Introduce push back interface for arch_service. * Fix issues and typos. v1 and older minor implementation: * Introduce pipeline architecture. * Implement the first version of arch_dispatcher. * Introduce define-based interface to interact with array of arch_description. |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:57:40
|
Sorry again, something wrong happened. On 12/10/2017 04:56 PM, Edgar Kaziakhmedov wrote: > Some relative paths don't work in Makefile.am when we move building directory, > so v12 fixes it allowing make-dist to be run properly. > > Changelog: > > v12 > * Add libcommon.a for sharing sources between strace and asinfo. > * Make polished patches. > * Add .dir to clean. > * Make make-dist working with asinfo. > * Expand .gitignore lists. > > v11 > * Add tests > * Fix issues in dispatcher.c file. > > v10 > * Add asinfo binary to deb/rpm build. > * Add '--raw' parameter to print out without formating. > * Update MAN page and usage. > * Fix issues and typos. > > v9 > * Add MAN page. > * Add script to generate source code describing architecture. > * Use new number_set API. > * Fix issues and typos. > * Fix broken make dist with regard to asinfo. > > v8 > * Add multiarch mode for syscall_dispatcher, which allows to show > descrepancy in syscall numbers/name/arguments (number). > * Add syscall filtering(as in strace). > * Fix issues and typos. > * Refine push back interface for syscall_service. > * Refine push back interface for arch_service. > > v7 > * Introduce multiarch mode for arch_dispatcher and abi_dispatcher. > * Introduce new arch_description storage (arch_definitions.h). > * Fix issues and typos. > > v6 > * Adapt syscall dispatcher to the new program architecture. > * Implement usage. > * Refine command_dispatcher. > * Fix issues and typos. > > v5,v4,v3 > * Add command_dispatcher > * Introduce syscall_dispatcher(raw version). > * Introduce push back interface for syscall_service. > * Fix issues and typos. > > v2 > * Refine arch_dispatcher. > * Introduce abi_dispatcher. > * Add all architectures/ABIs supported by strace. > * Introduce push back interface for arch_service. > * Fix issues and typos. > > v1 and older minor implementation: > * Introduce pipeline architecture. > * Implement the first version of arch_dispatcher. > * Introduce define-based interface to interact with array of arch_description. > . > |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:56
|
This set of tests cover all possible cases in asinfo tool. However,
as asinfo uses some libraries provided by strace (such as basic_filters)
there is no need to test them again in asinfo context.
Also, the set of syscalls for specific architecture (hence, its number) might
be expanded in the future, so to overcome this obstacle and avoid duplication
of the same strings reference output ptintings are stored in
ref_asinfo_output.h file.
As for syscall-related checks, tests use old syscalls as samples, so their
numbers and names can't be changed.
* configure.ac (AC_CONFIG_FILES): Add tests Makefile to be generated.
* tools/asinfo/Makefile.am (SUBDIRS): Add tests dir.
* tools/asinfo/tests/Makefile.m: New file.
* tools/asinfo/tests/init.sh: New file. Main subroutines for tests.
* tools/asinfo/tests/ref_asinfo_output.h: New file.
* tools/asinfo/tests/com_disp_wrong_keys.c: Likewise.
* tools/asinfo/tests/com_disp_wrong_keys.test: Likewise.
* tools/asinfo/tests/format_output.c: Likewise.
* tools/asinfo/tests/format_output.test: Likewise.
* tools/asinfo/tests/get_arch_abi.c: Likewise.
* tools/asinfo/tests/get_arch_abi.test: Likewise.
* tools/asinfo/tests/get_sname.c: Likewise.
* tools/asinfo/tests/get_sname.test: Likewise.
* tools/asinfo/tests/get_snum.c: Likewise.
* tools/asinfo/tests/get_snum.test: Likewise.
* tools/asinfo/tests/list_arch.c: Likewise.
* tools/asinfo/tests/list_arch.test: Likewise.
* tools/asinfo/tests/multiarch_get_sname.c: Likewise.
* tools/asinfo/tests/multiarch_get_sname.test: Likewise.
* tools/asinfo/tests/multiarch_get_snum.c: Likewise.
* tools/asinfo/tests/multiarch_get_snum.test: Likewise.
* tools/asinfo/tests/set_abi.c: Likewise.
* tools/asinfo/tests/set_abi.test: Likewise.
* tools/asinfo/tests/set_arch.c: Likewise.
* tools/asinfo/tests/set_arch.test: Likewise.
* tools/asinfo/tests/set_mult_abi.c: Likewise.
* tools/asinfo/tests/set_mult_abi.test: Likewise.
* tools/asinfo/tests/set_mult_arch.c: Likewise.
* tools/asinfo/tests/set_mult_arch.test: Likewise.
* tools/asinfo/tests/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
configure.ac | 1 +
tools/asinfo/Makefile.am | 2 +
tools/asinfo/tests/.gitignore | 16 +++
tools/asinfo/tests/Makefile.am | 67 +++++++++++
tools/asinfo/tests/com_disp_wrong_keys.c | 42 +++++++
tools/asinfo/tests/com_disp_wrong_keys.test | 32 +++++
tools/asinfo/tests/format_output.c | 17 +++
tools/asinfo/tests/format_output.test | 8 ++
tools/asinfo/tests/get_arch_abi.c | 180 ++++++++++++++++++++++++++++
tools/asinfo/tests/get_arch_abi.test | 7 ++
tools/asinfo/tests/get_sname.c | 26 ++++
tools/asinfo/tests/get_sname.test | 12 ++
tools/asinfo/tests/get_snum.c | 26 ++++
tools/asinfo/tests/get_snum.test | 12 ++
tools/asinfo/tests/init.sh | 97 +++++++++++++++
tools/asinfo/tests/list_arch.c | 49 ++++++++
tools/asinfo/tests/list_arch.test | 7 ++
tools/asinfo/tests/multiarch_get_sname.c | 27 +++++
tools/asinfo/tests/multiarch_get_sname.test | 12 ++
tools/asinfo/tests/multiarch_get_snum.c | 39 ++++++
tools/asinfo/tests/multiarch_get_snum.test | 12 ++
tools/asinfo/tests/ref_asinfo_output.h | 42 +++++++
tools/asinfo/tests/set_abi.c | 9 ++
tools/asinfo/tests/set_abi.test | 7 ++
tools/asinfo/tests/set_arch.c | 11 ++
tools/asinfo/tests/set_arch.test | 7 ++
tools/asinfo/tests/set_mult_abi.c | 11 ++
tools/asinfo/tests/set_mult_abi.test | 7 ++
tools/asinfo/tests/set_mult_arch.c | 12 ++
tools/asinfo/tests/set_mult_arch.test | 7 ++
30 files changed, 804 insertions(+)
create mode 100644 tools/asinfo/tests/.gitignore
create mode 100644 tools/asinfo/tests/Makefile.am
create mode 100644 tools/asinfo/tests/com_disp_wrong_keys.c
create mode 100755 tools/asinfo/tests/com_disp_wrong_keys.test
create mode 100644 tools/asinfo/tests/format_output.c
create mode 100755 tools/asinfo/tests/format_output.test
create mode 100644 tools/asinfo/tests/get_arch_abi.c
create mode 100755 tools/asinfo/tests/get_arch_abi.test
create mode 100644 tools/asinfo/tests/get_sname.c
create mode 100755 tools/asinfo/tests/get_sname.test
create mode 100644 tools/asinfo/tests/get_snum.c
create mode 100755 tools/asinfo/tests/get_snum.test
create mode 100644 tools/asinfo/tests/init.sh
create mode 100644 tools/asinfo/tests/list_arch.c
create mode 100755 tools/asinfo/tests/list_arch.test
create mode 100644 tools/asinfo/tests/multiarch_get_sname.c
create mode 100755 tools/asinfo/tests/multiarch_get_sname.test
create mode 100644 tools/asinfo/tests/multiarch_get_snum.c
create mode 100755 tools/asinfo/tests/multiarch_get_snum.test
create mode 100644 tools/asinfo/tests/ref_asinfo_output.h
create mode 100644 tools/asinfo/tests/set_abi.c
create mode 100755 tools/asinfo/tests/set_abi.test
create mode 100644 tools/asinfo/tests/set_arch.c
create mode 100755 tools/asinfo/tests/set_arch.test
create mode 100644 tools/asinfo/tests/set_mult_abi.c
create mode 100755 tools/asinfo/tests/set_mult_abi.test
create mode 100644 tools/asinfo/tests/set_mult_arch.c
create mode 100755 tools/asinfo/tests/set_mult_arch.test
diff --git a/configure.ac b/configure.ac
index 79690ba1..3e846be1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -911,6 +911,7 @@ AC_CONFIG_FILES([Makefile
tools/asinfo/asinfo.1
tools/Makefile
tools/asinfo/Makefile
+ tools/asinfo/tests/Makefile
strace.spec
debian/changelog])
AC_OUTPUT
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
index f2b23e74..9f78b733 100644
--- a/tools/asinfo/Makefile.am
+++ b/tools/asinfo/Makefile.am
@@ -25,6 +25,8 @@
# (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 = . tests
+
bin_PROGRAMS = asinfo
man_MANS = asinfo.1
diff --git a/tools/asinfo/tests/.gitignore b/tools/asinfo/tests/.gitignore
new file mode 100644
index 00000000..592d7b61
--- /dev/null
+++ b/tools/asinfo/tests/.gitignore
@@ -0,0 +1,16 @@
+*.dir
+*.log
+*.o
+*.trs
+set_arch
+set_mult_arch
+list_arch
+set_abi
+set_mult_abi
+get_arch_abi
+get_sname
+get_snum
+com_disp_wrong_keys
+multiarch_get_sname
+multiarch_get_snum
+format_output
diff --git a/tools/asinfo/tests/Makefile.am b/tools/asinfo/tests/Makefile.am
new file mode 100644
index 00000000..0eae4674
--- /dev/null
+++ b/tools/asinfo/tests/Makefile.am
@@ -0,0 +1,67 @@
+# Automake input for asinfo tests.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+OS = linux
+AM_COLOR_TESTS = always
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = $(ARCH_MFLAGS) \
+ -I$(builddir)/../ \
+ -I$(builddir) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)
+AM_LDFLAGS = $(ARCH_MFLAGS)
+
+check_PROGRAMS = set_arch set_mult_arch list_arch set_abi set_mult_abi \
+ get_arch_abi get_sname get_snum com_disp_wrong_keys \
+ multiarch_get_sname multiarch_get_snum format_output
+TESTS = set_arch.test set_mult_arch.test list_arch.test set_abi.test \
+ set_mult_abi.test get_arch_abi.test get_sname.test get_snum.test \
+ com_disp_wrong_keys.test multiarch_get_sname.test \
+ multiarch_get_snum.test format_output.test
+
+set_arch_SOURCES = set_arch.c
+set_mult_arch_SOURCES = set_mult_arch.c
+list_arch_SOURCES = list_arch.c
+set_abi_SOURCES = set_abi.c
+set_mult_abi_SOURCES = set_mult_abi.c
+get_arch_abi_SOURCES = get_arch_abi.c
+get_sname_SOURCES = get_sname.c
+get_snum_SOURCES = get_snum.c
+com_disp_wrong_keys_SOURCES = com_disp_wrong_keys.c
+multiarch_get_sname_SOURCES = multiarch_get_sname.c
+multiarch_get_snum_SOURCES = multiarch_get_snum.c
+format_output_SOURCES = format_output.c
+
+EXTRA_DIST = $(TESTS) \
+ ref_asinfo_output.h \
+ init.sh
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ -rm -rf -- $(TESTS:.test=.dir)
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.c b/tools/asinfo/tests/com_disp_wrong_keys.c
new file mode 100644
index 00000000..9dcb3ee2
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+#define TRY_HELP "Try \'../../asinfo -h\' for more information."
+
+int
+main(int argc, char *argv[])
+{
+ puts("../../asinfo: unrecognized option \'--set-ar\'\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--get-arch\' has been used more than "
+ "once\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--set-arch\' requires argument\n"
+ TRY_HELP "\n"
+ "../../asinfo: argument \'aarch64,\' of \'--set-arch\' parameter "
+ "has a wrong format\n"
+ TRY_HELP "\n"
+ "../../asinfo: exclusive parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: wrong parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: \'--list-arch\' cannot be used with any ABI "
+ "parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI parameters could be used only with "
+ "architecture parameter\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI modes cannot be automatically detected for "
+ "multiple architectures\n"
+ TRY_HELP "\n"
+ "../../asinfo: each architecture needs respective ABI mode, "
+ "and vice versa\n"
+ TRY_HELP "\n"
+ "../../asinfo: first set main output syscall characteristics\n"
+ TRY_HELP "\n"
+ "../../asinfo: raw data implies existing data\n"
+ TRY_HELP "\n"
+ "../../asinfo: must have OPTIONS\n"
+ TRY_HELP);
+ return 0;
+}
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.test b/tools/asinfo/tests/com_disp_wrong_keys.test
new file mode 100755
index 00000000..ba725ab5
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.test
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+#Unrecognized option
+run_asinfo --set-ar > $LOG
+#More than once param
+run_asinfo --get-arch --get-arch >> $LOG
+#Requiring argument
+run_asinfo --set-arch >> $LOG
+#Wrong format
+run_asinfo --set-arch aarch64, >> $LOG
+#More than one option in one group
+run_asinfo --get-arch --set-arch arm >> $LOG
+#syscall and list-arch
+run_asinfo --list-arch --get-sname all >> $LOG
+#list-arch and abi params
+run_asinfo --list-arch --list-abi >> $LOG
+#abi params without arch params
+run_asinfo --list-abi >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm --set-abi all,all,all >> $LOG
+#nargs should be used together with other options from syscall group
+run_asinfo --set-arch x86_64 --set-abi x32 --nargs >> $LOG
+#raw check
+run_asinfo --raw >> $LOG
+#empty input
+run_asinfo >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/format_output.c b/tools/asinfo/tests/format_output.c
new file mode 100644
index 00000000..870b8445
--- /dev/null
+++ b/tools/asinfo/tests/format_output.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts(
+"| N | Architecture name | ABI mode | IMPL syscalls | IPC IMPL | SOCKET IMPL |\n"
+"| 1 | avr32 | 32bit | 329 | external | external |"
+ );
+ puts(
+"| | | x86_64 | x86_64 | x86_64 |\n"
+"| N | Snum | 64bit | x32 | 32bit |\n"
+"| 1 | 1 | write | write | - |\n"
+"| 2 | 4 | - | - | write |");
+ return 0;
+}
diff --git a/tools/asinfo/tests/format_output.test b/tools/asinfo/tests/format_output.test
new file mode 100755
index 00000000..6addc6e9
--- /dev/null
+++ b/tools/asinfo/tests/format_output.test
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch avr32 --list-abi > $LOG
+run_asinfo --set-arch x86_64 --list-abi --get-snum write >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_arch_abi.c b/tools/asinfo/tests/get_arch_abi.c
new file mode 100644
index 00000000..e73aa0ca
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.c
@@ -0,0 +1,180 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "ref_asinfo_output.h"
+
+static inline void
+print_cannot_detect(char *arch_name)
+{
+ printf("../../asinfo: ABI mode cannot be automatically detected for "
+ "non-target architecture \'%s\'\n", arch_name);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct utsname buf;
+ uname(&buf);
+#if defined(bfin)
+ puts("1" BFIN_32bit_STR);
+ return 0;
+#endif
+#if defined(IA64)
+ puts("1" IA64_64bit_STR);
+ return 0;
+#endif
+#if defined(M68K)
+ puts("1" M68K_32bit_STR);
+#endif
+#if defined(SPARC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(SPARC)
+ puts("1" SPARC_32bit_STR);
+ return 0;
+#endif
+#if defined(METAG)
+ puts("1" METAG_32bit_STR);
+ return 0;
+#endif
+#if defined(MIPS)
+ if (strstr(buf.machine, "mips64")) {
+ puts(
+#if defined(LINUX_MIPSO32)
+ "1" MIPS64_O32_STR
+#elif defined(LINUX_MIPSN32)
+ "1" MIPS64_N32_STR
+#elif defined(LINUX_MIPSN64)
+ "1" MIPS64_N64_STR
+#endif
+ );
+ return 0;
+ }
+ if (strstr(buf.machine, "mips")) {
+ puts("1" MIPS_O32_STR);
+ return 0;
+ }
+#endif
+#if defined(ALPHA)
+ puts("1" ALPHA_64bit_STR);
+ return 0;
+#endif
+#if defined(POWERPC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(POWERPC)
+ puts("1" PPC_32bit_STR);
+ return 0;
+#endif
+#if defined(ARM)
+ if (strstr(buf.machine, "arm")) {
+ puts(
+#if defined(__ARM_EABI__) || !defined(ENABLE_ARM_OABI)
+ "1" ARM_eabi_STR
+#else
+ "1" ARM_oabi_STR
+#endif
+ );
+ return 0;
+ }
+#endif
+#if defined(AARCH64)
+ puts(
+#if defined(__ARM_EABI__)
+ "1" AARCH64_eabi_STR
+#else
+ "1" AARCH64_64bit_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(AVR32)
+ puts("1" AVR32_32bit_STR);
+ return 0;
+#endif
+#if defined(ARC)
+ puts("1" ARC_32bit_STR);
+ return 0;
+#endif
+#if defined(S390)
+ puts("1" S390_32bit_STR);
+ return 0;
+#endif
+#if defined(S390X)
+ puts("1" S390X_64bit_STR);
+ return 0;
+#endif
+#if defined(HPPA)
+ puts("1" PARISC_32bit_STR);
+ return 0;
+#endif
+#if defined(SH64)
+ puts("1" SH64_64bit_STR);
+ return 0;
+#endif
+#if defined(SH)
+ puts("1" SH_32bit_STR);
+ return 0;
+#endif
+#if defined(X86_64) || defined(X32)
+ puts(
+#if defined(X86_64)
+ "1" X86_64_64bit_STR
+#elif defined(X32)
+ "1" X86_64_X32_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(I386)
+ if (strstr(buf.machine, "64"))
+ puts("1" X86_64_32bit_STR);
+ else
+ puts("1" X86_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV10)
+ puts("1" CRISV10_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV32)
+ puts("1" CRISV32_32bit_STR);
+ return 0;
+#endif
+#if defined(TILE)
+ puts(
+#if defined(__tilepro__)
+ "1" TILE_64bit_STR
+#else
+ "1" TILE_32bit_STR
+#endif
+ );
+#endif
+#if defined(MICROBLAZE)
+ puts("1" MICROBLAZE_32bit_STR);
+ return 0;
+#endif
+#if defined(NIOS2)
+ puts("1" NIOS2_32bit_STR);
+ return 0;
+#endif
+#if defined(OR1K)
+ puts("1" OR1K_32bit_STR);
+ return 0;
+#endif
+#if defined(XTENSA)
+ puts("1" XTENSA_32bit_STR);
+ return 0;
+#endif
+#if defined(RISCV)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+ printf("../../asinfo: architecture \'%s\' is unsupported\n",
+ buf.machine);
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_arch_abi.test b/tools/asinfo/tests/get_arch_abi.test
new file mode 100755
index 00000000..d320c067
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --get-arch --raw > "$LOG"
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_sname.c b/tools/asinfo/tests/get_sname.c
new file mode 100644
index 00000000..5edd7877
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;\n"
+ "2;pwrite64;18;\n"
+ "3;pwritev;296;\n"
+ "4;pwritev2;328;\n"
+ "5;write;1;\n"
+ "6;writev;20;\n"
+ //--get-sname write,read
+ "1;read;0;\n"
+ "2;write;1;\n"
+ //--get-sname 1
+ "1;write;1;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_sname.test b/tools/asinfo/tests/get_sname.test
new file mode 100755
index 00000000..2bff806e
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_snum.c b/tools/asinfo/tests/get_snum.c
new file mode 100644
index 00000000..ada19312
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;\n"
+ //--get-snum /write
+ "1;1;write;\n"
+ "2;18;pwrite64;\n"
+ "3;20;writev;\n"
+ "4;296;pwritev;\n"
+ "5;311;process_vm_writev;\n"
+ "6;328;pwritev2;\n"
+ //--get-snum write,read
+ "1;0;read;\n"
+ "2;1;write;\n"
+ //--get-snum 1
+ "1;1;write;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_snum.test b/tools/asinfo/tests/get_snum.test
new file mode 100755
index 00000000..02dceca4
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/init.sh b/tools/asinfo/tests/init.sh
new file mode 100644
index 00000000..1ab105d9
--- /dev/null
+++ b/tools/asinfo/tests/init.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# Copyright (c) 2011-2017 The strace developers.
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+ME_="${0##*/}"
+LOG="log"
+OUT="out"
+EXP="exp"
+ASINFO="../../asinfo"
+
+fail_() { warn_ "$ME_: failed test: $*"; exit 1; }
+warn_() { printf >&2 '%s\n' "$*"; }
+
+run_prog()
+{
+ if [ $# -eq 0 ]; then
+ set -- "../$NAME"
+ fi
+ args="$*"
+ "$@" || {
+ rc=$?
+ if [ $rc != 0 ]; then
+ fail_ "$args failed with code $rc"
+ fi
+ }
+}
+
+
+dump_log_and_fail_with()
+{
+ cat < "$LOG" >&2
+ fail_ "$*"
+}
+
+run_asinfo()
+{
+ args="$*"
+ $ASINFO "$@" 2>&1
+}
+
+match_diff()
+{
+ local output expected error
+ if [ $# -eq 0 ]; then
+ output="$LOG"
+ else
+ output="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ expected="$srcdir/$NAME.expected"
+ else
+ expected="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ error="$STRACE $args output mismatch"
+ else
+ error="$1"; shift
+ fi
+
+ diff -u -- "$expected" "$output" ||
+ fail_ "$error"
+}
+
+NAME="${ME_%.test}"
+TESTDIR="$NAME.dir"
+rm -rf -- "$TESTDIR"
+mkdir -- "$TESTDIR"
+cd "$TESTDIR"
+case "$srcdir" in
+ /*) ;;
+ *) srcdir="../$srcdir" ;;
+esac
+
diff --git a/tools/asinfo/tests/list_arch.c b/tools/asinfo/tests/list_arch.c
new file mode 100644
index 00000000..a8b91553
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" BFIN_32bit_STR"\n"
+ "2" IA64_64bit_STR"\n"
+ "3" M68K_32bit_STR"\n"
+ "4" SPARC64_64bit_STR"\n"
+ "5" SPARC64_32bit_STR"\n"
+ "6" SPARC_32bit_STR"\n"
+ "7" METAG_32bit_STR"\n"
+ "8" MIPS64_N64_STR"\n"
+ "9" MIPS64_N32_STR"\n"
+ "10" MIPS64_O32_STR"\n"
+ "11" MIPS_O32_STR"\n"
+ "12" ALPHA_64bit_STR"\n"
+ "13" PPC64_64bit_STR"\n"
+ "14" PPC64_32bit_STR"\n"
+ "15" PPC_32bit_STR"\n"
+ "16" AARCH64_64bit_STR"\n"
+ "17" AARCH64_eabi_STR"\n"
+ "18" ARM_oabi_STR"\n"
+ "19" ARM_eabi_STR"\n"
+ "20" AVR32_32bit_STR"\n"
+ "21" ARC_32bit_STR"\n"
+ "22" S390X_64bit_STR"\n"
+ "23" S390_32bit_STR"\n"
+ "24" PARISC_32bit_STR"\n"
+ "25" SH64_64bit_STR"\n"
+ "26" SH_32bit_STR"\n"
+ "27" X86_64_64bit_STR"\n"
+ "28" X86_64_X32_STR"\n"
+ "29" X86_64_32bit_STR"\n"
+ "30" X86_32bit_STR"\n"
+ "31" CRISV10_32bit_STR"\n"
+ "32" CRISV32_32bit_STR"\n"
+ "33" TILE_64bit_STR"\n"
+ "34" TILE_32bit_STR"\n"
+ "35" TILEPRO_32bit_STR"\n"
+ "36" MICROBLAZE_32bit_STR"\n"
+ "37" NIOS2_32bit_STR"\n"
+ "38" OR1K_32bit_STR"\n"
+ "39" XTENSA_32bit_STR"\n"
+ "40" RISCV_64bit_STR"\n"
+ "41" RISCV_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/list_arch.test b/tools/asinfo/tests/list_arch.test
new file mode 100755
index 00000000..263d69df
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --list-arch --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_sname.c b/tools/asinfo/tests/multiarch_get_sname.c
new file mode 100644
index 00000000..53d219a9
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;1;4;4;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;540;348;348;\n"
+ "2;pwrite64;18;18;181;181;\n"
+ "3;pwritev;296;535;334;334;\n"
+ "4;pwritev2;328;547;379;379;\n"
+ "5;write;1;1;4;4;\n"
+ "6;writev;20;516;146;146;\n"
+ //--get-sname write,read
+ "1;read;0;0;3;3;\n"
+ "2;write;1;1;4;4;\n"
+ //--get-sname 1
+ "1;exit;-;-;1;1;\n"
+ "2;write;1;1;-;-;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_sname.test b/tools/asinfo/tests/multiarch_get_sname.test
new file mode 100755
index 00000000..0ff7bb92
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_snum.c b/tools/asinfo/tests/multiarch_get_snum.c
new file mode 100644
index 00000000..27658d20
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ //--get-snum /write
+ "1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ "3;18;pwrite64;pwrite64;-;-;\n"
+ "4;20;writev;-;-;-;\n"
+ "5;146;-;-;writev;writev;\n"
+ "6;181;-;-;pwrite64;pwrite64;\n"
+ "7;296;pwritev;-;-;-;\n"
+ "8;311;process_vm_writev;-;-;-;\n"
+ "9;328;pwritev2;-;-;-;\n"
+ "10;334;-;-;pwritev;pwritev;\n"
+ "11;348;-;-;process_vm_writev;process_vm_writev;\n"
+ "12;379;-;-;pwritev2;pwritev2;\n"
+ "13;516;-;writev;-;-;\n"
+ "14;535;-;pwritev;-;-;\n"
+ "15;540;-;process_vm_writev;-;-;\n"
+ "16;547;-;pwritev2;-;-;\n"
+ //--get-snum write,read
+ "1;0;read;read;-;-;\n"
+ "2;1;write;write;-;-;\n"
+ "3;3;-;-;read;read;\n"
+ "4;4;-;-;write;write;\n"
+ //--get-snum 1
+ "1;1;write;write;exit;exit;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_snum.test b/tools/asinfo/tests/multiarch_get_snum.test
new file mode 100755
index 00000000..364903a6
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/ref_asinfo_output.h b/tools/asinfo/tests/ref_asinfo_output.h
new file mode 100644
index 00000000..bc5fce4c
--- /dev/null
+++ b/tools/asinfo/tests/ref_asinfo_output.h
@@ -0,0 +1,42 @@
+/* Reference output strings for asinfo tool which are necessary for tests */
+#define BFIN_32bit_STR ";blackfin/bfin;32bit;391;external;external;"
+#define IA64_64bit_STR ";ia64;64bit;707;external;external;"
+#define M68K_32bit_STR ";m68k;32bit;378;internal;internal;"
+#define SPARC64_64bit_STR ";sparc64;64bit;340;internal;internal;"
+#define SPARC64_32bit_STR ";sparc64;32bit;358;internal;internal;"
+#define SPARC_32bit_STR ";sparc;32bit;358;internal;internal;"
+#define METAG_32bit_STR ";metag;32bit;280;external;external;"
+#define MIPS64_N64_STR ";mips64/mips64le;n64;1000;int/ext;int/ext;"
+#define MIPS64_N32_STR ";mips64/mips64le;n32;1004;int/ext;int/ext;"
+#define MIPS64_O32_STR ";mips64/mips64le;o32;1039;internal;internal;"
+#define MIPS_O32_STR ";mips/mipsle;o32;1039;internal;internal;"
+#define ALPHA_64bit_STR ";alpha;64bit;442;external;external;"
+#define PPC64_64bit_STR ";ppc64/ppc64le/powerpc64;64bit;374;int/ext;int/ext;"
+#define PPC64_32bit_STR ";ppc64/ppc64le/powerpc64;32bit;383;int/ext;int/ext;"
+#define PPC_32bit_STR ";ppc/ppcle/powerpc;32bit;383;int/ext;int/ext;"
+#define AARCH64_64bit_STR ";aarch64/arm64;64bit;332;external;external;"
+#define AARCH64_eabi_STR ";aarch64/arm64;eabi;400;external;external;"
+#define ARM_oabi_STR ";arm;oabi;400;int/ext;int/ext;"
+#define ARM_eabi_STR ";arm;eabi;400;external;external;"
+#define AVR32_32bit_STR ";avr32;32bit;329;external;external;"
+#define ARC_32bit_STR ";arc;32bit;281;external;external;"
+#define S390X_64bit_STR ";s390x;64bit;326;internal;internal;"
+#define S390_32bit_STR ";s390;32bit;359;internal;internal;"
+#define PARISC_32bit_STR ";parisc/hppa;32bit;349;external;external;"
+#define SH64_64bit_STR ";sh64;64bit;382;int/ext;int/ext;"
+#define SH_32bit_STR ";sh;32bit;374;internal;internal;"
+#define X86_64_64bit_STR ";x86_64/amd64/EM64T;64bit;333;external;external;"
+#define X86_64_X32_STR ";x86_64/amd64/EM64T;x32;369;external;external;"
+#define X86_64_32bit_STR ";x86_64/amd64/EM64T;32bit;381;internal;internal;"
+#define X86_32bit_STR ";x86/i386/i486/i586/i686;32bit;381;internal;internal;"
+#define CRISV10_32bit_STR ";cris/crisv10;32bit;355;internal;internal;"
+#define CRISV32_32bit_STR ";crisv32;32bit;355;internal;internal;"
+#define TILE_64bit_STR ";tile/tilegx;64bit;278;external;external;"
+#define TILE_32bit_STR ";tile/tilegx;32bit;278;external;external;"
+#define TILEPRO_32bit_STR ";tilepro;32bit;278;external;external;"
+#define MICROBLAZE_32bit_STR ";microblaze;32bit;395;external;external;"
+#define NIOS2_32bit_STR ";nios2;32bit;277;external;external;"
+#define OR1K_32bit_STR ";openrisc/or1k;32bit;277;external;external;"
+#define XTENSA_32bit_STR ";xtensa;32bit;325;external;external;"
+#define RISCV_64bit_STR ";riscv;64bit;276;external;external;"
+#define RISCV_32bit_STR ";riscv;32bit;276;external;external;"
diff --git a/tools/asinfo/tests/set_abi.c b/tools/asinfo/tests/set_abi.c
new file mode 100644
index 00000000..b74e0ccb
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_abi.test b/tools/asinfo/tests/set_abi.test
new file mode 100755
index 00000000..70b1f429
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_arch.c b/tools/asinfo/tests/set_arch.c
new file mode 100644
index 00000000..05f44b79
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" X86_64_X32_STR "\n"
+ "3" X86_64_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_arch.test b/tools/asinfo/tests/set_arch.test
new file mode 100755
index 00000000..e9a102c6
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --list-abi --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_abi.c b/tools/asinfo/tests/set_mult_abi.c
new file mode 100644
index 00000000..4107fabb
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" AARCH64_64bit_STR "\n"
+ "3" AARCH64_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_abi.test b/tools/asinfo/tests/set_mult_abi.test
new file mode 100755
index 00000000..555c27ca
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,aarch64 --set-abi 64bit,all --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_arch.c b/tools/asinfo/tests/set_mult_arch.c
new file mode 100644
index 00000000..ed8d66df
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" AARCH64_64bit_STR "\n"
+ "2" AARCH64_eabi_STR "\n"
+ "3" ARM_oabi_STR "\n"
+ "4" ARM_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_arch.test b/tools/asinfo/tests/set_mult_arch.test
new file mode 100755
index 00000000..d0152d60
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch aarch64,arm --list-abi --raw >> $LOG
+match_diff "$LOG" "$EXP"
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:53
|
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 448a9cb3..8ae25fbd 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ Noteworthy changes in release ?.?? (????-??-??) * Bug fixes * Fixed multi-personality support in cross builds. +* New tools + * Added asinfo tool, that is purposed to provide information about + system calls and architectures. + Noteworthy changes in release 4.20 (2017-11-13) =============================================== -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:52
|
As asinfo detects ABI mode based on userspace environment in biarch
systems, add asinfo only to strace package.
* debian/control (strace, strace-udeb): Add asinfo decription.
* debian/strace.install: Add path to asinfo binary.
* debian/strace.manpages: Add path to asinfo man.
* strace.spec.in (%files): Add asinfo binary.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
debian/control | 6 ++++++
debian/strace.install | 1 +
debian/strace.manpages | 1 +
strace.spec.in | 7 +++++--
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/debian/control b/debian/control
index 92cdc204..f47b36a1 100644
--- a/debian/control
+++ b/debian/control
@@ -20,6 +20,9 @@ Description: System call tracer
System calls and signals are events that happen at the user/kernel
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
+ .
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
Package: strace64
Architecture: i386 powerpc s390 sparc
@@ -54,5 +57,8 @@ Description: System call tracer
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
.
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
+ .
This is a stripped down package intended for debugging use in the Debian
installer.
diff --git a/debian/strace.install b/debian/strace.install
index 30b0a6b0..1e2401bb 100644
--- a/debian/strace.install
+++ b/debian/strace.install
@@ -1,2 +1,3 @@
build/strace usr/bin
strace-log-merge usr/bin
+build/tools/asinfo/asinfo usr/bin
diff --git a/debian/strace.manpages b/debian/strace.manpages
index d3b94482..cd0be9eb 100644
--- a/debian/strace.manpages
+++ b/debian/strace.manpages
@@ -1,2 +1,3 @@
strace.1
strace-log-merge.1
+build/tools/asinfo/asinfo.1
diff --git a/strace.spec.in b/strace.spec.in
index 41b69d0e..cbd15995 100644
--- a/strace.spec.in
+++ b/strace.spec.in
@@ -21,7 +21,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -36,7 +37,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -92,6 +94,7 @@ echo 'END OF TEST SUITE INFORMATION'
%{?suse_version:%defattr(-,root,root)}
%doc CREDITS ChangeLog ChangeLog-CVS COPYING NEWS README
%{_bindir}/strace
+${_bindir}/asinfo
%{_bindir}/strace-log-merge
%{_mandir}/man1/*
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:51
|
Since arch_definitions.h contains full description about architectures, arch_includes.h and arch_personalities.h can be generated. * tools/asinfo/gen_asinfo_files.sh: New file. * bootstrap: Add it. * tools/asinfo/arch_includes.h: Delete it. * tools/asinfo/arch_personalities.h: Likewise. * tools/asinfo/Makefile.am: Include Makemodule.am. (asinfo_SOURCES): Add $(ARCH_AUX_FILES). * tools/asinfo/README-arch: New README explaining how to add new architecture/ABI to asinfo tool. * tools/asinfo/.gitignore: Add generated files. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- bootstrap | 1 + configure.ac | 5 + tools/asinfo/.gitignore | 3 + tools/asinfo/Makefile.am | 6 +- tools/asinfo/README-arch | 38 ++++++ tools/asinfo/arch_includes.h | 272 ------------------------------------ tools/asinfo/arch_personalities.h | 36 ----- tools/asinfo/asinfo.1.in | 280 ++++++++++++++++++++++++++++++++++++++ tools/asinfo/gen_asinfo_files.sh | 160 ++++++++++++++++++++++ 9 files changed, 491 insertions(+), 310 deletions(-) create mode 100644 tools/asinfo/README-arch delete mode 100644 tools/asinfo/arch_includes.h delete mode 100644 tools/asinfo/arch_personalities.h create mode 100644 tools/asinfo/asinfo.1.in create mode 100755 tools/asinfo/gen_asinfo_files.sh diff --git a/bootstrap b/bootstrap index a9cadf53..da06de3b 100755 --- a/bootstrap +++ b/bootstrap @@ -4,6 +4,7 @@ ./xlat/gen.sh ./tests/gen_pure_executables.sh ./tests/gen_tests.sh +./tools/asinfo/gen_asinfo_files.sh for m in m32 mx32; do tests=tests-$m diff --git a/configure.ac b/configure.ac index 0492bd8b..79690ba1 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AC_INIT([strace], [https://strace.io]) m4_define([copyright_year], m4_esyscmd([./copyright-year-gen .year])) m4_define([manpage_date], m4_esyscmd([./file-date-gen strace.1.in])) +m4_define([asinfo_manpage_date], m4_esyscmd([./file-date-gen tools/asinfo/asinfo.1.in])) AC_COPYRIGHT([Copyright (c) 1999-]copyright_year[ The strace developers.]) AC_CONFIG_SRCDIR([strace.c]) AC_CONFIG_AUX_DIR([.]) @@ -67,6 +68,9 @@ AC_SUBST([COPYRIGHT_YEAR], [copyright_year]) AC_DEFINE([MANPAGE_DATE], "[manpage_date]", [Date]) AC_SUBST([MANPAGE_DATE], [manpage_date]) +AC_DEFINE([ASINFO_MANPAGE_DATE], "[asinfo_manpage_date]", [Date]) +AC_SUBST([ASINFO_MANPAGE_DATE], [asinfo_manpage_date]) + AC_MSG_CHECKING([for supported architecture]) arch_m32= arch_mx32= @@ -904,6 +908,7 @@ AC_CONFIG_FILES([Makefile tests-mx32/Makefile strace.1 strace-log-merge.1 + tools/asinfo/asinfo.1 tools/Makefile tools/asinfo/Makefile strace.spec diff --git a/tools/asinfo/.gitignore b/tools/asinfo/.gitignore index 09400c47..3254269c 100644 --- a/tools/asinfo/.gitignore +++ b/tools/asinfo/.gitignore @@ -1,2 +1,5 @@ +arch_includes.h +arch_personalities.h asinfo asinfo.1 +Makemodule.am diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am index 5051766e..f2b23e74 100644 --- a/tools/asinfo/Makefile.am +++ b/tools/asinfo/Makefile.am @@ -38,6 +38,9 @@ AM_CPPFLAGS = -I$(builddir) \ -I$(top_srcdir)/$(OS) \ -I$(top_builddir) \ -I$(top_srcdir) + +include Makemodule.am + asinfo_CPPFLAGS = $(AM_CPPFLAGS) asinfo_CFLAGS = $(AM_CFLAGS) asinfo_LDFLAGS = @@ -47,10 +50,9 @@ asinfo_LDADD = -L$(top_srcdir) \ asinfo_SOURCES = \ arch_definitions.h \ - arch_includes.h \ arch_interface.c \ + $(ARCH_AUX_FILES) \ arch_interface.h \ - arch_personalities.h \ asinfo.c \ dispatchers.c \ dispatchers.h \ diff --git a/tools/asinfo/README-arch b/tools/asinfo/README-arch new file mode 100644 index 00000000..6b73aa01 --- /dev/null +++ b/tools/asinfo/README-arch @@ -0,0 +1,38 @@ +This file describes the storage format of arch_definitions.h + +Storage format: +/* [ARCH_SPECIFIC_DEFINE],[ACONST1,ACONST2] */ +ARCH_DESC_DEFINE(ARCH_NAME,ARCH_ABI,PASS({COMPAT_PERS1,COMPAT_PERS2,...}),\ +PASS({ALIAS1,ALIAS2,...})) + +ARCH_SPECIFIC_DEFINE: +One syscallent.h header can contain several set of system calls for each +compatible mode. And specific set can be switched by passing particular +definition. +So ARCH_SPECIFIC_DEFINE allows to forward a given definition, where +!ARCH_SPECIFIC_DEFINE forwards undefined. +If it is not required, left empty. + +ACONST1,ACONST2: +It could be used to store architecture specific constants and pass them to code. +If is is not required each one must be set to zero. + +ARCH_NAME: +The main name of architecture will be used to generate the personality +constants. +The personality constant is equal to ARCH_+\$ARCH_ABI+_+\$ARCH_NAME. + +ARCH_ABI: +Application binary interface for a given architecture, i.e. 32bit, 64bit, oabi, +eabi, o32 etc. + +COMPAT_PERS1,COMPAT_PERS2,...: +Compatible mode for a given architecture. It should be one of personality +constants. +If is is not required, left empty. + +ALIAS1,ALIAS2,...: +Other name of the same architecture, like x86 and i386. At least one alias +must to be set as it shows the name of architecture while printing. +If current ARCH_NAME is just the compatible ABI mode, left empty. + diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h deleted file mode 100644 index e73a8328..00000000 --- a/tools/asinfo/arch_includes.h +++ /dev/null @@ -1,272 +0,0 @@ -/* ARCH_blackfin */ -static const struct_sysent blackfin_32bit_sysent[] = { - #include "bfin/syscallent.h" -}; -static const int blackfin_32bit_usr1 = 0; -const int blackfin_32bit_usr2 = 0; -/* ARCH_ia64 */ -struct_sysent ia64_64bit_sysent[] = { - #include "ia64/syscallent.h" -}; -static const int ia64_64bit_usr1 = 0; -static const int ia64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_m68k */ -static const struct_sysent m68k_32bit_sysent[] = { - #include "m68k/syscallent.h" -}; -static const int m68k_32bit_usr1 = 0; -static const int m68k_32bit_usr2 = 0; -/* ARCH_sparc64 64bit ABI */ -static const struct_sysent sparc64_64bit_sysent[] = { - #include "sparc64/syscallent.h" -}; -static const int sparc64_64bit_usr1 = 0; -static const int sparc64_64bit_usr2 = 0; -/* ARCH_sparc and 32bit ABI */ -static const struct_sysent sparc_32bit_sysent[] = { - #include "sparc/syscallent.h" -}; -static const int sparc_32bit_usr1 = 0; -static const int sparc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_metag */ -static const struct_sysent metag_32bit_sysent[] = { - #include "metag/syscallent.h" -}; -static const int metag_32bit_usr1 = 0; -static const int metag_32bit_usr2 = 0; -/* ARCH_mips n64 ABI */ -#ifndef LINUX_MIPSN64 -# define LINUX_MIPSN64 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n64_usr1 = 0; -static const int mips64_n64_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips n32 ABI */ -#ifndef LINUX_MIPSN32 -# define LINUX_MIPSN32 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n32_usr1 = 0; -static const int mips64_n32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips o32 ABI */ -#ifndef LINUX_MIPSO32 -# define LINUX_MIPSO32 1 -# define NOW_DEFINED 1 -#endif -static const 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 -static const int mips_o32_usr1 = 0; -static const int mips_o32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_alpha */ -static const struct_sysent alpha_64bit_sysent[] = { - #include "alpha/syscallent.h" -}; -static const int alpha_64bit_usr1 = 0; -static const int alpha_64bit_usr2 = 0; -/* ARCH_ppc64 64bit ABI */ -static const struct_sysent ppc64_64bit_sysent[] = { - #include "powerpc64/syscallent.h" -}; -static const int ppc64_64bit_usr1 = 0; -static const int ppc64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_ppc and 32bit */ -static const struct_sysent ppc_32bit_sysent[] = { - #include "powerpc/syscallent.h" -}; -static const int ppc_32bit_usr1 = 0; -static const int ppc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_aarch64 64bit ABI */ -static const struct_sysent aarch64_64bit_sysent[] = { - #include "aarch64/syscallent.h" -}; -static const int aarch64_64bit_usr1 = 0; -static const int aarch64_64bit_usr2 = 0; -/* ARCH_arm OABI*/ -#ifdef __ARM_EABI__ -# undef __ARM_EABI__ -# define NOW_UNDEFINED 1 -#endif -static const struct_sysent arm_oabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL; -#undef ARM_FIRST_SHUFFLED_SYSCALL -#undef ARM_LAST_SPECIAL_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 -static const struct_sysent arm_eabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_eabi_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 */ -static const struct_sysent avr32_32bit_sysent[] = { - #include "avr32/syscallent.h" -}; -static const int avr32_32bit_usr1 = 0; -static const int avr32_32bit_usr2 = 0; -/* ARCH_arc */ -static const struct_sysent arc_32bit_sysent[] = { - #include "arc/syscallent.h" -}; -static const int arc_32bit_usr1 = 0; -static const int arc_32bit_usr2 = 0; -/* ARCH_s390x */ -static const struct_sysent s390x_64bit_sysent[] = { - #include "s390x/syscallent.h" -}; -static const int s390x_64bit_usr1 = 0; -static const int s390x_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_s390 */ -static const struct_sysent s390_32bit_sysent[] = { - #include "s390/syscallent.h" -}; -static const int s390_32bit_usr1 = 0; -static const int s390_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_hppa */ -static const struct_sysent hppa_32bit_sysent[] = { - #include "hppa/syscallent.h" -}; -static const int hppa_32bit_usr1 = 0; -static const int hppa_32bit_usr2 = 0; -/* ARCH_sh64 */ -static const struct_sysent sh64_64bit_sysent[] = { - #include "sh64/syscallent.h" -}; -static const int sh64_64bit_usr1 = 0; -static const int sh64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_sh */ -static const struct_sysent sh_32bit_sysent[] = { - #include "sh/syscallent.h" -}; -static const int sh_32bit_usr1 = 0; -static const int sh_32bit_usr2 = 0; -/* ARCH_x86_64 64bit ABI mode */ -static const struct_sysent x86_64_64bit_sysent[] = { - #include "x86_64/syscallent.h" -}; -static const int x86_64_64bit_usr1 = 0; -static const int x86_64_64bit_usr2 = 0; -/* ARCH_x86_64 x32 ABI mode */ -static const struct_sysent x86_64_x32_sysent[] = { - #include "x86_64/syscallent2.h" -}; -static const int x86_64_x32_usr1 = 0; -static const int x86_64_x32_usr2 = 0; -/* ARCH_x86 */ -static const struct_sysent x86_32bit_sysent[] = { - #include "i386/syscallent.h" -}; -static const int x86_32bit_usr1 = 0; -static const int x86_32bit_usr2 = 0; -/* ARCH_cris */ -static struct_sysent cris_32bit_sysent[] = { - #include "crisv10/syscallent.h" -}; -static const int cris_32bit_usr1 = 0; -static const int cris_32bit_usr2 = 0; -/* ARCH_crisv32 */ -static const struct_sysent crisv32_32bit_sysent[] = { - #include "crisv32/syscallent.h" -}; -static const int crisv32_32bit_usr1 = 0; -static const int crisv32_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_tile 64bit ABI mode */ -static const struct_sysent tile_64bit_sysent[] = { - #include "tile/syscallent.h" -}; -static const int tile_64bit_usr1 = 0; -static const int tile_64bit_usr2 = 0; -/* ARCH_tile 32bit ABI mode */ -static const struct_sysent tile_32bit_sysent[] = { - #include "tile/syscallent1.h" -}; -static const int tile_32bit_usr1 = 0; -static const int tile_32bit_usr2 = 0; -/* ARCH_microblaze */ -static const struct_sysent microblaze_32bit_sysent[] = { - #include "microblaze/syscallent.h" -}; -static const int microblaze_32bit_usr1 = 0; -static const int microblaze_32bit_usr2 = 0; -/* ARCH_nios2 */ -static const struct_sysent nios2_32bit_sysent[] = { - #include "nios2/syscallent.h" -}; -static const int nios2_32bit_usr1 = 0; -static const int nios2_32bit_usr2 = 0; -/* ARCH_openrisc */ -struct_sysent openrisc_32bit_sysent[] = { - #include "or1k/syscallent.h" -}; -static const int openrisc_32bit_usr1 = 0; -static const int openrisc_32bit_usr2 = 0; -/* ARCH_xtensa */ -static const struct_sysent xtensa_32bit_sysent[] = { - #include "xtensa/syscallent.h" -}; -static const int xtensa_32bit_usr1 = 0; -static const int xtensa_32bit_usr2 = 0; -/* ARCH_riscv 64bit ABI mode */ -static const struct_sysent riscv_64bit_sysent[] = { - #include "riscv/syscallent.h" -}; -static const int riscv_64bit_usr1 = 0; -static const int riscv_64bit_usr2 = 0; -/* ARCH_riscv 32bit ABI mode */ -static const struct_sysent riscv_32bit_sysent[] = { - #include "riscv/syscallent1.h" -}; -static const int riscv_32bit_usr1 = 0; -static const int riscv_32bit_usr2 = 0; diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h deleted file mode 100644 index 9499c5aa..00000000 --- a/tools/asinfo/arch_personalities.h +++ /dev/null @@ -1,36 +0,0 @@ -ARCH_no_pers, -ARCH_blackfin_32bit, -ARCH_ia64_64bit, -ARCH_m68k_32bit, -ARCH_sparc64_64bit, -ARCH_sparc_32bit, -ARCH_metag_32bit, -ARCH_mips64_n64, -ARCH_mips64_n32, -ARCH_mips_o32, -ARCH_alpha_64bit, -ARCH_ppc64_64bit, -ARCH_ppc_32bit, -ARCH_aarch64_64bit, -ARCH_arm_oabi, -ARCH_arm_eabi, -ARCH_avr32_32bit, -ARCH_arc_32bit, -ARCH_s390x_64bit, -ARCH_s390_32bit, -ARCH_hppa_32bit, -ARCH_sh64_64bit, -ARCH_sh_32bit, -ARCH_x86_64_64bit, -ARCH_x86_64_x32, -ARCH_x86_32bit, -ARCH_cris_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 diff --git a/tools/asinfo/asinfo.1.in b/tools/asinfo/asinfo.1.in new file mode 100644 index 00000000..009c69ed --- /dev/null +++ b/tools/asinfo/asinfo.1.in @@ -0,0 +1,280 @@ +.\" Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...> +.\" Copyright (c) 1996-2017 The strace developers. +.\" 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. + +.\" Required option. +.de OR +. ie \\n(.$-1 \ +. RI "\fB\\$1\fP" "\ \\$2" +. el \ +. BR "\\$1" +.. +.TH ASINFO 1 "@ASINFO_MANPAGE_DATE@" "strace package @VERSION@" +.SH NAME +asinfo \- advanced system call information tool +.SH SYNOPSIS +.SY asinfo +.BR "" \fR[{ +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" } +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR]\fR] +.BR "" { +.BR "" { +.OR \-\-get\-sname expr +.BR "" | +.OR \-\-get\-snum expr +.BR "" } +.OP \-\-nargs +.BR "" } +.OP "\-\-raw" +.YS +.SY asinfo +.BR "" { +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" | +.OR \-\-list\-arch +.BR "" } +.BD "" [ +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR] +.OP "\-\-raw" + +.SH DESCRIPTION +.B asinfo +is a useful tool, which aimed to provide information about system calls, +architectures, and application binary interfaces (ABIs). In the simplest +case it provides mapping from system call name to number and reverse. +The main advantage of tool is it can work in single/multi arch modes with +the opportunity to show discrepancies in system call characteristics. +Also, the single arch mode allows program to take a guess about the +current architecture and ABI, if they are not specified. Furthermore, +.B asinfo +provides convenient filtering for selecting system calls. + +.SH OPTIONS +.SS "Architecture parameters" +.TP 7 +.BI "\-\-set\-arch " arch +Specify architecture/architectures manually. The format of the +.I arch +expression is: +.RS 9 +.IP +\fIarch1\/\fR[\fB,\fIarch2\/\fR]... +.RE +.IP +.TP +.B \-\-get\-arch +Select achitecture based on the current machine. +.TP +.B \-\-list-arch +Print out all supported architectures. +Combined use with any ABI option is permitted. +.SS "ABI parameters" +.TP 7 +.BI "\-\-set\-abi " abi +Specify ABI/ABIs manually. The format of the experession is: +.RS 9 +.IP +\fIabi1\/\fR[\fB,\fIabi2\/\fR]... +.RE +.IP +.IP +Note that ABI should be selected for each corresponding architecture. +In addition, the special value +.B all +allows to choose all ABIs for the respective architecture. +.TP +.B "\-\-list\-abi " +Select all ABIs for the chosen architecture/architectures. +.IP +If ABI parameters are not used and only single architecture is selected, tool +will take a guess about ABI based on the strace package build. +.SS "System call parameters" +.TP 7 +.BI "\-\-get\-sname " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out name of system calls and numbers for each architecture/ABI. +.TP +.BI "\-\-get\-snum " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out number of system calls and names for each architecture/ABI. +.TP +.B \-\-nargs +Switch the second output system call characteristic to number of arguments. +.SS Output formatting +.TP 7 +.B "\-\-raw" +Reset alignment and remove titles, use ';' as a delimiter. +.SS Miscellaneous +.TP 7 +.B \-h +Print the help summary. +.TP +.B \-v +Print the version number. + +.SH "FILTERING EXPRESSION" +A filtering expression is a pattern that describes a set of syscall names, +syscall numbers, and syscall group. The format of the expression is: +.RS 2 +.IP +[\fB!\fR][\fB?\fR]\,\fIvalue1\/\fR[\fB,\fR[\fB?\fR]\,\fIvalue2\/\fR]... +.RE +.LP +where +.I value +is a symbol or number. Using an exclamation mark negates the set of values. +For example, +.BR \fIvalue\fR = write +means print strictly the write system call. By contrast, +.BR \fIvalue\fR = !write +means to dump every system call except write. Question mark before the +syscall qualification allows suppression of error in case no syscalls matched +the qualification provided, that can be particularly useful in multiarch mode, +when system call is not presented in all selected architectures. In addition, +the special values +.B all +and +.B none +have the obvious meanings. +.LP +Note that some shells use the exclamation point for history +expansion even inside quoted arguments. If so, you must escape +the exclamation point with a backslash. +.SS "Strict match" +.TP 7 +.B \fIvalue\fR=\,\fIset\fR +Print out only the specified set of system calls. For example, +.BR \fIvalue\fR = open,close,read,write +means to only show those four system calls. +.SS "Regex match" +.TP 7 +.B \fIvalue\fR=/\,\fIregex\fR +Show only those system calls that match the +.IR regex . +You can use +.B POSIX +Extended Regular Expression syntax (see +.BR regex (7)). +.SS "Class match" +.TP 7 +.BR \fIvalue\fR = %file +.TQ +.BR \fIvalue\fR = file " (deprecated)" +Show all system calls which take a file name as an argument. You +can think of this as an abbreviation for +.BR \fIvalue\fR = open,stat,chmod,unlink,... +Furthermore, using the abbreviation will ensure that you don't +accidentally forget to include a call like +.B lstat +in the list. +.PP +.BR \fIvalue\fR = %process +.TQ +.BR \fIvalue\fR = process " (deprecated)" +Show all system calls which involve process management. +.PP +.BR \fIvalue\fR = %network +.TQ +.BR \fIvalue\fR = network " (deprecated)" +Show all the network related system calls. +.PP +.BR \fIvalue\fR = %signal +.TQ +.BR \fIvalue\fR = signal " (deprecated)" +Show all signal related system calls. +.PP +.BR \fIvalue\fR = %ipc +.TQ +.BR \fIvalue\fR = ipc " (deprecated)" +Show all IPC related system calls. +.PP +.BR \fIvalue\fR = %desc +.TQ +.BR \fIvalue\fR = desc " (deprecated)" +Show all file descriptor related system calls. +.PP +.BR \fIvalue\fR = %memory +.TQ +.BR \fIvalue\fR = memory " (deprecated)" +Show all memory mapping related system calls. +.TP +.BR \fIvalue\fR = %stat +Show stat syscall variants. +.TP +.BR \fIvalue\fR = %lstat +Show lstat syscall variants. +.TP +.BR \fIvalue\fR = %fstat +Show fstat and fstatat syscall variants. +.TP +.BR \fIvalue\fR = %%stat +Show syscalls used for requesting file status (stat, lstat, fstat, fstatat, +statx, and their variants). +.TP +.BR \fIvalue\fR = %statfs +Show statfs, statfs64, statvfs, osf_statfs, and osf_statfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /^(.*_)?statv?fs +regular expression. +.TP +.BR \fIvalue\fR = %fstatfs +Show fstatfs, fstatfs64, fstatvfs, osf_fstatfs, and osf_fstatfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /fstatv?fs +regular expression. +.TP +.BR \fIvalue\fR = %%statfs +Show syscalls related to file system statistics (statfs-like, fstatfs-like, +and ustat). The same effect can be achieved with +.BR \fIvalue\fR = /statv?fs|fsstat|ustat +regular expression. + +.SH "EXIT STATUS" +On success, +.B asinfo +returns 0. Otherwise, in case of wrong input or no matches found, 1. + +.SH "REPORTING BUGS" +Problems with +.B asinfo +should be reported to the +.B strace +mailing list at <str...@li...>. + +.SH "SEE ALSO" +.BR strace (1) diff --git a/tools/asinfo/gen_asinfo_files.sh b/tools/asinfo/gen_asinfo_files.sh new file mode 100755 index 00000000..bd7b33ae --- /dev/null +++ b/tools/asinfo/gen_asinfo_files.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# +# Code generator simplifies addition of new architecture to asinfo tool +# +# Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...> +# 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. + +cur_pers="" + +gen_pers_line() +{ + local out_file="$1" + local line="$2" + local arch_abi="" + + LC_COLLATE=C + arch_abi="$(printf %s "${line}" | + sed 's/ARCH_DESC_DEFINE(//' | cut -d, -f 1,2 | + sed 's/,/_/g')" + cur_pers="${arch_abi}" + echo "ARCH_${arch_abi}," >> "${out_file}" +} + +gen_includes_block() +{ + local out_file="$1" + local line="$2" + local def is_def includes include nums num count + + ( + LC_COLLATE=C + echo "/* ${cur_pers} */" + def="$(printf %s "${line#*\*}" | cut -d] -f 1 | sed 's/.*[][]//g')" + #Generate define construction + if [ "${def#!}" != "" ] && [ $(printf %.1s "${def}") = "!" ]; then + cat <<-EOF + #ifdef ${def#!} + # undef ${def#!} + # define ${def#!}_DUMMY_UNDEFINE + #endif + EOF + is_def="def" + else if [ "${def#!}" != "" ]; then + cat <<-EOF + #ifndef ${def} + # define ${def} + # define ${def}_DUMMY_DEFINE + #endif + EOF + is_def="undef" + fi + fi + #Generate includes + includes="$(printf %s "${line#*\*}" | cut -d] -f 2 | sed 's/.*[][]//g')" + echo "static const struct_sysent ${cur_pers}_sysent[] = {" + for include in $(echo "${includes}" | sed "s/,/ /g") + do + echo " #include \"${include}\"" + done + echo "};" + #Undefine definitions, if it is required + if [ "${is_def}" = "def" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_UNDEFINE + # define ${def#!} 1 + # undef ${def#!}_DUMMY_UNDEFINE + #endif + EOF + else if [ "${is_def}" = "undef" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_DEFINE + # undef ${def#!} + # undef ${def#!}_DUMMY_DEFINE + #endif + EOF + fi + fi + #Generate arch specific numbers + nums="$(printf %s "${line#*\*}" | cut -d] -f 3 | sed 's/.*[][]//g')" + count=1 + for num in $(echo "${nums}" | sed "s/,/ /g") + do + echo "static const int ${cur_pers}_usr${count} = ${num};" + count=$((count+1)) + case "${num}" in + *[A-Za-z_]*) echo "#undef ${num}" ;; + *) ;; + esac + done + if [ $count -eq 1 ]; then + echo "static const int ${cur_pers}_usr${count} = 0;" + fi + echo "#undef SYS_socket_subcall" + ) >> "${out_file}" + echo "${def}" >> "${out_file}" +} + +main() +{ + set -- "${0%/*}" "${0%/*}" + + local input="$1" + local output="$2" + local defs_file="arch_definitions.h" + local pers_file="arch_personalities.h" + local includes_file="arch_includes.h" + local pline="" + + echo "ARCH_no_pers," > "${output}/${pers_file}" + echo -n > "${output}/${includes_file}" + + #Main work + while read line; do + line="$(printf %s "${line}" | sed 's/[[:space:]]//g')" + if $(printf %s "${line}" | + grep -F "ARCH_DESC_DEFINE" > /dev/null); then + gen_pers_line "${output}/${pers_file}" "${line}" + fi + if $(printf %s "${pline}" | grep -F "/*" > /dev/null); then + gen_includes_block "${output}/${includes_file}"\ + "${pline}" + fi + pline="${line}" + done < "${input}/${defs_file}" + #Makemodule.am + ( + printf "ARCH_AUX_FILES = ${includes_file} ${pers_file}" + echo + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${includes_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${pers_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + ) > "${output}/Makemodule.am" +} + +main "$@" -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:48
|
The main purpose of this query tool is to present all information concluded
at sysent.h files in a convenient way.
The asinfo tool has the following staged architecture:
(command dispatcher)->(architecture dispatcher)->
(abi dispatcher)->(system call dispatcher).
Each dispatcher accepts proccesed data from the previous one.
This point can be illustrated by the following example:
$ asinfo --get-arch --get-sname write
First of all, arch_dispatcher will return the current architecture, based on
uname return value, after that in case of no options for abi_dispatcher,
it perceives empty parameter as get-abi parameter and returns ABI mode set at
compile time of strace package. Therefore, syscall_dispatcher accepts this
architecture/ABI and works with specific set of system calls. It is worth
mentioning that it supports all architectures/ABIs supported by strace.
Also, tool can work in multi-arch mode. for instance:
$ ./tools/asinfo/asinfo --set-arch mips64,mips --set-abi n64,all
--get-snum 100,8,ipc
For more info, use asinfo -h.
* Makefile.am (SUBDIRS): Add tools directory.
* configure.ac (AC_CONFIG_FILES): Add Makefiles.
* tools/Makefile.am: New file.
* tools/asinfo/Makefile.am: Likewise.
* tools/asinfo/dispatchers.h: New file. Prototype abi_dispatcher,
arch_dispatcher, and syscall_dispatcher.
* tools/asinfo/dispatchers.c: New file. Implement them.
* tools/asinfo/error_interface.h: New file. Introduce error_service to
improve informativeness of output errors. Prototype methods to work with
error_service.
* tools/asinfo/error_interface.c: New file. Implement it.
* tools/asinfo/arch_interface.h: New file. Introduce struct
arch_descriptor. Introduce arch_service. Prototype methods to simplify
work with the arch_service.
* tools/asinfo/arch_interface.c: New file. Implement it.
* tools/asinfo/syscall_interface.h: New file. Introduce syscall_service.
Prototype methods to simplify work with syscall_service.
* tools/asinfo/syscall_interface.c: New file. Implement it.
* tools/asinfo/request_msgs.h: New file. Introduce main requests.
* tools/asinfo/asinfo.c: New file. Implement support of all options.
Implement usage. Implement version.
* tools/asinfo/arch_definitions.h: New file. Introduce useful storage
for architectures.
* tools/asinfo/arch_includes.h: New file.
* tools/asinfo/personalities.h: Likewise.
* tools/asinfo/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
Makefile.am | 2 +-
configure.ac | 2 +
tools/Makefile.am | 28 ++
tools/asinfo/.gitignore | 2 +
tools/asinfo/Makefile.am | 62 ++++
tools/asinfo/arch_definitions.h | 70 ++++
tools/asinfo/arch_includes.h | 272 +++++++++++++++
tools/asinfo/arch_interface.c | 654 ++++++++++++++++++++++++++++++++++++
tools/asinfo/arch_interface.h | 162 +++++++++
tools/asinfo/arch_personalities.h | 36 ++
tools/asinfo/asinfo.c | 331 ++++++++++++++++++
tools/asinfo/dispatchers.c | 244 ++++++++++++++
tools/asinfo/dispatchers.h | 48 +++
tools/asinfo/error_interface.c | 110 ++++++
tools/asinfo/error_interface.h | 95 ++++++
tools/asinfo/request_msgs.h | 93 ++++++
tools/asinfo/syscall_interface.c | 684 ++++++++++++++++++++++++++++++++++++++
tools/asinfo/syscall_interface.h | 142 ++++++++
18 files changed, 3036 insertions(+), 1 deletion(-)
create mode 100644 tools/Makefile.am
create mode 100644 tools/asinfo/.gitignore
create mode 100644 tools/asinfo/Makefile.am
create mode 100644 tools/asinfo/arch_definitions.h
create mode 100644 tools/asinfo/arch_includes.h
create mode 100644 tools/asinfo/arch_interface.c
create mode 100644 tools/asinfo/arch_interface.h
create mode 100644 tools/asinfo/arch_personalities.h
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/error_interface.c
create mode 100644 tools/asinfo/error_interface.h
create mode 100644 tools/asinfo/request_msgs.h
create mode 100644 tools/asinfo/syscall_interface.c
create mode 100644 tools/asinfo/syscall_interface.h
diff --git a/Makefile.am b/Makefile.am
index e90c7809..1c9c3dac 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 strace-log-merge.1
diff --git a/configure.ac b/configure.ac
index 729ef3f7..0492bd8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -904,6 +904,8 @@ AC_CONFIG_FILES([Makefile
tests-mx32/Makefile
strace.1
strace-log-merge.1
+ 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 <edg...@vi...>
+# 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/.gitignore b/tools/asinfo/.gitignore
new file mode 100644
index 00000000..09400c47
--- /dev/null
+++ b/tools/asinfo/.gitignore
@@ -0,0 +1,2 @@
+asinfo
+asinfo.1
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
new file mode 100644
index 00000000..5051766e
--- /dev/null
+++ b/tools/asinfo/Makefile.am
@@ -0,0 +1,62 @@
+# Automake input for asinfo.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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_LDFLAGS =
+asinfo_LDADD = -L$(top_srcdir) \
+ -L$(top_builddir) \
+ -lcommon
+
+asinfo_SOURCES = \
+ arch_definitions.h \
+ arch_includes.h \
+ arch_interface.c \
+ arch_interface.h \
+ arch_personalities.h \
+ asinfo.c \
+ dispatchers.c \
+ dispatchers.h \
+ error_interface.c \
+ error_interface.h \
+ request_msgs.h \
+ syscall_interface.c \
+ syscall_interface.h \
+ #end of asinfo_SOURCES
diff --git a/tools/asinfo/arch_definitions.h b/tools/asinfo/arch_definitions.h
new file mode 100644
index 00000000..37103160
--- /dev/null
+++ b/tools/asinfo/arch_definitions.h
@@ -0,0 +1,70 @@
+/* [],[bfin/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(blackfin, 32bit, PASS({}), PASS({"blackfin", "bfin"}) ),
+/* [],[ia64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ia64, 64bit, PASS({}), PASS({"ia64"}) ),
+/* [],[m68k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(m68k, 32bit, PASS({}), PASS({"m68k"}) ),
+/* [],[sparc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc64, 64bit, PASS({ARCH_sparc_32bit}), PASS({"sparc64"}) ),
+/* [],[sparc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc, 32bit, PASS({}), PASS({"sparc"}) ),
+/* [],[metag/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(metag, 32bit, PASS({}), PASS({"metag"}) ),
+/* [LINUX_MIPSN64],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n64.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n64, PASS({ARCH_mips64_n32, ARCH_mips_o32}), PASS({"mips64", "mips64le"}) ),
+/* [LINUX_MIPSN32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n32.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n32, PASS({ARCH_mips_o32}), PASS({}) ),
+/* [LINUX_MIPSO32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-o32.h],[0,0] */
+ARCH_DESC_DEFINE(mips, o32, PASS({}), PASS({"mips", "mipsle"}) ),
+/* [],[alpha/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(alpha, 64bit, PASS({}), PASS({"alpha"}) ),
+/* [],[powerpc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc64, 64bit, PASS({ARCH_ppc_32bit}), PASS({"ppc64", "ppc64le", "powerpc64"}) ),
+/* [],[powerpc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc, 32bit, PASS({}), PASS({"ppc", "ppcle", "powerpc"}) ),
+/* [],[aarch64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(aarch64, 64bit, PASS({ARCH_arm_eabi}), PASS({"aarch64", "arm64"}) ),
+/* [!__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, oabi, PASS({ARCH_arm_eabi}), PASS({"arm"}) ),
+/* [__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, eabi, PASS({}), PASS({}) ),
+/* [],[avr32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(avr32, 32bit, PASS({}), PASS({"avr32"}) ),
+/* [],[arc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(arc, 32bit, PASS({}), PASS({"arc"}) ),
+/* [],[s390x/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390x, 64bit, PASS({}), PASS({"s390x"}) ),
+/* [],[s390/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390, 32bit, PASS({}), PASS({"s390"}) ),
+/* [],[hppa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(hppa, 32bit, PASS({}), PASS({"parisc", "hppa"}) ),
+/* [],[sh64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh64, 64bit, PASS({}), PASS({"sh64"}) ),
+/* [],[sh/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh, 32bit, PASS({}), PASS({"sh"}) ),
+/* [],[x86_64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, 64bit, PASS({ARCH_x86_64_x32, ARCH_x86_32bit}), PASS({"x86_64", "amd64", "EM64T"}) ),
+/* [],[x86_64/syscallent2.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, x32, PASS({ARCH_x86_32bit}), PASS({}) ),
+/* [],[i386/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86, 32bit, PASS({}), PASS({"x86", "i386", "i486", "i586", "i686"}) ),
+/* [],[crisv10/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(cris, 32bit, PASS({}), PASS({"cris", "crisv10"}) ),
+/* [],[crisv32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(crisv32, 32bit, PASS({}), PASS({"crisv32"}) ),
+/* [],[tile/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 64bit, PASS({ARCH_tile_32bit}), PASS({"tile", "tilegx"}) ),
+/* [],[tile/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 32bit, PASS({}), PASS({"tilepro"}) ),
+/* [],[microblaze/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(microblaze, 32bit, PASS({}), PASS({"microblaze"}) ),
+/* [],[nios2/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(nios2, 32bit, PASS({}), PASS({"nios2"}) ),
+/* [],[or1k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(openrisc, 32bit, PASS({}), PASS({"openrisc", "or1k"}) ),
+/* [],[xtensa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(xtensa, 32bit, PASS({}), PASS({"xtensa"}) ),
+/* [],[riscv/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 64bit, PASS({ARCH_riscv_32bit}), PASS({"riscv"}) ),
+/* [],[riscv/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 32bit, PASS({}), PASS({}) )
diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h
new file mode 100644
index 00000000..e73a8328
--- /dev/null
+++ b/tools/asinfo/arch_includes.h
@@ -0,0 +1,272 @@
+/* ARCH_blackfin */
+static const struct_sysent blackfin_32bit_sysent[] = {
+ #include "bfin/syscallent.h"
+};
+static const int blackfin_32bit_usr1 = 0;
+const int blackfin_32bit_usr2 = 0;
+/* ARCH_ia64 */
+struct_sysent ia64_64bit_sysent[] = {
+ #include "ia64/syscallent.h"
+};
+static const int ia64_64bit_usr1 = 0;
+static const int ia64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_m68k */
+static const struct_sysent m68k_32bit_sysent[] = {
+ #include "m68k/syscallent.h"
+};
+static const int m68k_32bit_usr1 = 0;
+static const int m68k_32bit_usr2 = 0;
+/* ARCH_sparc64 64bit ABI */
+static const struct_sysent sparc64_64bit_sysent[] = {
+ #include "sparc64/syscallent.h"
+};
+static const int sparc64_64bit_usr1 = 0;
+static const int sparc64_64bit_usr2 = 0;
+/* ARCH_sparc and 32bit ABI */
+static const struct_sysent sparc_32bit_sysent[] = {
+ #include "sparc/syscallent.h"
+};
+static const int sparc_32bit_usr1 = 0;
+static const int sparc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_metag */
+static const struct_sysent metag_32bit_sysent[] = {
+ #include "metag/syscallent.h"
+};
+static const int metag_32bit_usr1 = 0;
+static const int metag_32bit_usr2 = 0;
+/* ARCH_mips n64 ABI */
+#ifndef LINUX_MIPSN64
+# define LINUX_MIPSN64 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n64_usr1 = 0;
+static const int mips64_n64_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips n32 ABI */
+#ifndef LINUX_MIPSN32
+# define LINUX_MIPSN32 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n32_usr1 = 0;
+static const int mips64_n32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips o32 ABI */
+#ifndef LINUX_MIPSO32
+# define LINUX_MIPSO32 1
+# define NOW_DEFINED 1
+#endif
+static const 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
+static const int mips_o32_usr1 = 0;
+static const int mips_o32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_alpha */
+static const struct_sysent alpha_64bit_sysent[] = {
+ #include "alpha/syscallent.h"
+};
+static const int alpha_64bit_usr1 = 0;
+static const int alpha_64bit_usr2 = 0;
+/* ARCH_ppc64 64bit ABI */
+static const struct_sysent ppc64_64bit_sysent[] = {
+ #include "powerpc64/syscallent.h"
+};
+static const int ppc64_64bit_usr1 = 0;
+static const int ppc64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_ppc and 32bit */
+static const struct_sysent ppc_32bit_sysent[] = {
+ #include "powerpc/syscallent.h"
+};
+static const int ppc_32bit_usr1 = 0;
+static const int ppc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_aarch64 64bit ABI */
+static const struct_sysent aarch64_64bit_sysent[] = {
+ #include "aarch64/syscallent.h"
+};
+static const int aarch64_64bit_usr1 = 0;
+static const int aarch64_64bit_usr2 = 0;
+/* ARCH_arm OABI*/
+#ifdef __ARM_EABI__
+# undef __ARM_EABI__
+# define NOW_UNDEFINED 1
+#endif
+static const struct_sysent arm_oabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL;
+#undef ARM_FIRST_SHUFFLED_SYSCALL
+#undef ARM_LAST_SPECIAL_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
+static const struct_sysent arm_eabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_eabi_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 */
+static const struct_sysent avr32_32bit_sysent[] = {
+ #include "avr32/syscallent.h"
+};
+static const int avr32_32bit_usr1 = 0;
+static const int avr32_32bit_usr2 = 0;
+/* ARCH_arc */
+static const struct_sysent arc_32bit_sysent[] = {
+ #include "arc/syscallent.h"
+};
+static const int arc_32bit_usr1 = 0;
+static const int arc_32bit_usr2 = 0;
+/* ARCH_s390x */
+static const struct_sysent s390x_64bit_sysent[] = {
+ #include "s390x/syscallent.h"
+};
+static const int s390x_64bit_usr1 = 0;
+static const int s390x_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_s390 */
+static const struct_sysent s390_32bit_sysent[] = {
+ #include "s390/syscallent.h"
+};
+static const int s390_32bit_usr1 = 0;
+static const int s390_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_hppa */
+static const struct_sysent hppa_32bit_sysent[] = {
+ #include "hppa/syscallent.h"
+};
+static const int hppa_32bit_usr1 = 0;
+static const int hppa_32bit_usr2 = 0;
+/* ARCH_sh64 */
+static const struct_sysent sh64_64bit_sysent[] = {
+ #include "sh64/syscallent.h"
+};
+static const int sh64_64bit_usr1 = 0;
+static const int sh64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_sh */
+static const struct_sysent sh_32bit_sysent[] = {
+ #include "sh/syscallent.h"
+};
+static const int sh_32bit_usr1 = 0;
+static const int sh_32bit_usr2 = 0;
+/* ARCH_x86_64 64bit ABI mode */
+static const struct_sysent x86_64_64bit_sysent[] = {
+ #include "x86_64/syscallent.h"
+};
+static const int x86_64_64bit_usr1 = 0;
+static const int x86_64_64bit_usr2 = 0;
+/* ARCH_x86_64 x32 ABI mode */
+static const struct_sysent x86_64_x32_sysent[] = {
+ #include "x86_64/syscallent2.h"
+};
+static const int x86_64_x32_usr1 = 0;
+static const int x86_64_x32_usr2 = 0;
+/* ARCH_x86 */
+static const struct_sysent x86_32bit_sysent[] = {
+ #include "i386/syscallent.h"
+};
+static const int x86_32bit_usr1 = 0;
+static const int x86_32bit_usr2 = 0;
+/* ARCH_cris */
+static struct_sysent cris_32bit_sysent[] = {
+ #include "crisv10/syscallent.h"
+};
+static const int cris_32bit_usr1 = 0;
+static const int cris_32bit_usr2 = 0;
+/* ARCH_crisv32 */
+static const struct_sysent crisv32_32bit_sysent[] = {
+ #include "crisv32/syscallent.h"
+};
+static const int crisv32_32bit_usr1 = 0;
+static const int crisv32_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_tile 64bit ABI mode */
+static const struct_sysent tile_64bit_sysent[] = {
+ #include "tile/syscallent.h"
+};
+static const int tile_64bit_usr1 = 0;
+static const int tile_64bit_usr2 = 0;
+/* ARCH_tile 32bit ABI mode */
+static const struct_sysent tile_32bit_sysent[] = {
+ #include "tile/syscallent1.h"
+};
+static const int tile_32bit_usr1 = 0;
+static const int tile_32bit_usr2 = 0;
+/* ARCH_microblaze */
+static const struct_sysent microblaze_32bit_sysent[] = {
+ #include "microblaze/syscallent.h"
+};
+static const int microblaze_32bit_usr1 = 0;
+static const int microblaze_32bit_usr2 = 0;
+/* ARCH_nios2 */
+static const struct_sysent nios2_32bit_sysent[] = {
+ #include "nios2/syscallent.h"
+};
+static const int nios2_32bit_usr1 = 0;
+static const int nios2_32bit_usr2 = 0;
+/* ARCH_openrisc */
+struct_sysent openrisc_32bit_sysent[] = {
+ #include "or1k/syscallent.h"
+};
+static const int openrisc_32bit_usr1 = 0;
+static const int openrisc_32bit_usr2 = 0;
+/* ARCH_xtensa */
+static const struct_sysent xtensa_32bit_sysent[] = {
+ #include "xtensa/syscallent.h"
+};
+static const int xtensa_32bit_usr1 = 0;
+static const int xtensa_32bit_usr2 = 0;
+/* ARCH_riscv 64bit ABI mode */
+static const struct_sysent riscv_64bit_sysent[] = {
+ #include "riscv/syscallent.h"
+};
+static const int riscv_64bit_usr1 = 0;
+static const int riscv_64bit_usr2 = 0;
+/* ARCH_riscv 32bit ABI mode */
+static const struct_sysent riscv_32bit_sysent[] = {
+ #include "riscv/syscallent1.h"
+};
+static const int riscv_32bit_usr1 = 0;
+static const int riscv_32bit_usr2 = 0;
diff --git a/tools/asinfo/arch_interface.c b/tools/asinfo/arch_interface.c
new file mode 100644
index 00000000..8e02ffd0
--- /dev/null
+++ b/tools/asinfo/arch_interface.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 <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. */
+#include "sysent_shorthand_defs.h"
+
+/* For the current functionality there is no need
+ to use sen and (*sys_func)() fields in sysent struct */
+#define SEN(syscall_name) 0, NULL
+
+/* Generated file based on arch_definitions.h */
+#include "arch_includes.h"
+
+/* Now undef them since short defines cause wicked namespace pollution. */
+#include "sysent_shorthand_undefs.h"
+
+#define PASS(...) __VA_ARGS__
+#define ARCH_DESC_DEFINE(arch, mode, comp_pers, arch_aliases) \
+ [ARCH_##arch##_##mode] = { \
+ .pers = ARCH_##arch##_##mode, \
+ .arch_name = arch_aliases, \
+ .abi_mode = #mode, \
+ .abi_mode_len = ARRAY_SIZE(#arch) - 1, \
+ .compat_pers = comp_pers, \
+ .max_scn = ARRAY_SIZE(arch##_##mode##_sysent), \
+ .syscall_list = arch##_##mode##_sysent, \
+ .user_num1 = &arch##_##mode##_usr1, \
+ .user_num2 = &arch##_##mode##_usr2, \
+ }
+
+/* Generate array of arch_descriptors for each personality */
+const struct arch_descriptor architectures[] = {
+ #include "arch_definitions.h"
+};
+
+#undef ARCH_DESC_DEFINE
+#undef PASS
+
+struct arch_service *
+al_create(unsigned capacity)
+{
+ ARCH_LIST_DEFINE(as) = NULL;
+
+ if (!capacity)
+ return NULL;
+ as = xcalloc(sizeof(*as), 1);
+ as->arch_list = xcalloc(sizeof(*(as->arch_list)), capacity);
+ as->flag = xcalloc(sizeof(*(as->flag)), capacity);
+ as->in_aname = xcalloc(sizeof(*(as->in_aname)), capacity);
+ as->err = es_create();
+ as->capacity = capacity;
+ as->next_free = 0;
+ return as;
+}
+
+int
+al_push(struct arch_service *m, const struct arch_descriptor *element)
+{
+ if (m->next_free >= m->capacity)
+ return -1;
+ m->arch_list[m->next_free] = element;
+ m->flag[m->next_free] = AD_FLAG_EMPTY;
+ 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->flag[index] = flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_add_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] | flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_sub_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] & ~flag;
+ return 0;
+ }
+ return -1;
+}
+
+const 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;
+}
+
+void
+al_free(struct arch_service *m)
+{
+ int i;
+ int size = al_size(m);
+
+ for (i = 0; i < size; i++)
+ if (al_in_aname(m, i) != NULL)
+ free(al_in_aname(m, i));
+ free(m->arch_list);
+ free(m->flag);
+ free(m->in_aname);
+ es_free(m->err);
+ free(m);
+}
+
+struct error_service *al_err(struct arch_service *m)
+{
+ return m->err;
+}
+
+enum arch_pers
+al_pers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->pers : ARCH_no_pers);
+}
+
+const char **
+al_arch_name(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (const char **)elem->arch_name : NULL);
+}
+
+enum arch_pers *
+al_cpers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (enum arch_pers *)elem->compat_pers : NULL);
+}
+
+const char *
+al_abi_mode(struct arch_service *m, unsigned index)
+{
+ const 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)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->abi_mode_len : -1);
+}
+
+int
+al_flag(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->flag[index] : -1);
+}
+
+int
+al_set_in_aname(struct arch_service *m, unsigned index, char *aname)
+{
+ int status = al_is_index_ok(m, index);
+
+ if (status)
+ return -1;
+ m->in_aname[index] = aname;
+ return 0;
+}
+
+char *
+al_in_aname(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->in_aname[index] : NULL);
+}
+
+int
+al_psize(struct arch_service *m)
+{
+ int i;
+ int a_size = al_size(m);
+ int psize = 0;
+
+ for (i = 0; i < a_size; i++)
+ if (al_flag(m, i) & AD_FLAG_PRINT)
+ psize++;
+ return psize;
+}
+
+int
+al_arch_name_len(struct arch_service *m, unsigned index, int delim_len)
+{
+ const char **arch_name = NULL;
+ int i;
+ int final_len = 0;
+
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ for (i = 0; (arch_name[i] != NULL) && (i < MAX_ALIASES); i++) {
+ final_len += strlen(arch_name[i]);
+ final_len += delim_len;
+ }
+ final_len -= delim_len;
+ return final_len;
+}
+
+int
+al_syscall_impl(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name &&
+ !(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ count++;
+ }
+ return count;
+}
+
+/* This method is purposed to count the supported ABI modes for the given
+ arch */
+int
+al_get_abi_modes(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+ int i = 0;
+ int abi_count = 1;
+
+ if (!elem)
+ return -1;
+ for (i = 0; i < MAX_ALT_ABIS; i++)
+ if (elem->compat_pers[i] != ARCH_no_pers)
+ abi_count++;
+ return abi_count;
+}
+
+/* This method is purposed to find next one name of the same architecture.
+ For instance, x86_64 = amd64 */
+const char *
+al_next_alias(struct arch_service *m, unsigned index)
+{
+ static int next_alias = -1;
+ static const char **arch_name = NULL;
+ static unsigned lindex = 0;
+
+ if (lindex != index) {
+ lindex = index;
+ next_alias = -1;
+ }
+ if (al_pers(m, index) == ARCH_no_pers)
+ return NULL;
+ if (next_alias == -1) {
+ next_alias = 0;
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ } else
+ next_alias++;
+ if (next_alias >= MAX_ALIASES || arch_name[next_alias] == NULL) {
+ next_alias = -1;
+ return NULL;
+ }
+ return arch_name[next_alias];
+}
+
+/* This method is purposed to return next one compat personality of the
+ same architecture */
+enum arch_pers
+al_next_cpers(struct arch_service *m, unsigned index)
+{
+ static int next_pers = -1;
+ enum arch_pers *a_pers = al_cpers(m, index);
+ static unsigned lindex = 0;
+
+ if (al_pers(m, index) == ARCH_no_pers)
+ return ARCH_no_pers;
+ if (lindex != index) {
+ lindex = index;
+ next_pers = -1;
+ }
+ if (next_pers == -1)
+ next_pers = 0;
+ else
+ next_pers++;
+ if (next_pers >= MAX_ALT_ABIS ||
+ a_pers[next_pers] == ARCH_no_pers) {
+ next_pers = -1;
+ return ARCH_no_pers;
+ }
+ return a_pers[next_pers];
+}
+
+enum impl_type
+al_ipc_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just semop sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "semop")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+enum impl_type
+al_sck_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just socket sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "socket")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+/* This method is purposed to create extended list of architectures */
+struct arch_service *
+al_create_filled(void)
+{
+ static const int architectures_size = ARRAY_SIZE(architectures) - 1;
+ ARCH_LIST_DEFINE(as) = al_create(architectures_size);
+ ARCH_LIST_DEFINE(f_as);
+ enum arch_pers cpers;
+ int esize = 0;
+ const char **arch_name = NULL;
+ int i;
+
+ /* Push and calculate size of extended table */
+ for (i = 0; i < architectures_size; i++) {
+ al_push(as, &(architectures[i + 1]));
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] != NULL)
+ esize += al_get_abi_modes(as, i);
+ }
+ f_as = al_create(esize);
+ /* Fill extended teble */
+ for (i = 0; i < architectures_size; i++) {
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] == NULL)
+ continue;
+ al_push(f_as, al_get(as, i));
+ al_add_flag(f_as, al_size(f_as) - 1, AD_FLAG_MPERS);
+ while ((cpers = al_next_cpers(as, i)) != ARCH_no_pers)
+ al_push(f_as, &(architectures[cpers]));
+ }
+ free(as);
+ return f_as;
+}
+
+/* To look up arch in arch_descriptor array */
+int
+al_mark_matches(struct arch_service *m, char *arch_str)
+{
+ int arch_match = -1;
+ char *match_pointer = NULL;
+ const char *a_name = NULL;
+ int al_size_full = al_size(m);
+ unsigned prev_arch_len = 0;
+ int i;
+ int a_abi;
+ char *in_aname;
+
+ if (arch_str == NULL)
+ return -1;
+ /* Here we find the best match for arch_str in architecture list.
+ Best match means here that we have to find the longest name of
+ architecture in a_full_list with arch_str substring, beginning
+ from the first letter */
+ for (i = 0; i < al_size_full; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_MPERS))
+ continue;
+ while ((a_name = al_next_alias(m, i)) != NULL) {
+ match_pointer = strstr(arch_str, a_name);
+ if (match_pointer == NULL || match_pointer != arch_str)
+ continue;
+ if (arch_match == -1 ||
+ strlen(a_name) > prev_arch_len) {
+ prev_arch_len = strlen(a_name);
+ arch_match = i;
+ }
+ }
+ }
+ if (arch_match == -1)
+ return -1;
+ /* Now we find all ABI modes related to the architecture */
+ if ((a_abi = al_get_abi_modes(m, arch_match)) == -1)
+ return -1;
+ for (i = arch_match; i < (arch_match + a_abi); i++) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ in_aname = xcalloc(sizeof(*in_aname), strlen(arch_str) + 1);
+ strcpy(in_aname, arch_str);
+ al_set_in_aname(m, i, in_aname);
+ }
+ return 0;
+}
+
+/* Join all architectures from 'f' and architectures with AD_FLAG_PRINT
+ from 's' arch_service structures */
+struct arch_service *
+al_join_print(struct arch_service *f, struct arch_service *s)
+{
+ int size1 = (f ? al_size(f) : 0);
+ int psize2 = al_psize(s);
+ int size2 = al_size(s);
+ int i;
+ int start_point = 0;
+ ARCH_LIST_DEFINE(final) = al_create(size1 + psize2);
+
+ for (i = 0; i < size2; i++)
+ if (al_flag(s, i) & AD_FLAG_PRINT) {
+ start_point = i;
+ break;
+ }
+ for (i = 0; i < size1; i++) {
+ al_push(final, al_get(f, i));
+ al_set_flag(final, i, al_flag(f, i));
+ al_set_in_aname(final, i, al_in_aname(f, i));
+ al_set_in_aname(f, i, NULL);
+ }
+ for (i = 0; i < psize2; i++) {
+ al_push(final, al_get(s, start_point + i));
+ al_set_flag(final, size1 + i , al_flag(s, start_point + i));
+ al_set_in_aname(final, size1 + i,
+ al_in_aname(s, start_point + i));
+ al_set_in_aname(s, start_point + i, NULL);
+ al_sub_flag(s, start_point + i, AD_FLAG_PRINT);
+ }
+ if (f)
+ al_free(f);
+ return final;
+}
+
+/* To avoid duplication of for(;;) construction */
+void
+al_unmark_all(struct arch_service *m, int flag)
+{
+ int a_size = al_size(m);
+ int i;
+
+ for (i = 0; i < a_size; i++)
+ al_sub_flag(m, i, flag);
+}
+
+/* Select one compatible personality in range of one architecture */
+int
+al_mark_pers4arch(struct arch_service *m, unsigned index, const char *abi_mode)
+{
+ unsigned i = index;
+
+ while (!(al_flag(m, i) & AD_FLAG_MPERS) || (i == index)) {
+ if (strcmp(abi_mode, "all") == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ i++;
+ if ((al_is_index_ok(m, i)) ||
+ (al_flag(m, i) & AD_FLAG_MPERS))
+ return 0;
+ else
+ continue;
+ }
+ if (strcmp(al_abi_mode(m, i), abi_mode) == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ return 0;
+ }
+ i++;
+ }
+ return -1;
+}
+
+void
+al_dump(struct arch_service *m, int is_raw)
+{
+ static const char *title[] = {
+ "N",
+ "Architecture name",
+ "ABI mode",
+ /* Implemented syscalls */
+ "IMPL syscalls",
+ /* IPC implementation */
+ "IPC IMPL",
+ /* SOCKET implementation */
+ "SOCKET IMPL"
+ };
+ int title_len[] = {
+ 0,
+ strlen(title[1]),
+ strlen(title[2]),
+ strlen(title[3]),
+ strlen(title[4]),
+ strlen(title[5]),
+ };
+ static const char *impl_st[] = {
+ "external",
+ "internal",
+ "int/ext"
+ };
+ static const char *delim = "/";
+ int i = 0;
+ int N = 0;
+ int temp_len = 0;
+ int arch_size = al_size(m);
+ int arch_psize = al_psize(m);
+ const char *next_alias = NULL;
+ char *whole_arch_name;
+
+ /* Calculate length of the column with the number of architectures */
+ for (i = 1; arch_psize/i != 0; i *= 10)
+ title_len[0]++;
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ /* Calculate length of the column with the
+ architectures name */
+ temp_len = al_arch_name_len(m, i, strlen(delim));
+ if (temp_len > title_len[1])
+ title_len[1] = temp_len;
+ /* Calculate length of the column with the ABI mode */
+ if (al_abi_mode_len(m, i) > title_len[2])
+ title_len[2] = al_abi_mode_len(m, i);
+ }
+
+ whole_arch_name = xcalloc(title_len[1], sizeof(*whole_arch_name));
+ /* Output title */
+ if (!is_raw)
+ printf("| %*s | %*s | %*s | %*s | %*s | %*s |\n",
+ title_len[0], title[0], title_len[1], title[1],
+ title_len[2], title[2], title_len[3], title[3],
+ title_len[4], title[4], title_len[5], title[5]);
+ /* Output architectures */
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ N++;
+ memset(whole_arch_name, 0, title_len[1]);
+ /* Put all the same arch back together */
+ next_alias = al_next_alias(m, i);
+ strcat(whole_arch_name, next_alias);
+ while ((next_alias = al_next_alias(m, i)) != NULL) {
+ strcat(whole_arch_name, delim);
+ strcat(whole_arch_name, next_alias);
+ }
+ if (is_raw) {
+ printf("%u;%s;%s;%d;%s;%s;\n", N, whole_arch_name,
+ al_abi_mode(m, i), al_syscall_impl(m, i),
+ impl_st[al_ipc_syscall(m, i)],
+ impl_st[al_ipc_syscall(m, i)]);
+ continue;
+ }
+ printf("| %*u | ", title_len[0], N);
+ printf("%*s | ", title_len[1], whole_arch_name);
+ printf("%*s | ", title_len[2], al_abi_mode(m, i));
+ printf("%*d | ", title_len[3], al_syscall_impl(m, i));
+ printf("%*s | ", title_len[4], impl_st[al_ipc_syscall(m, i)]);
+ printf("%*s |\n", title_len[5], impl_st[al_sck_syscall(m, i)]);
+ }
+ free(whole_arch_name);
+}
diff --git a/tools/asinfo/arch_interface.h b/tools/asinfo/arch_interface.h
new file mode 100644
index 00000000..1e7123fc
--- /dev/null
+++ b/tools/asinfo/arch_interface.h
@@ -0,0 +1,162 @@
+/*
+ * 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 <edg...@vi...>
+ * 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_H
+#define ASINFO_ARCH_INTERFACE_H
+
+#include "error_interface.h"
+#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 personalities
+ * arch_pers = ARCH_ + kernel_kernel/other_name + abi_mode */
+enum arch_pers {
+ #include "arch_personalities.h"
+};
+
+#define MAX_ALIASES 6
+#define MAX_ALT_ABIS 3
+
+struct arch_descriptor {
+ enum arch_pers pers;
+ const char *arch_name[MAX_ALIASES];
+ const char *abi_mode;
+ const int abi_mode_len;
+ enum arch_pers compat_pers[MAX_ALT_ABIS];
+ const int max_scn;
+ const struct_sysent *syscall_list;
+ /* In the most cases these fields are purposed to store specific for
+ given arch constants, for instance, ARM_FIRST_SHUFFLED_SYSCALL */
+ const int *user_num1;
+ const int *user_num2;
+};
+
+#define AD_FLAG_EMPTY 0
+/* to hide some abi modes belonging to one architecture */
+#define AD_FLAG_PRINT (1 << 0)
+/* main personality, like x86_64 64bit */
+#define AD_FLAG_MPERS (1 << 1)
+
+/* To provide push-back interface with arch_list */
+struct arch_service {
+ /* immutable field */
+ const struct arch_descriptor **arch_list;
+ /* User flags for each arch_descriptor */
+ int *flag;
+ /* To support conformity between ABI and ARCH */
+ char **in_aname;
+ struct error_service *err;
+ 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 capacity);
+
+int al_push(struct arch_service *m, const struct arch_descriptor *element);
+
+int al_set_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_add_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_sub_flag(struct arch_service *m, unsigned index, int flag);
+
+const struct arch_descriptor *al_get(struct arch_service *m, unsigned index);
+
+unsigned int al_size(struct arch_service *m);
+
+void al_free(struct arch_service *m);
+
+struct error_service *al_err(struct arch_service *m);
+
+/* methods returning fields with error check */
+enum arch_pers al_pers(struct arch_service *m, unsigned index);
+
+const char **al_arch_name(struct arch_service *m, unsigned index);
+
+enum arch_pers *al_cpers(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);
+
+int al_set_in_aname(struct arch_service *m, unsigned index, char *aname);
+
+char *al_in_aname(struct arch_service *m, unsigned index);
+
+/* calculating methods */
+int al_psize(struct arch_service *m);
+
+int al_arch_name_len(struct arch_service *m, unsigned index, int delim_len);
+
+int al_syscall_impl(struct arch_service *m, unsigned index);
+
+int al_get_abi_modes(struct arch_service *m, unsigned index);
+
+const char *al_next_alias(struct arch_service *m, unsigned index);
+
+enum arch_pers al_next_cpers(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);
+
+struct arch_service *al_create_filled(void);
+
+int al_mark_matches(struct arch_service *m, char *arch_str);
+
+struct arch_service *al_join_print(struct arch_service *f,
+ struct arch_service *s);
+
+void al_unmark_all(struct arch_service *m, int flag);
+
+int al_mark_pers4arch(struct arch_service *m, unsigned index,
+ const char *abi_mode);
+
+void al_dump(struct arch_service *m, int is_raw);
+
+#endif /* !ASINFO_ARCH_INTERFACE_H */
diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h
new file mode 100644
index 00000000..9499c5aa
--- /dev/null
+++ b/tools/asinfo/arch_personalities.h
@@ -0,0 +1,36 @@
+ARCH_no_pers,
+ARCH_blackfin_32bit,
+ARCH_ia64_64bit,
+ARCH_m68k_32bit,
+ARCH_sparc64_64bit,
+ARCH_sparc_32bit,
+ARCH_metag_32bit,
+ARCH_mips64_n64,
+ARCH_mips64_n32,
+ARCH_mips_o32,
+ARCH_alpha_64bit,
+ARCH_ppc64_64bit,
+ARCH_ppc_32bit,
+ARCH_aarch64_64bit,
+ARCH_arm_oabi,
+ARCH_arm_eabi,
+ARCH_avr32_32bit,
+ARCH_arc_32bit,
+ARCH_s390x_64bit,
+ARCH_s390_32bit,
+ARCH_hppa_32bit,
+ARCH_sh64_64bit,
+ARCH_sh_32bit,
+ARCH_x86_64_64bit,
+ARCH_x86_64_x32,
+ARCH_x86_32bit,
+ARCH_cris_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
diff --git a/tools/asinfo/asinfo.c b/tools/asinfo/asinfo.c
new file mode 100644
index 00000000..9b1ac9e5
--- /dev/null
+++ b/tools/asinfo/asinfo.c
@@ -0,0 +1,331 @@
+/*
+ * 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 <edg...@vi...>
+ * 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 <ctype.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_interface.h"
+#include "error_prints.h"
+#include "macros.h"
+#include "request_msgs.h"
+#include "syscall_interface.h"
+#include "xmalloc.h"
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
+
+static void
+usage(void)
+{
+ puts(
+ "usage: asinfo (--set-arch arch | --get-arch | --list-arch)\n"
+ " [--set-abi abi | --list-abi] [--raw]\n"
+ " or: asinfo [(--set-arch arch | --get-arch) [--set-abi abi | --list-abi]]\n"
+ " ((--get-sname expr | --get-snum expr) [--nargs]) [--raw]\n"
+ "\n"
+ "Architecture:\n"
+ " --set-arch arch use architecture ARCH for further work\n"
+ " argument format: arch1,arch2,...\n"
+ " --get-arch use architecture returned by uname for further work\n"
+ " --list-arch print out all architectures supported by strace\n"
+ " (combined use list-arch and any ABI option is permitted)\n"
+ "\n"
+ "ABI:\n"
+ " --set-abi abi use application binary interface ABI for further work\n"
+ " ('all' can be used as ABI to use all compatible personalities\n"
+ " for corresponding architecture)\n"
+ " argument format: abi1,abi2,...\n"
+ " --list-abi use all ABIs for specified architecture\n"
+ "\n"
+ "System call:\n"
+ " --get-sname expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall name | snum1 | snum2 | ...\n"
+ " --get-snum expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall number | sname1 | sname2 | ...\n"
+ " --nargs change output format as follows:\n"
+ " | N | syscall name or number | nargs1 | sname2 | ...\n"
+ "\n"
+ "Output formatting:\n"
+ " --raw reset alignment and remove titles, use ';' as a delimiter\n"
+ "\n"
+ "Miscellaneous:\n"
+ " -h print help message\n"
+ " -v print version");
+ exit(0);
+}
+
+static void
+print_version(void)
+{
+ printf("asinfo (%s package) -- version %s\n"
+ "Copyright (c) 1991-%s The strace developers <%s>.\n"
+ "This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+ PACKAGE_NAME, PACKAGE_VERSION, COPYRIGHT_YEAR, PACKAGE_URL);
+ exit(0);
+}
+
+void
+die(void)
+{
+ exit(1);
+}
+
+static int
+is_more1bit(unsigned int num)
+{
+ return !(num & (num - 1));
+}
+
+static unsigned
+strpar2req(char *option)
+{
+ /* Convertion table to store string with options */
+ static const char *options[] = {
+ [SD_REQ_GET_SNAME_BIT] = "--get-sname",
+ [SD_REQ_GET_SNUM_BIT] = "--get-snum",
+ [SD_REQ_NARGS_BIT] = "--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_BIT] = "--set-abi",
+ [ABD_REQ_LIST_ABI_BIT] = "--list-abi",
+ [SERV_REQ_RAW_BIT] = "--raw",
+ [SERV_REQ_HELP_BIT] = "-h",
+ [SERV_REQ_VERSION_BIT] = "-v"
+ };
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(options); i++) {
+ if (options[i] && strcmp(option, options[i]) == 0)
+ return i;
+ }
+ return SERV_REQ_ERROR_BIT;
+}
+
+static char **
+arg2list(char *argument)
+{
+ int i;
+ int len = strlen(argument);
+ int occur = 1;
+ char **arg_list;
+
+ for (i = 0; i < len; i++) {
+ if (argument[i] == ',') {
+ if (i == 0 || i == len - 1 || argument[i + 1] == ',')
+ return NULL;
+ occur++;
+ }
+ }
+ arg_list = xcalloc(sizeof(*arg_list), occur + 1);
+ for (i = 0; i < occur; i++) {
+ arg_list[i] = argument;
+ argument = strchr(argument, ',');
+ if (argument) {
+ *argument = '\0';
+ argument++;
+ }
+ }
+ return arg_list;
+}
+
+/* The purpose of this function is to convert input parameters to number with
+ set bits, where each bit means specific work mode. Moreover, it checks input
+ for correctness and outputs error messages in case of wrong input */
+static unsigned
+command_dispatcher(int argc, char *argv[], char **args[])
+{
+ int i;
+ unsigned final_req = 0;
+ unsigned temp_req = 0;
+ int mult_arch = 0;
+ int mult_abi = 0;
+ unsigned non_req_arg = AD_REQ_GET_ARCH | AD_REQ_LIST_ARCH |
+ ABD_REQ_LIST_ABI | SD_REQ_NARGS |
+ SERV_REQ_RAW;
+
+ if (!program_invocation_name || !*program_invocation_name) {
+ static char name[] = "asinfo";
+ program_invocation_name =
+ (argv[0] && *argv[0]) ? argv[0] : name;
+ }
+
+ /* Try to find help or version parameter first */
+ for (i = 1; i < argc; i++) {
+ if (strpar2req(argv[i]) == SERV_REQ_HELP_BIT)
+ usage();
+ if (strpar2req(argv[i]) == SERV_REQ_VERSION_BIT)
+ print_version();
+ }
+ /* For now, is is necessary to convert string parameter to number of
+ request and make basic check */
+ for (i = 1; i < argc; i++) {
+ if ((temp_req = strpar2req(argv[i])) == SERV_REQ_ERROR_BIT)
+ error_msg_and_help("unrecognized option '%s'",
+ argv[i]);
+ if (final_req & 1 << temp_req)
+ error_msg_and_help("parameter '%s' has been used "
+ "more than once", argv[i]);
+ if (!((1 << temp_req) & non_req_arg) &&
+ (i + 1 >= argc || strlen(argv[i + 1]) == 0 ||
+ strpar2req(argv[i + 1]) != SERV_REQ_ERROR_BIT))
+ error_msg_and_help("parameter '%s' requires "
+ "argument", argv[i]);
+ final_req |= 1 << temp_req;
+ if (!((1 << temp_req) & non_req_arg)) {
+ if ((1 << temp_req) & SD_REQ_MASK) {
+ args[temp_req] = &argv[i + 1];
+ i++;
+ continue;
+ }
+ if ((args[temp_req] = arg2list(argv[i + 1])) != NULL) {
+ i++;
+ continue;
+ }
+ error_msg_and_help("argument '%s' of '%s' parameter "
+ "has a wrong format",
+ argv[i + 1], argv[i]);
+ }
+ }
+ /* Count our multuarchness */
+ if (args[AD_REQ_SET_ARCH_BIT])
+ while (args[AD_REQ_SET_ARCH_BIT][mult_arch] != NULL)
+ mult_arch++;
+ if (args[ABD_REQ_SET_ABI_BIT])
+ while (args[ABD_REQ_SET_ABI_BIT][mult_abi] != NULL)
+ mult_abi++;
+ /* final_req should be logically checked */
+ /* More than one option from one request group couldn't be set */
+ if ((is_more1bit(final_req & SD_REQ_MASK & ~SD_REQ_NARGS) == 0) ||
+ (is_more1bit(final_req & AD_REQ_MASK) == 0) ||
+ (is_more1bit(final_req & ABD_REQ_MASK) == 0))
+ error_msg_and_help("exclusive parameters");
+ /* Check on mutually exclusive options chain */
+ /* If at least one syscall option has been typed, therefore
+ arch_options couldn't be list-arch and
+ abi_option couldn't be list-abi */
+ if ((final_req & SD_REQ_MASK) &&
+ (((final_req & AD_REQ_MASK) && (final_req & AD_REQ_LIST_ARCH))))
+ error_msg_and_help("wrong parameters");
+ /* list-arch couldn't be used with any abi options */
+ if ((final_req & AD_REQ_LIST_ARCH) &&
+ (final_req & ABD_REQ_MASK))
+ error_msg_and_help("'--list-arch' cannot be used with any "
+ "ABI parameters");
+ /* ABI requests could be used just in a combination with arch
+ requests */
+ if ((final_req & ABD_REQ_MASK) &&
+ !(final_req & AD_REQ_MASK))
+ error_msg_and_help("ABI parameters could be used only with "
+ "architecture parameter");
+ /* set-abi must be used in case of multiple arch */
+ if ((mult_arch > 1) && !(final_req & ABD_REQ_MASK))
+ error_msg_and_help("ABI modes cannot be automatically "
+ "detected for multiple "
+ "architectures");
+ /* set-abi and set-arch have to take the same number of args */
+ if ((final_req & AD_REQ_SET_ARCH) && (final_req & ABD_REQ_SET_ABI) &&
+ (mult_arch != mult_abi))
+ error_msg_and_help("each architecture needs respective "
+ "ABI mode, and vice versa");
+ /* --nargs cannot be used alone */
+ if ((final_req & SD_REQ_NARGS) &&
+ !(final_req & SD_REQ_MASK & ~SD_REQ_NARGS))
+ error_msg_and_help("first set main output syscall "
+ "characteristics");
+ /* raw should not be single */
+ if (final_req == SERV_REQ_RAW)
+ error_msg_and_help("raw data implies existing data");
+ return final_req;
+}
+
+static char *
+seek_sc_arg(char **input_args[])
+{
+ int i;
+
+ for (i = SD_REQ_GET_SNAME_BIT; i < SYSCALL_REQ_BIT_LAST; i++)
+ if (input_args[i] != NULL)
+ return input_args[i][0];
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ ARCH_LIST_DEFINE(arch_list);
+ SYSCALL_LIST_DEFINE(sc_list);
+ /* This array is purposed to store arguments for options in the
+ most convenient way */
+ char ***in_args = xcalloc(sizeof(*in_args), REQ_LAST_BIT);
+ unsigned reqs;
+
+ /* command_dispatcher turn */
+ reqs = command_dispatcher(argc, argv, in_args);
+ if (reqs == 0)
+ error_msg_and_help("must have OPTIONS");
+
+ /* arch_dispatcher turn */
+ arch_list = arch_dispatcher(reqs, in_args[AD_REQ_SET_ARCH_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* abi_dispatcher turn */
+ abi_dispatcher(arch_list, reqs, in_args[ABD_REQ_SET_ABI_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* syscall_dispatcher turn */
+ sc_list = syscall_dispatcher(arch_list, reqs, seek_sc_arg(in_args));
+ if (es_error(ss_err(sc_list)))
+ perror_msg_and_die("%s", es_get_serror(ss_err(sc_list)));
+ /* If we want to get info about only architectures thus we print out
+ architectures, otherwise system calls */
+ if (!(reqs & SD_REQ_MASK))
+ al_dump(arch_list, reqs & SERV_REQ_RAW);
+ else
+ ss_dump(sc_list, reqs & SERV_REQ_RAW);
+ return 0;
+}
diff --git a/tools/asinfo/dispatchers.c b/tools/asinfo/dispatchers.c
new file mode 100644
index 00000000..ec0f20f9
--- /dev/null
+++ b/tools/asinfo/dispatchers.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 "syscall_interface.h"
+#include "sysent.h"
+#include "xmalloc.h"
+
+struct arch_service *
+arch_dispatcher(unsigned request_type, char *arch[])
+{
+ struct utsname info_uname;
+ int i;
+ ARCH_LIST_DEFINE(arch_list) = al_create_filled();
+ ARCH_LIST_DEFINE(arch_final) = NULL;
+
+ /* If user don't type any option in ARCH_REQ group, it means
+ get current arch */
+ if ((request_type & AD_REQ_GET_ARCH) ||
+ (!(request_type & AD_REQ_MASK))) {
+ uname(&info_uname);
+ if (al_mark_matches(arch_list, info_uname.machine) == -1) {
+ es_set_error(al_err(arch_list), AD_UNSUP_ARCH);
+ es_set_option(al_err(arch_list), info_uname.machine,
+ NULL, NULL);
+ goto fail;
+ }
+ /* Cut off useless archs */
+ arch_final = al_join_print(arch_final, arch_list);
+ al_unmark_all(arch_final, AD_FLAG_P...
[truncated message content] |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:42
|
As asinfo requires some strace source files to work, it is neccessary to group them into separate static library. * Makefile.am (strace_SOURCES): Delete basic_filters.c, error_prints.c, error_prints.h, filter.h, macros.h, number_set.c, number_set.h, string_to_uint.h, string_to_uint.c, sysent_shorthand_defs.h, sysent_shorthand_undefs, xmalloc.c and xmalloc.h. (libcommon_SOURCES): Add them. (strace_LDADD): Add libcommon.a. (noinst_LIBRARIES): Likewise. * .gitignore: Add libcommon.a. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- .gitignore | 1 + Makefile.am | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 94a0be39..30938836 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ /ioctlent[012].h /ioctls_all[012].h /ioctlsort[012] +/libcommon.a /libmpers-m32.a /libmpers-mx32.a /libstrace.a diff --git a/Makefile.am b/Makefile.am index c04125ec..e90c7809 100644 --- a/Makefile.am +++ b/Makefile.am @@ -83,12 +83,31 @@ libstrace_a_SOURCES = \ upoke.c \ # end of libstrace_a_SOURCES +strace_LDADD += libcommon.a +noinst_LIBRARIES += libcommon.a +libcommon_a_CPPFLAGS = $(strace_CPPFLAGS) +libcommon_a_CFLAGS = $(strace_CFLAGS) +libcommon_a_SOURCES = \ + basic_filters.c \ + error_prints.c \ + error_prints.h \ + filter.h \ + macros.h \ + number_set.c \ + number_set.h \ + string_to_uint.h \ + string_to_uint.c \ + sysent_shorthand_defs.h \ + sysent_shorthand_undefs.h \ + xmalloc.c \ + xmalloc.h \ + #end of libcommon_a_SOURCES + strace_SOURCES = \ access.c \ affinity.c \ aio.c \ alpha.c \ - basic_filters.c \ bind.c \ bjm.c \ block.c \ @@ -116,8 +135,6 @@ strace_SOURCES = \ dyxlat.c \ empty.h \ epoll.c \ - error_prints.c \ - error_prints.h \ evdev.c \ eventfd.c \ execve.c \ @@ -137,7 +154,6 @@ strace_SOURCES = \ file_handle.c \ file_ioctl.c \ filter_qualify.c \ - filter.h \ flock.c \ flock.h \ fs_x_ioctl.c \ @@ -176,7 +192,6 @@ strace_SOURCES = \ lookup_dcookie.c \ loop.c \ lseek.c \ - macros.h \ mem.c \ membarrier.c \ memfd_create.c \ @@ -210,8 +225,6 @@ strace_SOURCES = \ nsfs.h \ nsig.h \ numa.c \ - number_set.c \ - number_set.h \ oldstat.c \ open.c \ or1k_atomic.c \ @@ -291,15 +304,11 @@ strace_SOURCES = \ statx.c \ statx.h \ strace.c \ - string_to_uint.h \ - string_to_uint.c \ supported_personalities.h \ swapon.c \ syscall.c \ sysctl.c \ sysent.h \ - sysent_shorthand_defs.h \ - sysent_shorthand_undefs.h \ sysinfo.c \ syslog.c \ sysmips.c \ @@ -324,8 +333,6 @@ strace_SOURCES = \ xattr.c \ xlat.c \ xlat.h \ - xmalloc.c \ - xmalloc.h \ # end of strace_SOURCES if USE_LIBUNWIND -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:41
|
From: Masatake YAMATO <ya...@re...> * tests/ioctl_kvm_run.c: New file. * tests/ioctl_kvm_run.test: New test. * tests/Makefile.am (DECODER_TESTS): Add ioctl_kvm_run.test. * tests/pure_executables.list: Add ioctl_kvm_run. * tests/.gitignore: Likewise. Co-authored-by: Dmitry V. Levin <ld...@al...> --- tests/.gitignore | 1 + tests/Makefile.am | 1 + tests/ioctl_kvm_run.c | 220 ++++++++++++++++++++++++++++++++++++++++++++ tests/ioctl_kvm_run.test | 11 +++ tests/pure_executables.list | 1 + 5 files changed, 234 insertions(+) create mode 100644 tests/ioctl_kvm_run.c create mode 100755 tests/ioctl_kvm_run.test diff --git a/tests/.gitignore b/tests/.gitignore index 93c980fa..7838a5b0 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -128,6 +128,7 @@ ioctl_dm ioctl_dm-v ioctl_evdev ioctl_evdev-v +ioctl_kvm_run ioctl_loop ioctl_loop-nv ioctl_loop-v diff --git a/tests/Makefile.am b/tests/Makefile.am index 7bc2872f..22a39d75 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -206,6 +206,7 @@ DECODER_TESTS = \ ioctl.test \ ioctl_dm-v.test \ ioctl_dm.test \ + ioctl_kvm_run.test \ ioctl_loop-nv.test \ ioctl_nsfs.test \ ioctl_sock_gifconf.test \ diff --git a/tests/ioctl_kvm_run.c b/tests/ioctl_kvm_run.c new file mode 100644 index 00000000..51229511 --- /dev/null +++ b/tests/ioctl_kvm_run.c @@ -0,0 +1,220 @@ +/* + * Check decoding of KVM_* commands of ioctl syscall using /dev/kvm API. + * Based on kvmtest.c from https://lwn.net/Articles/658512/ + * + * kvmtest.c author: Josh Triplett <jo...@jo...> + * Copyright (c) 2015 Intel Corporation + * Copyright (c) 2017 The strace developers. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "tests.h" + +#if defined HAVE_LINUX_KVM_H \ + && defined HAVE_STRUCT_KVM_REGS \ + && defined HAVE_STRUCT_KVM_SREGS \ + && defined HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION \ + &&(defined __x86_64__ || defined __i386__) + +# include <fcntl.h> +# include <stdint.h> +# include <stdio.h> +# include <stdlib.h> +# include <string.h> +# include <sys/ioctl.h> +# include <sys/mman.h> +# include <linux/kvm.h> + +static int +kvm_ioctl(int fd, unsigned long cmd, const char *cmd_str, void *arg) +{ + int rc = ioctl(fd, cmd, arg); + if (rc < 0) + perror_msg_and_skip("%s", cmd_str); + return rc; +} + +#define KVM_IOCTL(fd_, cmd_, arg_) \ + kvm_ioctl((fd_), (cmd_), #cmd_, (arg_)) + +static const char dev[] = "/dev/kvm"; +static const char vm_dev[] = "anon_inode:kvm-vm"; +static const char vcpu_dev[] = "anon_inode:kvm-vcpu"; +static size_t page_size; + +static void +code(void) +{ + __asm__("mov $0xd80003f8, %edx; mov $'\n', %al; out %al, (%dx); hlt"); +} + +static void +run_kvm(const int vcpu_fd, struct kvm_run *const run, const size_t mmap_size, + void *const mem) +{ + /* Initialize CS to point at 0, via a read-modify-write of sregs. */ + struct kvm_sregs sregs; + KVM_IOCTL(vcpu_fd, KVM_GET_SREGS, &sregs); + printf("ioctl(%d<%s>, KVM_GET_SREGS, {cs={base=%#jx, limit=%u, selector=%u" + ", type=%u, present=%u, dpl=%u, db=%u, s=%u, l=%u, g=%u, avl=%u}" + ", ...}) = 0\n", vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base, + sregs.cs.limit, sregs.cs.selector, sregs.cs.type, + sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s, + sregs.cs.l, sregs.cs.g, sregs.cs.avl); + + sregs.cs.base = 0; + sregs.cs.selector = 0; + KVM_IOCTL(vcpu_fd, KVM_SET_SREGS, &sregs); + printf("ioctl(%d<%s>, KVM_SET_SREGS, {cs={base=%#jx, limit=%u" + ", selector=%u, type=%u, present=%u, dpl=%u, db=%u, s=%u" + ", l=%u, g=%u, avl=%u}, ...}) = 0\n", + vcpu_fd, vcpu_dev, (uintmax_t) sregs.cs.base, + sregs.cs.limit, sregs.cs.selector, sregs.cs.type, + sregs.cs.present, sregs.cs.dpl, sregs.cs.db, sregs.cs.s, + sregs.cs.l, sregs.cs.g, sregs.cs.avl); + + /* + * Initialize registers: instruction pointer for our code, addends, + * and initial flags required by x86 architecture. + */ + struct kvm_regs regs = { + .rip = page_size, + .rax = 2, + .rbx = 2, + .rflags = 0x2, + }; + KVM_IOCTL(vcpu_fd, KVM_SET_REGS, ®s); + printf("ioctl(%d<%s>, KVM_SET_REGS, {rax=%#jx, ..." + ", rsp=%#jx, rbp=%#jx, ..., rip=%#jx, rflags=%#jx}) = 0\n", + vcpu_fd, vcpu_dev, (uintmax_t) regs.rax, + (uintmax_t) regs.rsp, (uintmax_t) regs.rbp, + (uintmax_t) regs.rip, (uintmax_t) regs.rflags); + + /* Copy the code till the end of page */ + size_t code_size = page_size - ((uintptr_t) code & (page_size - 1)); + if (code_size < 16) + code_size = 16; + memcpy(mem, code, code_size); + + const char *p = "\n"; + + /* Repeatedly run code and handle VM exits. */ + for (;;) { + KVM_IOCTL(vcpu_fd, KVM_RUN, NULL); + printf("ioctl(%d<%s>, KVM_RUN, 0) = 0\n", vcpu_fd, vcpu_dev); + + switch (run->exit_reason) { + case KVM_EXIT_HLT: + if (p) + error_msg_and_fail("premature KVM_EXIT_HLT"); + return; + case KVM_EXIT_IO: + if (run->io.direction == KVM_EXIT_IO_OUT + && run->io.size == 1 + && run->io.port == 0x03f8 + && run->io.count == 1 + && run->io.data_offset < mmap_size + && p && *p == ((char *) run)[run->io.data_offset]) + p = NULL; + else + error_msg_and_fail("unhandled KVM_EXIT_IO"); + break; + default: + error_msg_and_fail("exit_reason = %#x", + run->exit_reason); + } + } +} + +int +main(void) +{ + skip_if_unavailable("/proc/self/fd/"); + + int kvm = open(dev, O_RDWR); + if (kvm < 0) + perror_msg_and_skip("open: %s", dev); + + /* Make sure we have the stable version of the API */ + int ret = KVM_IOCTL(kvm, KVM_GET_API_VERSION, 0); + if (ret != KVM_API_VERSION) + error_msg_and_skip("KVM_GET_API_VERSION returned %d" + ", KVM_API_VERSION is %d", + kvm, KVM_API_VERSION); + printf("ioctl(%d<%s>, KVM_GET_API_VERSION, 0) = %d\n", + kvm, dev, ret); + + int vm_fd = KVM_IOCTL(kvm, KVM_CREATE_VM, 0); + printf("ioctl(%d<%s>, KVM_CREATE_VM, 0) = %d<%s>\n", + kvm, dev, vm_fd, vm_dev); + + /* Allocate one aligned page of guest memory to hold the code. */ + page_size = get_page_size(); + void *const mem = mmap(NULL, page_size, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, -1, 0); + if (mem == MAP_FAILED) + perror_msg_and_fail("mmap page"); + + /* Map it to the second page frame (to avoid the real-mode IDT at 0). */ + struct kvm_userspace_memory_region region = { + .slot = 0, + .guest_phys_addr = page_size, + .memory_size = page_size, + .userspace_addr = (uintptr_t) mem, + }; + KVM_IOCTL(vm_fd, KVM_SET_USER_MEMORY_REGION, ®ion); + printf("ioctl(%d<%s>, KVM_SET_USER_MEMORY_REGION" + ", {slot=0, flags=0, guest_phys_addr=%#lx, memory_size=%lu" + ", userspace_addr=%p}) = 0\n", vm_fd, vm_dev, + (unsigned long) page_size, (unsigned long) page_size, mem); + + int vcpu_fd = KVM_IOCTL(vm_fd, KVM_CREATE_VCPU, NULL); + printf("ioctl(%d<%s>, KVM_CREATE_VCPU, 0) = %d<%s>\n", + vm_fd, vm_dev, vcpu_fd, vcpu_dev); + + /* Map the shared kvm_run structure and following data. */ + ret = KVM_IOCTL(kvm, KVM_GET_VCPU_MMAP_SIZE, NULL); + struct kvm_run *run; + if (ret < (int) sizeof(*run)) + error_msg_and_fail("KVM_GET_VCPU_MMAP_SIZE returned %d < %d", + ret, (int) sizeof(*run)); + printf("ioctl(%d<%s>, KVM_GET_VCPU_MMAP_SIZE, 0) = %d\n", + kvm, dev, ret); + + const size_t mmap_size = (ret + page_size - 1) & -page_size; + run = mmap(NULL, mmap_size, PROT_READ | PROT_WRITE, + MAP_SHARED, vcpu_fd, 0); + if (run == MAP_FAILED) + perror_msg_and_fail("mmap vcpu"); + + run_kvm(vcpu_fd, run, mmap_size, mem); + + puts("+++ exited with 0 +++"); + return 0; +} + +#else /* !HAVE_LINUX_KVM_H */ + +SKIP_MAIN_UNDEFINED("HAVE_LINUX_KVM_H && HAVE_STRUCT_KVM_REGS && " + "HAVE_STRUCT_KVM_SREGS && " + "HAVE_STRUCT_KVM_USERSPACE_MEMORY_REGION && " + "(__x86_64__ || __i386__)") + +#endif diff --git a/tests/ioctl_kvm_run.test b/tests/ioctl_kvm_run.test new file mode 100755 index 00000000..a23cbeba --- /dev/null +++ b/tests/ioctl_kvm_run.test @@ -0,0 +1,11 @@ +#!/bin/sh + +# Check decoding of KVM_* ioctl commands. + +. "${srcdir=.}/init.sh" + +check_prog grep +run_prog > /dev/null +run_strace -a36 -y -eioctl $args > "$EXP" +grep -v '^ioctl([012],' < "$LOG" > "$OUT" +match_diff "$OUT" "$EXP" diff --git a/tests/pure_executables.list b/tests/pure_executables.list index 7ab52efe..0d1964de 100755 --- a/tests/pure_executables.list +++ b/tests/pure_executables.list @@ -103,6 +103,7 @@ ioctl ioctl_block ioctl_dm ioctl_evdev +ioctl_kvm_run ioctl_loop ioctl_mtd ioctl_rtc -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:39
|
Some relative paths don't work in Makefile.am when we move building directory, so v12 fixes it allowing make-dist to be run properly. Changelog: v12 * Add libcommon.a for sharing sources between strace and asinfo. * Make polished patches. * Add .dir to clean. * Make make-dist working with asinfo. * Expand .gitignore lists. v11 * Add tests * Fix issues in dispatcher.c file. v10 * Add asinfo binary to deb/rpm build. * Add '--raw' parameter to print out without formating. * Update MAN page and usage. * Fix issues and typos. v9 * Add MAN page. * Add script to generate source code describing architecture. * Use new number_set API. * Fix issues and typos. * Fix broken make dist with regard to asinfo. v8 * Add multiarch mode for syscall_dispatcher, which allows to show descrepancy in syscall numbers/name/arguments (number). * Add syscall filtering(as in strace). * Fix issues and typos. * Refine push back interface for syscall_service. * Refine push back interface for arch_service. v7 * Introduce multiarch mode for arch_dispatcher and abi_dispatcher. * Introduce new arch_description storage (arch_definitions.h). * Fix issues and typos. v6 * Adapt syscall dispatcher to the new program architecture. * Implement usage. * Refine command_dispatcher. * Fix issues and typos. v5,v4,v3 * Add command_dispatcher * Introduce syscall_dispatcher(raw version). * Introduce push back interface for syscall_service. * Fix issues and typos. v2 * Refine arch_dispatcher. * Introduce abi_dispatcher. * Add all architectures/ABIs supported by strace. * Introduce push back interface for arch_service. * Fix issues and typos. v1 and older minor implementation: * Introduce pipeline architecture. * Implement the first version of arch_dispatcher. * Introduce define-based interface to interact with array of arch_description. |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:56:18
|
Sorry, forgot to attach 7th patch On 12/10/2017 04:53 PM, Edgar Kaziakhmedov wrote: > Some relative paths don't work in Makefile.am when we move building directory, > so v12 fixes it allowing make-dist to be run properly. > > Changelog: > > v12 > * Add libcommon.a for sharing sources between strace and asinfo. > * Make polished patches. > * Add .dir to clean. > * Make make-dist working with asinfo. > * Expand .gitignore lists. > > v11 > * Add tests > * Fix issues in dispatcher.c file. > > v10 > * Add asinfo binary to deb/rpm build. > * Add '--raw' parameter to print out without formating. > * Update MAN page and usage. > * Fix issues and typos. > > v9 > * Add MAN page. > * Add script to generate source code describing architecture. > * Use new number_set API. > * Fix issues and typos. > * Fix broken make dist with regard to asinfo. > > v8 > * Add multiarch mode for syscall_dispatcher, which allows to show > descrepancy in syscall numbers/name/arguments (number). > * Add syscall filtering(as in strace). > * Fix issues and typos. > * Refine push back interface for syscall_service. > * Refine push back interface for arch_service. > > v7 > * Introduce multiarch mode for arch_dispatcher and abi_dispatcher. > * Introduce new arch_description storage (arch_definitions.h). > * Fix issues and typos. > > v6 > * Adapt syscall dispatcher to the new program architecture. > * Implement usage. > * Refine command_dispatcher. > * Fix issues and typos. > > v5,v4,v3 > * Add command_dispatcher > * Introduce syscall_dispatcher(raw version). > * Introduce push back interface for syscall_service. > * Fix issues and typos. > > v2 > * Refine arch_dispatcher. > * Introduce abi_dispatcher. > * Add all architectures/ABIs supported by strace. > * Introduce push back interface for arch_service. > * Fix issues and typos. > > v1 and older minor implementation: > * Introduce pipeline architecture. > * Implement the first version of arch_dispatcher. > * Introduce define-based interface to interact with array of arch_description. > . > |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:15
|
This set of tests cover all possible cases in asinfo tool. However,
as asinfo uses some libraries provided by strace (such as basic_filters)
there is no need to test them again in asinfo context.
Also, the set of syscalls for specific architecture (hence, its number) might
be expanded in the future, so to overcome this obstacle and avoid duplication
of the same strings reference output ptintings are stored in
ref_asinfo_output.h file.
As for syscall-related checks, tests use old syscalls as samples, so their
numbers and names can't be changed.
* configure.ac (AC_CONFIG_FILES): Add tests Makefile to be generated.
* tools/asinfo/Makefile.am (SUBDIRS): Add tests dir.
* tools/asinfo/tests/Makefile.m: New file.
* tools/asinfo/tests/init.sh: New file. Main subroutines for tests.
* tools/asinfo/tests/ref_asinfo_output.h: New file.
* tools/asinfo/tests/com_disp_wrong_keys.c: Likewise.
* tools/asinfo/tests/com_disp_wrong_keys.test: Likewise.
* tools/asinfo/tests/format_output.c: Likewise.
* tools/asinfo/tests/format_output.test: Likewise.
* tools/asinfo/tests/get_arch_abi.c: Likewise.
* tools/asinfo/tests/get_arch_abi.test: Likewise.
* tools/asinfo/tests/get_sname.c: Likewise.
* tools/asinfo/tests/get_sname.test: Likewise.
* tools/asinfo/tests/get_snum.c: Likewise.
* tools/asinfo/tests/get_snum.test: Likewise.
* tools/asinfo/tests/list_arch.c: Likewise.
* tools/asinfo/tests/list_arch.test: Likewise.
* tools/asinfo/tests/multiarch_get_sname.c: Likewise.
* tools/asinfo/tests/multiarch_get_sname.test: Likewise.
* tools/asinfo/tests/multiarch_get_snum.c: Likewise.
* tools/asinfo/tests/multiarch_get_snum.test: Likewise.
* tools/asinfo/tests/set_abi.c: Likewise.
* tools/asinfo/tests/set_abi.test: Likewise.
* tools/asinfo/tests/set_arch.c: Likewise.
* tools/asinfo/tests/set_arch.test: Likewise.
* tools/asinfo/tests/set_mult_abi.c: Likewise.
* tools/asinfo/tests/set_mult_abi.test: Likewise.
* tools/asinfo/tests/set_mult_arch.c: Likewise.
* tools/asinfo/tests/set_mult_arch.test: Likewise.
* tools/asinfo/tests/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
configure.ac | 1 +
tools/asinfo/Makefile.am | 2 +
tools/asinfo/tests/.gitignore | 16 +++
tools/asinfo/tests/Makefile.am | 67 +++++++++++
tools/asinfo/tests/com_disp_wrong_keys.c | 42 +++++++
tools/asinfo/tests/com_disp_wrong_keys.test | 32 +++++
tools/asinfo/tests/format_output.c | 17 +++
tools/asinfo/tests/format_output.test | 8 ++
tools/asinfo/tests/get_arch_abi.c | 180 ++++++++++++++++++++++++++++
tools/asinfo/tests/get_arch_abi.test | 7 ++
tools/asinfo/tests/get_sname.c | 26 ++++
tools/asinfo/tests/get_sname.test | 12 ++
tools/asinfo/tests/get_snum.c | 26 ++++
tools/asinfo/tests/get_snum.test | 12 ++
tools/asinfo/tests/init.sh | 97 +++++++++++++++
tools/asinfo/tests/list_arch.c | 49 ++++++++
tools/asinfo/tests/list_arch.test | 7 ++
tools/asinfo/tests/multiarch_get_sname.c | 27 +++++
tools/asinfo/tests/multiarch_get_sname.test | 12 ++
tools/asinfo/tests/multiarch_get_snum.c | 39 ++++++
tools/asinfo/tests/multiarch_get_snum.test | 12 ++
tools/asinfo/tests/ref_asinfo_output.h | 42 +++++++
tools/asinfo/tests/set_abi.c | 9 ++
tools/asinfo/tests/set_abi.test | 7 ++
tools/asinfo/tests/set_arch.c | 11 ++
tools/asinfo/tests/set_arch.test | 7 ++
tools/asinfo/tests/set_mult_abi.c | 11 ++
tools/asinfo/tests/set_mult_abi.test | 7 ++
tools/asinfo/tests/set_mult_arch.c | 12 ++
tools/asinfo/tests/set_mult_arch.test | 7 ++
30 files changed, 804 insertions(+)
create mode 100644 tools/asinfo/tests/.gitignore
create mode 100644 tools/asinfo/tests/Makefile.am
create mode 100644 tools/asinfo/tests/com_disp_wrong_keys.c
create mode 100755 tools/asinfo/tests/com_disp_wrong_keys.test
create mode 100644 tools/asinfo/tests/format_output.c
create mode 100755 tools/asinfo/tests/format_output.test
create mode 100644 tools/asinfo/tests/get_arch_abi.c
create mode 100755 tools/asinfo/tests/get_arch_abi.test
create mode 100644 tools/asinfo/tests/get_sname.c
create mode 100755 tools/asinfo/tests/get_sname.test
create mode 100644 tools/asinfo/tests/get_snum.c
create mode 100755 tools/asinfo/tests/get_snum.test
create mode 100644 tools/asinfo/tests/init.sh
create mode 100644 tools/asinfo/tests/list_arch.c
create mode 100755 tools/asinfo/tests/list_arch.test
create mode 100644 tools/asinfo/tests/multiarch_get_sname.c
create mode 100755 tools/asinfo/tests/multiarch_get_sname.test
create mode 100644 tools/asinfo/tests/multiarch_get_snum.c
create mode 100755 tools/asinfo/tests/multiarch_get_snum.test
create mode 100644 tools/asinfo/tests/ref_asinfo_output.h
create mode 100644 tools/asinfo/tests/set_abi.c
create mode 100755 tools/asinfo/tests/set_abi.test
create mode 100644 tools/asinfo/tests/set_arch.c
create mode 100755 tools/asinfo/tests/set_arch.test
create mode 100644 tools/asinfo/tests/set_mult_abi.c
create mode 100755 tools/asinfo/tests/set_mult_abi.test
create mode 100644 tools/asinfo/tests/set_mult_arch.c
create mode 100755 tools/asinfo/tests/set_mult_arch.test
diff --git a/configure.ac b/configure.ac
index 79690ba1..3e846be1 100644
--- a/configure.ac
+++ b/configure.ac
@@ -911,6 +911,7 @@ AC_CONFIG_FILES([Makefile
tools/asinfo/asinfo.1
tools/Makefile
tools/asinfo/Makefile
+ tools/asinfo/tests/Makefile
strace.spec
debian/changelog])
AC_OUTPUT
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
index f2b23e74..9f78b733 100644
--- a/tools/asinfo/Makefile.am
+++ b/tools/asinfo/Makefile.am
@@ -25,6 +25,8 @@
# (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 = . tests
+
bin_PROGRAMS = asinfo
man_MANS = asinfo.1
diff --git a/tools/asinfo/tests/.gitignore b/tools/asinfo/tests/.gitignore
new file mode 100644
index 00000000..592d7b61
--- /dev/null
+++ b/tools/asinfo/tests/.gitignore
@@ -0,0 +1,16 @@
+*.dir
+*.log
+*.o
+*.trs
+set_arch
+set_mult_arch
+list_arch
+set_abi
+set_mult_abi
+get_arch_abi
+get_sname
+get_snum
+com_disp_wrong_keys
+multiarch_get_sname
+multiarch_get_snum
+format_output
diff --git a/tools/asinfo/tests/Makefile.am b/tools/asinfo/tests/Makefile.am
new file mode 100644
index 00000000..0eae4674
--- /dev/null
+++ b/tools/asinfo/tests/Makefile.am
@@ -0,0 +1,67 @@
+# Automake input for asinfo tests.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+OS = linux
+AM_COLOR_TESTS = always
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = $(ARCH_MFLAGS) \
+ -I$(builddir)/../ \
+ -I$(builddir) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(top_srcdir)
+AM_LDFLAGS = $(ARCH_MFLAGS)
+
+check_PROGRAMS = set_arch set_mult_arch list_arch set_abi set_mult_abi \
+ get_arch_abi get_sname get_snum com_disp_wrong_keys \
+ multiarch_get_sname multiarch_get_snum format_output
+TESTS = set_arch.test set_mult_arch.test list_arch.test set_abi.test \
+ set_mult_abi.test get_arch_abi.test get_sname.test get_snum.test \
+ com_disp_wrong_keys.test multiarch_get_sname.test \
+ multiarch_get_snum.test format_output.test
+
+set_arch_SOURCES = set_arch.c
+set_mult_arch_SOURCES = set_mult_arch.c
+list_arch_SOURCES = list_arch.c
+set_abi_SOURCES = set_abi.c
+set_mult_abi_SOURCES = set_mult_abi.c
+get_arch_abi_SOURCES = get_arch_abi.c
+get_sname_SOURCES = get_sname.c
+get_snum_SOURCES = get_snum.c
+com_disp_wrong_keys_SOURCES = com_disp_wrong_keys.c
+multiarch_get_sname_SOURCES = multiarch_get_sname.c
+multiarch_get_snum_SOURCES = multiarch_get_snum.c
+format_output_SOURCES = format_output.c
+
+EXTRA_DIST = $(TESTS) \
+ ref_asinfo_output.h \
+ init.sh
+
+clean-local: clean-local-check
+.PHONY: clean-local-check
+clean-local-check:
+ -rm -rf -- $(TESTS:.test=.dir)
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.c b/tools/asinfo/tests/com_disp_wrong_keys.c
new file mode 100644
index 00000000..9dcb3ee2
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+#define TRY_HELP "Try \'../../asinfo -h\' for more information."
+
+int
+main(int argc, char *argv[])
+{
+ puts("../../asinfo: unrecognized option \'--set-ar\'\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--get-arch\' has been used more than "
+ "once\n"
+ TRY_HELP "\n"
+ "../../asinfo: parameter \'--set-arch\' requires argument\n"
+ TRY_HELP "\n"
+ "../../asinfo: argument \'aarch64,\' of \'--set-arch\' parameter "
+ "has a wrong format\n"
+ TRY_HELP "\n"
+ "../../asinfo: exclusive parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: wrong parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: \'--list-arch\' cannot be used with any ABI "
+ "parameters\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI parameters could be used only with "
+ "architecture parameter\n"
+ TRY_HELP "\n"
+ "../../asinfo: ABI modes cannot be automatically detected for "
+ "multiple architectures\n"
+ TRY_HELP "\n"
+ "../../asinfo: each architecture needs respective ABI mode, "
+ "and vice versa\n"
+ TRY_HELP "\n"
+ "../../asinfo: first set main output syscall characteristics\n"
+ TRY_HELP "\n"
+ "../../asinfo: raw data implies existing data\n"
+ TRY_HELP "\n"
+ "../../asinfo: must have OPTIONS\n"
+ TRY_HELP);
+ return 0;
+}
diff --git a/tools/asinfo/tests/com_disp_wrong_keys.test b/tools/asinfo/tests/com_disp_wrong_keys.test
new file mode 100755
index 00000000..ba725ab5
--- /dev/null
+++ b/tools/asinfo/tests/com_disp_wrong_keys.test
@@ -0,0 +1,32 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+#Unrecognized option
+run_asinfo --set-ar > $LOG
+#More than once param
+run_asinfo --get-arch --get-arch >> $LOG
+#Requiring argument
+run_asinfo --set-arch >> $LOG
+#Wrong format
+run_asinfo --set-arch aarch64, >> $LOG
+#More than one option in one group
+run_asinfo --get-arch --set-arch arm >> $LOG
+#syscall and list-arch
+run_asinfo --list-arch --get-sname all >> $LOG
+#list-arch and abi params
+run_asinfo --list-arch --list-abi >> $LOG
+#abi params without arch params
+run_asinfo --list-abi >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm >> $LOG
+#auto abi for multiple archs
+run_asinfo --set-arch aarch64,arm --set-abi all,all,all >> $LOG
+#nargs should be used together with other options from syscall group
+run_asinfo --set-arch x86_64 --set-abi x32 --nargs >> $LOG
+#raw check
+run_asinfo --raw >> $LOG
+#empty input
+run_asinfo >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/format_output.c b/tools/asinfo/tests/format_output.c
new file mode 100644
index 00000000..870b8445
--- /dev/null
+++ b/tools/asinfo/tests/format_output.c
@@ -0,0 +1,17 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts(
+"| N | Architecture name | ABI mode | IMPL syscalls | IPC IMPL | SOCKET IMPL |\n"
+"| 1 | avr32 | 32bit | 329 | external | external |"
+ );
+ puts(
+"| | | x86_64 | x86_64 | x86_64 |\n"
+"| N | Snum | 64bit | x32 | 32bit |\n"
+"| 1 | 1 | write | write | - |\n"
+"| 2 | 4 | - | - | write |");
+ return 0;
+}
diff --git a/tools/asinfo/tests/format_output.test b/tools/asinfo/tests/format_output.test
new file mode 100755
index 00000000..6addc6e9
--- /dev/null
+++ b/tools/asinfo/tests/format_output.test
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch avr32 --list-abi > $LOG
+run_asinfo --set-arch x86_64 --list-abi --get-snum write >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_arch_abi.c b/tools/asinfo/tests/get_arch_abi.c
new file mode 100644
index 00000000..e73aa0ca
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.c
@@ -0,0 +1,180 @@
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "ref_asinfo_output.h"
+
+static inline void
+print_cannot_detect(char *arch_name)
+{
+ printf("../../asinfo: ABI mode cannot be automatically detected for "
+ "non-target architecture \'%s\'\n", arch_name);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct utsname buf;
+ uname(&buf);
+#if defined(bfin)
+ puts("1" BFIN_32bit_STR);
+ return 0;
+#endif
+#if defined(IA64)
+ puts("1" IA64_64bit_STR);
+ return 0;
+#endif
+#if defined(M68K)
+ puts("1" M68K_32bit_STR);
+#endif
+#if defined(SPARC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(SPARC)
+ puts("1" SPARC_32bit_STR);
+ return 0;
+#endif
+#if defined(METAG)
+ puts("1" METAG_32bit_STR);
+ return 0;
+#endif
+#if defined(MIPS)
+ if (strstr(buf.machine, "mips64")) {
+ puts(
+#if defined(LINUX_MIPSO32)
+ "1" MIPS64_O32_STR
+#elif defined(LINUX_MIPSN32)
+ "1" MIPS64_N32_STR
+#elif defined(LINUX_MIPSN64)
+ "1" MIPS64_N64_STR
+#endif
+ );
+ return 0;
+ }
+ if (strstr(buf.machine, "mips")) {
+ puts("1" MIPS_O32_STR);
+ return 0;
+ }
+#endif
+#if defined(ALPHA)
+ puts("1" ALPHA_64bit_STR);
+ return 0;
+#endif
+#if defined(POWERPC64)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+#if defined(POWERPC)
+ puts("1" PPC_32bit_STR);
+ return 0;
+#endif
+#if defined(ARM)
+ if (strstr(buf.machine, "arm")) {
+ puts(
+#if defined(__ARM_EABI__) || !defined(ENABLE_ARM_OABI)
+ "1" ARM_eabi_STR
+#else
+ "1" ARM_oabi_STR
+#endif
+ );
+ return 0;
+ }
+#endif
+#if defined(AARCH64)
+ puts(
+#if defined(__ARM_EABI__)
+ "1" AARCH64_eabi_STR
+#else
+ "1" AARCH64_64bit_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(AVR32)
+ puts("1" AVR32_32bit_STR);
+ return 0;
+#endif
+#if defined(ARC)
+ puts("1" ARC_32bit_STR);
+ return 0;
+#endif
+#if defined(S390)
+ puts("1" S390_32bit_STR);
+ return 0;
+#endif
+#if defined(S390X)
+ puts("1" S390X_64bit_STR);
+ return 0;
+#endif
+#if defined(HPPA)
+ puts("1" PARISC_32bit_STR);
+ return 0;
+#endif
+#if defined(SH64)
+ puts("1" SH64_64bit_STR);
+ return 0;
+#endif
+#if defined(SH)
+ puts("1" SH_32bit_STR);
+ return 0;
+#endif
+#if defined(X86_64) || defined(X32)
+ puts(
+#if defined(X86_64)
+ "1" X86_64_64bit_STR
+#elif defined(X32)
+ "1" X86_64_X32_STR
+#endif
+ );
+ return 0;
+#endif
+#if defined(I386)
+ if (strstr(buf.machine, "64"))
+ puts("1" X86_64_32bit_STR);
+ else
+ puts("1" X86_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV10)
+ puts("1" CRISV10_32bit_STR);
+ return 0;
+#endif
+#if defined(CRISV32)
+ puts("1" CRISV32_32bit_STR);
+ return 0;
+#endif
+#if defined(TILE)
+ puts(
+#if defined(__tilepro__)
+ "1" TILE_64bit_STR
+#else
+ "1" TILE_32bit_STR
+#endif
+ );
+#endif
+#if defined(MICROBLAZE)
+ puts("1" MICROBLAZE_32bit_STR);
+ return 0;
+#endif
+#if defined(NIOS2)
+ puts("1" NIOS2_32bit_STR);
+ return 0;
+#endif
+#if defined(OR1K)
+ puts("1" OR1K_32bit_STR);
+ return 0;
+#endif
+#if defined(XTENSA)
+ puts("1" XTENSA_32bit_STR);
+ return 0;
+#endif
+#if defined(RISCV)
+ print_cannot_detect(buf.machine);
+ return 0;
+#endif
+ printf("../../asinfo: architecture \'%s\' is unsupported\n",
+ buf.machine);
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_arch_abi.test b/tools/asinfo/tests/get_arch_abi.test
new file mode 100755
index 00000000..d320c067
--- /dev/null
+++ b/tools/asinfo/tests/get_arch_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --get-arch --raw > "$LOG"
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_sname.c b/tools/asinfo/tests/get_sname.c
new file mode 100644
index 00000000..5edd7877
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;\n"
+ "2;pwrite64;18;\n"
+ "3;pwritev;296;\n"
+ "4;pwritev2;328;\n"
+ "5;write;1;\n"
+ "6;writev;20;\n"
+ //--get-sname write,read
+ "1;read;0;\n"
+ "2;write;1;\n"
+ //--get-sname 1
+ "1;write;1;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_sname.test b/tools/asinfo/tests/get_sname.test
new file mode 100755
index 00000000..2bff806e
--- /dev/null
+++ b/tools/asinfo/tests/get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/get_snum.c b/tools/asinfo/tests/get_snum.c
new file mode 100644
index 00000000..ada19312
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.c
@@ -0,0 +1,26 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;\n"
+ //--get-snum /write
+ "1;1;write;\n"
+ "2;18;pwrite64;\n"
+ "3;20;writev;\n"
+ "4;296;pwritev;\n"
+ "5;311;process_vm_writev;\n"
+ "6;328;pwritev2;\n"
+ //--get-snum write,read
+ "1;0;read;\n"
+ "2;1;write;\n"
+ //--get-snum 1
+ "1;1;write;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/get_snum.test b/tools/asinfo/tests/get_snum.test
new file mode 100755
index 00000000..02dceca4
--- /dev/null
+++ b/tools/asinfo/tests/get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64 --set-abi 64bit --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/init.sh b/tools/asinfo/tests/init.sh
new file mode 100644
index 00000000..1ab105d9
--- /dev/null
+++ b/tools/asinfo/tests/init.sh
@@ -0,0 +1,97 @@
+#!/bin/sh
+#
+# Copyright (c) 2011-2017 The strace developers.
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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.
+
+ME_="${0##*/}"
+LOG="log"
+OUT="out"
+EXP="exp"
+ASINFO="../../asinfo"
+
+fail_() { warn_ "$ME_: failed test: $*"; exit 1; }
+warn_() { printf >&2 '%s\n' "$*"; }
+
+run_prog()
+{
+ if [ $# -eq 0 ]; then
+ set -- "../$NAME"
+ fi
+ args="$*"
+ "$@" || {
+ rc=$?
+ if [ $rc != 0 ]; then
+ fail_ "$args failed with code $rc"
+ fi
+ }
+}
+
+
+dump_log_and_fail_with()
+{
+ cat < "$LOG" >&2
+ fail_ "$*"
+}
+
+run_asinfo()
+{
+ args="$*"
+ $ASINFO "$@" 2>&1
+}
+
+match_diff()
+{
+ local output expected error
+ if [ $# -eq 0 ]; then
+ output="$LOG"
+ else
+ output="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ expected="$srcdir/$NAME.expected"
+ else
+ expected="$1"; shift
+ fi
+ if [ $# -eq 0 ]; then
+ error="$STRACE $args output mismatch"
+ else
+ error="$1"; shift
+ fi
+
+ diff -u -- "$expected" "$output" ||
+ fail_ "$error"
+}
+
+NAME="${ME_%.test}"
+TESTDIR="$NAME.dir"
+rm -rf -- "$TESTDIR"
+mkdir -- "$TESTDIR"
+cd "$TESTDIR"
+case "$srcdir" in
+ /*) ;;
+ *) srcdir="../$srcdir" ;;
+esac
+
diff --git a/tools/asinfo/tests/list_arch.c b/tools/asinfo/tests/list_arch.c
new file mode 100644
index 00000000..a8b91553
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.c
@@ -0,0 +1,49 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" BFIN_32bit_STR"\n"
+ "2" IA64_64bit_STR"\n"
+ "3" M68K_32bit_STR"\n"
+ "4" SPARC64_64bit_STR"\n"
+ "5" SPARC64_32bit_STR"\n"
+ "6" SPARC_32bit_STR"\n"
+ "7" METAG_32bit_STR"\n"
+ "8" MIPS64_N64_STR"\n"
+ "9" MIPS64_N32_STR"\n"
+ "10" MIPS64_O32_STR"\n"
+ "11" MIPS_O32_STR"\n"
+ "12" ALPHA_64bit_STR"\n"
+ "13" PPC64_64bit_STR"\n"
+ "14" PPC64_32bit_STR"\n"
+ "15" PPC_32bit_STR"\n"
+ "16" AARCH64_64bit_STR"\n"
+ "17" AARCH64_eabi_STR"\n"
+ "18" ARM_oabi_STR"\n"
+ "19" ARM_eabi_STR"\n"
+ "20" AVR32_32bit_STR"\n"
+ "21" ARC_32bit_STR"\n"
+ "22" S390X_64bit_STR"\n"
+ "23" S390_32bit_STR"\n"
+ "24" PARISC_32bit_STR"\n"
+ "25" SH64_64bit_STR"\n"
+ "26" SH_32bit_STR"\n"
+ "27" X86_64_64bit_STR"\n"
+ "28" X86_64_X32_STR"\n"
+ "29" X86_64_32bit_STR"\n"
+ "30" X86_32bit_STR"\n"
+ "31" CRISV10_32bit_STR"\n"
+ "32" CRISV32_32bit_STR"\n"
+ "33" TILE_64bit_STR"\n"
+ "34" TILE_32bit_STR"\n"
+ "35" TILEPRO_32bit_STR"\n"
+ "36" MICROBLAZE_32bit_STR"\n"
+ "37" NIOS2_32bit_STR"\n"
+ "38" OR1K_32bit_STR"\n"
+ "39" XTENSA_32bit_STR"\n"
+ "40" RISCV_64bit_STR"\n"
+ "41" RISCV_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/list_arch.test b/tools/asinfo/tests/list_arch.test
new file mode 100755
index 00000000..263d69df
--- /dev/null
+++ b/tools/asinfo/tests/list_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --list-arch --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_sname.c b/tools/asinfo/tests/multiarch_get_sname.c
new file mode 100644
index 00000000..53d219a9
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.c
@@ -0,0 +1,27 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-sname write
+ puts("1;write;1;1;4;4;\n"
+ //--get-sname /write
+ "1;process_vm_writev;311;540;348;348;\n"
+ "2;pwrite64;18;18;181;181;\n"
+ "3;pwritev;296;535;334;334;\n"
+ "4;pwritev2;328;547;379;379;\n"
+ "5;write;1;1;4;4;\n"
+ "6;writev;20;516;146;146;\n"
+ //--get-sname write,read
+ "1;read;0;0;3;3;\n"
+ "2;write;1;1;4;4;\n"
+ //--get-sname 1
+ "1;exit;-;-;1;1;\n"
+ "2;write;1;1;-;-;\n"
+ //--get-sname 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-sname helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_sname.test b/tools/asinfo/tests/multiarch_get_sname.test
new file mode 100755
index 00000000..0ff7bb92
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_sname.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-sname helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/multiarch_get_snum.c b/tools/asinfo/tests/multiarch_get_snum.c
new file mode 100644
index 00000000..27658d20
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.c
@@ -0,0 +1,39 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ //--get-snum write
+ puts("1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ //--get-snum /write
+ "1;1;write;write;-;-;\n"
+ "2;4;-;-;write;write;\n"
+ "3;18;pwrite64;pwrite64;-;-;\n"
+ "4;20;writev;-;-;-;\n"
+ "5;146;-;-;writev;writev;\n"
+ "6;181;-;-;pwrite64;pwrite64;\n"
+ "7;296;pwritev;-;-;-;\n"
+ "8;311;process_vm_writev;-;-;-;\n"
+ "9;328;pwritev2;-;-;-;\n"
+ "10;334;-;-;pwritev;pwritev;\n"
+ "11;348;-;-;process_vm_writev;process_vm_writev;\n"
+ "12;379;-;-;pwritev2;pwritev2;\n"
+ "13;516;-;writev;-;-;\n"
+ "14;535;-;pwritev;-;-;\n"
+ "15;540;-;process_vm_writev;-;-;\n"
+ "16;547;-;pwritev2;-;-;\n"
+ //--get-snum write,read
+ "1;0;read;read;-;-;\n"
+ "2;1;write;write;-;-;\n"
+ "3;3;-;-;read;read;\n"
+ "4;4;-;-;write;write;\n"
+ //--get-snum 1
+ "1;1;write;write;exit;exit;\n"
+ //--get-snum 1000
+ "../../asinfo: invalid system call(x86_64/64bit) \'1000\'\n"
+ //--get-snum helloworld
+ "../../asinfo: invalid system call(x86_64/64bit) \'helloworld\'");
+ return 0;
+}
diff --git a/tools/asinfo/tests/multiarch_get_snum.test b/tools/asinfo/tests/multiarch_get_snum.test
new file mode 100755
index 00000000..364903a6
--- /dev/null
+++ b/tools/asinfo/tests/multiarch_get_snum.test
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write --raw > $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum /write --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum write,read --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum 1000 --raw >> $LOG
+run_asinfo --set-arch x86_64,x86 --list-abi --get-snum helloworld --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/ref_asinfo_output.h b/tools/asinfo/tests/ref_asinfo_output.h
new file mode 100644
index 00000000..bc5fce4c
--- /dev/null
+++ b/tools/asinfo/tests/ref_asinfo_output.h
@@ -0,0 +1,42 @@
+/* Reference output strings for asinfo tool which are necessary for tests */
+#define BFIN_32bit_STR ";blackfin/bfin;32bit;391;external;external;"
+#define IA64_64bit_STR ";ia64;64bit;707;external;external;"
+#define M68K_32bit_STR ";m68k;32bit;378;internal;internal;"
+#define SPARC64_64bit_STR ";sparc64;64bit;340;internal;internal;"
+#define SPARC64_32bit_STR ";sparc64;32bit;358;internal;internal;"
+#define SPARC_32bit_STR ";sparc;32bit;358;internal;internal;"
+#define METAG_32bit_STR ";metag;32bit;280;external;external;"
+#define MIPS64_N64_STR ";mips64/mips64le;n64;1000;int/ext;int/ext;"
+#define MIPS64_N32_STR ";mips64/mips64le;n32;1004;int/ext;int/ext;"
+#define MIPS64_O32_STR ";mips64/mips64le;o32;1039;internal;internal;"
+#define MIPS_O32_STR ";mips/mipsle;o32;1039;internal;internal;"
+#define ALPHA_64bit_STR ";alpha;64bit;442;external;external;"
+#define PPC64_64bit_STR ";ppc64/ppc64le/powerpc64;64bit;374;int/ext;int/ext;"
+#define PPC64_32bit_STR ";ppc64/ppc64le/powerpc64;32bit;383;int/ext;int/ext;"
+#define PPC_32bit_STR ";ppc/ppcle/powerpc;32bit;383;int/ext;int/ext;"
+#define AARCH64_64bit_STR ";aarch64/arm64;64bit;332;external;external;"
+#define AARCH64_eabi_STR ";aarch64/arm64;eabi;400;external;external;"
+#define ARM_oabi_STR ";arm;oabi;400;int/ext;int/ext;"
+#define ARM_eabi_STR ";arm;eabi;400;external;external;"
+#define AVR32_32bit_STR ";avr32;32bit;329;external;external;"
+#define ARC_32bit_STR ";arc;32bit;281;external;external;"
+#define S390X_64bit_STR ";s390x;64bit;326;internal;internal;"
+#define S390_32bit_STR ";s390;32bit;359;internal;internal;"
+#define PARISC_32bit_STR ";parisc/hppa;32bit;349;external;external;"
+#define SH64_64bit_STR ";sh64;64bit;382;int/ext;int/ext;"
+#define SH_32bit_STR ";sh;32bit;374;internal;internal;"
+#define X86_64_64bit_STR ";x86_64/amd64/EM64T;64bit;333;external;external;"
+#define X86_64_X32_STR ";x86_64/amd64/EM64T;x32;369;external;external;"
+#define X86_64_32bit_STR ";x86_64/amd64/EM64T;32bit;381;internal;internal;"
+#define X86_32bit_STR ";x86/i386/i486/i586/i686;32bit;381;internal;internal;"
+#define CRISV10_32bit_STR ";cris/crisv10;32bit;355;internal;internal;"
+#define CRISV32_32bit_STR ";crisv32;32bit;355;internal;internal;"
+#define TILE_64bit_STR ";tile/tilegx;64bit;278;external;external;"
+#define TILE_32bit_STR ";tile/tilegx;32bit;278;external;external;"
+#define TILEPRO_32bit_STR ";tilepro;32bit;278;external;external;"
+#define MICROBLAZE_32bit_STR ";microblaze;32bit;395;external;external;"
+#define NIOS2_32bit_STR ";nios2;32bit;277;external;external;"
+#define OR1K_32bit_STR ";openrisc/or1k;32bit;277;external;external;"
+#define XTENSA_32bit_STR ";xtensa;32bit;325;external;external;"
+#define RISCV_64bit_STR ";riscv;64bit;276;external;external;"
+#define RISCV_32bit_STR ";riscv;32bit;276;external;external;"
diff --git a/tools/asinfo/tests/set_abi.c b/tools/asinfo/tests/set_abi.c
new file mode 100644
index 00000000..b74e0ccb
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_abi.test b/tools/asinfo/tests/set_abi.test
new file mode 100755
index 00000000..70b1f429
--- /dev/null
+++ b/tools/asinfo/tests/set_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --set-abi 64bit --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_arch.c b/tools/asinfo/tests/set_arch.c
new file mode 100644
index 00000000..05f44b79
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" X86_64_X32_STR "\n"
+ "3" X86_64_32bit_STR);
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_arch.test b/tools/asinfo/tests/set_arch.test
new file mode 100755
index 00000000..e9a102c6
--- /dev/null
+++ b/tools/asinfo/tests/set_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64 --list-abi --raw > $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_abi.c b/tools/asinfo/tests/set_mult_abi.c
new file mode 100644
index 00000000..4107fabb
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" X86_64_64bit_STR "\n"
+ "2" AARCH64_64bit_STR "\n"
+ "3" AARCH64_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_abi.test b/tools/asinfo/tests/set_mult_abi.test
new file mode 100755
index 00000000..555c27ca
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_abi.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch x86_64,aarch64 --set-abi 64bit,all --raw >> $LOG
+match_diff "$LOG" "$EXP"
diff --git a/tools/asinfo/tests/set_mult_arch.c b/tools/asinfo/tests/set_mult_arch.c
new file mode 100644
index 00000000..ed8d66df
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+#include "ref_asinfo_output.h"
+
+int
+main(int argc, char *argv[])
+{
+ puts("1" AARCH64_64bit_STR "\n"
+ "2" AARCH64_eabi_STR "\n"
+ "3" ARM_oabi_STR "\n"
+ "4" ARM_eabi_STR );
+ return 0;
+}
diff --git a/tools/asinfo/tests/set_mult_arch.test b/tools/asinfo/tests/set_mult_arch.test
new file mode 100755
index 00000000..d0152d60
--- /dev/null
+++ b/tools/asinfo/tests/set_mult_arch.test
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+. "${srcdir=.}/init.sh"
+
+run_prog > $EXP
+run_asinfo --set-arch aarch64,arm --list-abi --raw >> $LOG
+match_diff "$LOG" "$EXP"
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:12
|
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- NEWS | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/NEWS b/NEWS index 448a9cb3..8ae25fbd 100644 --- a/NEWS +++ b/NEWS @@ -16,6 +16,10 @@ Noteworthy changes in release ?.?? (????-??-??) * Bug fixes * Fixed multi-personality support in cross builds. +* New tools + * Added asinfo tool, that is purposed to provide information about + system calls and architectures. + Noteworthy changes in release 4.20 (2017-11-13) =============================================== -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:12
|
As asinfo detects ABI mode based on userspace environment in biarch
systems, add asinfo only to strace package.
* debian/control (strace, strace-udeb): Add asinfo decription.
* debian/strace.install: Add path to asinfo binary.
* debian/strace.manpages: Add path to asinfo man.
* strace.spec.in (%files): Add asinfo binary.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
debian/control | 6 ++++++
debian/strace.install | 1 +
debian/strace.manpages | 1 +
strace.spec.in | 7 +++++--
4 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/debian/control b/debian/control
index 92cdc204..f47b36a1 100644
--- a/debian/control
+++ b/debian/control
@@ -20,6 +20,9 @@ Description: System call tracer
System calls and signals are events that happen at the user/kernel
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
+ .
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
Package: strace64
Architecture: i386 powerpc s390 sparc
@@ -54,5 +57,8 @@ Description: System call tracer
interface. A close examination of this boundary is very useful for bug
isolation, sanity checking and attempting to capture race conditions.
.
+ In addition, asinfo tool, included to package, allows to get information
+ about any system call for specified architecture.
+ .
This is a stripped down package intended for debugging use in the Debian
installer.
diff --git a/debian/strace.install b/debian/strace.install
index 30b0a6b0..1e2401bb 100644
--- a/debian/strace.install
+++ b/debian/strace.install
@@ -1,2 +1,3 @@
build/strace usr/bin
strace-log-merge usr/bin
+build/tools/asinfo/asinfo usr/bin
diff --git a/debian/strace.manpages b/debian/strace.manpages
index d3b94482..cd0be9eb 100644
--- a/debian/strace.manpages
+++ b/debian/strace.manpages
@@ -1,2 +1,3 @@
strace.1
strace-log-merge.1
+build/tools/asinfo/asinfo.1
diff --git a/strace.spec.in b/strace.spec.in
index 41b69d0e..cbd15995 100644
--- a/strace.spec.in
+++ b/strace.spec.in
@@ -21,7 +21,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -36,7 +37,8 @@ The strace program intercepts and records the system calls called and
received by a running process. Strace can print a record of each
system call, its arguments and its return value. Strace is useful for
diagnosing problems and debugging, as well as for instructional
-purposes.
+purposes. Also strace includes advanced system call information tool
+(asinfo), which provides information about system calls and architectures.
Install strace if you need a tool to track the system calls made and
received by a process.
@@ -92,6 +94,7 @@ echo 'END OF TEST SUITE INFORMATION'
%{?suse_version:%defattr(-,root,root)}
%doc CREDITS ChangeLog ChangeLog-CVS COPYING NEWS README
%{_bindir}/strace
+${_bindir}/asinfo
%{_bindir}/strace-log-merge
%{_mandir}/man1/*
--
2.11.0
|
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:10
|
Since arch_definitions.h contains full description about architectures, arch_includes.h and arch_personalities.h can be generated. * tools/asinfo/gen_asinfo_files.sh: New file. * bootstrap: Add it. * tools/asinfo/arch_includes.h: Delete it. * tools/asinfo/arch_personalities.h: Likewise. * tools/asinfo/Makefile.am: Include Makemodule.am. (asinfo_SOURCES): Add $(ARCH_AUX_FILES). * tools/asinfo/README-arch: New README explaining how to add new architecture/ABI to asinfo tool. * tools/asinfo/.gitignore: Add generated files. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- bootstrap | 1 + configure.ac | 5 + tools/asinfo/.gitignore | 3 + tools/asinfo/Makefile.am | 6 +- tools/asinfo/README-arch | 38 ++++++ tools/asinfo/arch_includes.h | 272 ------------------------------------ tools/asinfo/arch_personalities.h | 36 ----- tools/asinfo/asinfo.1.in | 280 ++++++++++++++++++++++++++++++++++++++ tools/asinfo/gen_asinfo_files.sh | 160 ++++++++++++++++++++++ 9 files changed, 491 insertions(+), 310 deletions(-) create mode 100644 tools/asinfo/README-arch delete mode 100644 tools/asinfo/arch_includes.h delete mode 100644 tools/asinfo/arch_personalities.h create mode 100644 tools/asinfo/asinfo.1.in create mode 100755 tools/asinfo/gen_asinfo_files.sh diff --git a/bootstrap b/bootstrap index a9cadf53..da06de3b 100755 --- a/bootstrap +++ b/bootstrap @@ -4,6 +4,7 @@ ./xlat/gen.sh ./tests/gen_pure_executables.sh ./tests/gen_tests.sh +./tools/asinfo/gen_asinfo_files.sh for m in m32 mx32; do tests=tests-$m diff --git a/configure.ac b/configure.ac index 0492bd8b..79690ba1 100644 --- a/configure.ac +++ b/configure.ac @@ -38,6 +38,7 @@ AC_INIT([strace], [https://strace.io]) m4_define([copyright_year], m4_esyscmd([./copyright-year-gen .year])) m4_define([manpage_date], m4_esyscmd([./file-date-gen strace.1.in])) +m4_define([asinfo_manpage_date], m4_esyscmd([./file-date-gen tools/asinfo/asinfo.1.in])) AC_COPYRIGHT([Copyright (c) 1999-]copyright_year[ The strace developers.]) AC_CONFIG_SRCDIR([strace.c]) AC_CONFIG_AUX_DIR([.]) @@ -67,6 +68,9 @@ AC_SUBST([COPYRIGHT_YEAR], [copyright_year]) AC_DEFINE([MANPAGE_DATE], "[manpage_date]", [Date]) AC_SUBST([MANPAGE_DATE], [manpage_date]) +AC_DEFINE([ASINFO_MANPAGE_DATE], "[asinfo_manpage_date]", [Date]) +AC_SUBST([ASINFO_MANPAGE_DATE], [asinfo_manpage_date]) + AC_MSG_CHECKING([for supported architecture]) arch_m32= arch_mx32= @@ -904,6 +908,7 @@ AC_CONFIG_FILES([Makefile tests-mx32/Makefile strace.1 strace-log-merge.1 + tools/asinfo/asinfo.1 tools/Makefile tools/asinfo/Makefile strace.spec diff --git a/tools/asinfo/.gitignore b/tools/asinfo/.gitignore index 09400c47..3254269c 100644 --- a/tools/asinfo/.gitignore +++ b/tools/asinfo/.gitignore @@ -1,2 +1,5 @@ +arch_includes.h +arch_personalities.h asinfo asinfo.1 +Makemodule.am diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am index 5051766e..f2b23e74 100644 --- a/tools/asinfo/Makefile.am +++ b/tools/asinfo/Makefile.am @@ -38,6 +38,9 @@ AM_CPPFLAGS = -I$(builddir) \ -I$(top_srcdir)/$(OS) \ -I$(top_builddir) \ -I$(top_srcdir) + +include Makemodule.am + asinfo_CPPFLAGS = $(AM_CPPFLAGS) asinfo_CFLAGS = $(AM_CFLAGS) asinfo_LDFLAGS = @@ -47,10 +50,9 @@ asinfo_LDADD = -L$(top_srcdir) \ asinfo_SOURCES = \ arch_definitions.h \ - arch_includes.h \ arch_interface.c \ + $(ARCH_AUX_FILES) \ arch_interface.h \ - arch_personalities.h \ asinfo.c \ dispatchers.c \ dispatchers.h \ diff --git a/tools/asinfo/README-arch b/tools/asinfo/README-arch new file mode 100644 index 00000000..6b73aa01 --- /dev/null +++ b/tools/asinfo/README-arch @@ -0,0 +1,38 @@ +This file describes the storage format of arch_definitions.h + +Storage format: +/* [ARCH_SPECIFIC_DEFINE],[ACONST1,ACONST2] */ +ARCH_DESC_DEFINE(ARCH_NAME,ARCH_ABI,PASS({COMPAT_PERS1,COMPAT_PERS2,...}),\ +PASS({ALIAS1,ALIAS2,...})) + +ARCH_SPECIFIC_DEFINE: +One syscallent.h header can contain several set of system calls for each +compatible mode. And specific set can be switched by passing particular +definition. +So ARCH_SPECIFIC_DEFINE allows to forward a given definition, where +!ARCH_SPECIFIC_DEFINE forwards undefined. +If it is not required, left empty. + +ACONST1,ACONST2: +It could be used to store architecture specific constants and pass them to code. +If is is not required each one must be set to zero. + +ARCH_NAME: +The main name of architecture will be used to generate the personality +constants. +The personality constant is equal to ARCH_+\$ARCH_ABI+_+\$ARCH_NAME. + +ARCH_ABI: +Application binary interface for a given architecture, i.e. 32bit, 64bit, oabi, +eabi, o32 etc. + +COMPAT_PERS1,COMPAT_PERS2,...: +Compatible mode for a given architecture. It should be one of personality +constants. +If is is not required, left empty. + +ALIAS1,ALIAS2,...: +Other name of the same architecture, like x86 and i386. At least one alias +must to be set as it shows the name of architecture while printing. +If current ARCH_NAME is just the compatible ABI mode, left empty. + diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h deleted file mode 100644 index e73a8328..00000000 --- a/tools/asinfo/arch_includes.h +++ /dev/null @@ -1,272 +0,0 @@ -/* ARCH_blackfin */ -static const struct_sysent blackfin_32bit_sysent[] = { - #include "bfin/syscallent.h" -}; -static const int blackfin_32bit_usr1 = 0; -const int blackfin_32bit_usr2 = 0; -/* ARCH_ia64 */ -struct_sysent ia64_64bit_sysent[] = { - #include "ia64/syscallent.h" -}; -static const int ia64_64bit_usr1 = 0; -static const int ia64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_m68k */ -static const struct_sysent m68k_32bit_sysent[] = { - #include "m68k/syscallent.h" -}; -static const int m68k_32bit_usr1 = 0; -static const int m68k_32bit_usr2 = 0; -/* ARCH_sparc64 64bit ABI */ -static const struct_sysent sparc64_64bit_sysent[] = { - #include "sparc64/syscallent.h" -}; -static const int sparc64_64bit_usr1 = 0; -static const int sparc64_64bit_usr2 = 0; -/* ARCH_sparc and 32bit ABI */ -static const struct_sysent sparc_32bit_sysent[] = { - #include "sparc/syscallent.h" -}; -static const int sparc_32bit_usr1 = 0; -static const int sparc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_metag */ -static const struct_sysent metag_32bit_sysent[] = { - #include "metag/syscallent.h" -}; -static const int metag_32bit_usr1 = 0; -static const int metag_32bit_usr2 = 0; -/* ARCH_mips n64 ABI */ -#ifndef LINUX_MIPSN64 -# define LINUX_MIPSN64 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n64_usr1 = 0; -static const int mips64_n64_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips n32 ABI */ -#ifndef LINUX_MIPSN32 -# define LINUX_MIPSN32 1 -# define NOW_DEFINED 1 -#endif -static const struct_sysent mips64_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 -static const int mips64_n32_usr1 = 0; -static const int mips64_n32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_mips o32 ABI */ -#ifndef LINUX_MIPSO32 -# define LINUX_MIPSO32 1 -# define NOW_DEFINED 1 -#endif -static const 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 -static const int mips_o32_usr1 = 0; -static const int mips_o32_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_alpha */ -static const struct_sysent alpha_64bit_sysent[] = { - #include "alpha/syscallent.h" -}; -static const int alpha_64bit_usr1 = 0; -static const int alpha_64bit_usr2 = 0; -/* ARCH_ppc64 64bit ABI */ -static const struct_sysent ppc64_64bit_sysent[] = { - #include "powerpc64/syscallent.h" -}; -static const int ppc64_64bit_usr1 = 0; -static const int ppc64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_ppc and 32bit */ -static const struct_sysent ppc_32bit_sysent[] = { - #include "powerpc/syscallent.h" -}; -static const int ppc_32bit_usr1 = 0; -static const int ppc_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_aarch64 64bit ABI */ -static const struct_sysent aarch64_64bit_sysent[] = { - #include "aarch64/syscallent.h" -}; -static const int aarch64_64bit_usr1 = 0; -static const int aarch64_64bit_usr2 = 0; -/* ARCH_arm OABI*/ -#ifdef __ARM_EABI__ -# undef __ARM_EABI__ -# define NOW_UNDEFINED 1 -#endif -static const struct_sysent arm_oabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL; -#undef ARM_FIRST_SHUFFLED_SYSCALL -#undef ARM_LAST_SPECIAL_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 -static const struct_sysent arm_eabi_sysent[] = { - #include "arm/syscallent.h" -}; -static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL; -static const int arm_eabi_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 */ -static const struct_sysent avr32_32bit_sysent[] = { - #include "avr32/syscallent.h" -}; -static const int avr32_32bit_usr1 = 0; -static const int avr32_32bit_usr2 = 0; -/* ARCH_arc */ -static const struct_sysent arc_32bit_sysent[] = { - #include "arc/syscallent.h" -}; -static const int arc_32bit_usr1 = 0; -static const int arc_32bit_usr2 = 0; -/* ARCH_s390x */ -static const struct_sysent s390x_64bit_sysent[] = { - #include "s390x/syscallent.h" -}; -static const int s390x_64bit_usr1 = 0; -static const int s390x_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_s390 */ -static const struct_sysent s390_32bit_sysent[] = { - #include "s390/syscallent.h" -}; -static const int s390_32bit_usr1 = 0; -static const int s390_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_hppa */ -static const struct_sysent hppa_32bit_sysent[] = { - #include "hppa/syscallent.h" -}; -static const int hppa_32bit_usr1 = 0; -static const int hppa_32bit_usr2 = 0; -/* ARCH_sh64 */ -static const struct_sysent sh64_64bit_sysent[] = { - #include "sh64/syscallent.h" -}; -static const int sh64_64bit_usr1 = 0; -static const int sh64_64bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_sh */ -static const struct_sysent sh_32bit_sysent[] = { - #include "sh/syscallent.h" -}; -static const int sh_32bit_usr1 = 0; -static const int sh_32bit_usr2 = 0; -/* ARCH_x86_64 64bit ABI mode */ -static const struct_sysent x86_64_64bit_sysent[] = { - #include "x86_64/syscallent.h" -}; -static const int x86_64_64bit_usr1 = 0; -static const int x86_64_64bit_usr2 = 0; -/* ARCH_x86_64 x32 ABI mode */ -static const struct_sysent x86_64_x32_sysent[] = { - #include "x86_64/syscallent2.h" -}; -static const int x86_64_x32_usr1 = 0; -static const int x86_64_x32_usr2 = 0; -/* ARCH_x86 */ -static const struct_sysent x86_32bit_sysent[] = { - #include "i386/syscallent.h" -}; -static const int x86_32bit_usr1 = 0; -static const int x86_32bit_usr2 = 0; -/* ARCH_cris */ -static struct_sysent cris_32bit_sysent[] = { - #include "crisv10/syscallent.h" -}; -static const int cris_32bit_usr1 = 0; -static const int cris_32bit_usr2 = 0; -/* ARCH_crisv32 */ -static const struct_sysent crisv32_32bit_sysent[] = { - #include "crisv32/syscallent.h" -}; -static const int crisv32_32bit_usr1 = 0; -static const int crisv32_32bit_usr2 = 0; -#undef SYS_socket_subcall -/* ARCH_tile 64bit ABI mode */ -static const struct_sysent tile_64bit_sysent[] = { - #include "tile/syscallent.h" -}; -static const int tile_64bit_usr1 = 0; -static const int tile_64bit_usr2 = 0; -/* ARCH_tile 32bit ABI mode */ -static const struct_sysent tile_32bit_sysent[] = { - #include "tile/syscallent1.h" -}; -static const int tile_32bit_usr1 = 0; -static const int tile_32bit_usr2 = 0; -/* ARCH_microblaze */ -static const struct_sysent microblaze_32bit_sysent[] = { - #include "microblaze/syscallent.h" -}; -static const int microblaze_32bit_usr1 = 0; -static const int microblaze_32bit_usr2 = 0; -/* ARCH_nios2 */ -static const struct_sysent nios2_32bit_sysent[] = { - #include "nios2/syscallent.h" -}; -static const int nios2_32bit_usr1 = 0; -static const int nios2_32bit_usr2 = 0; -/* ARCH_openrisc */ -struct_sysent openrisc_32bit_sysent[] = { - #include "or1k/syscallent.h" -}; -static const int openrisc_32bit_usr1 = 0; -static const int openrisc_32bit_usr2 = 0; -/* ARCH_xtensa */ -static const struct_sysent xtensa_32bit_sysent[] = { - #include "xtensa/syscallent.h" -}; -static const int xtensa_32bit_usr1 = 0; -static const int xtensa_32bit_usr2 = 0; -/* ARCH_riscv 64bit ABI mode */ -static const struct_sysent riscv_64bit_sysent[] = { - #include "riscv/syscallent.h" -}; -static const int riscv_64bit_usr1 = 0; -static const int riscv_64bit_usr2 = 0; -/* ARCH_riscv 32bit ABI mode */ -static const struct_sysent riscv_32bit_sysent[] = { - #include "riscv/syscallent1.h" -}; -static const int riscv_32bit_usr1 = 0; -static const int riscv_32bit_usr2 = 0; diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h deleted file mode 100644 index 9499c5aa..00000000 --- a/tools/asinfo/arch_personalities.h +++ /dev/null @@ -1,36 +0,0 @@ -ARCH_no_pers, -ARCH_blackfin_32bit, -ARCH_ia64_64bit, -ARCH_m68k_32bit, -ARCH_sparc64_64bit, -ARCH_sparc_32bit, -ARCH_metag_32bit, -ARCH_mips64_n64, -ARCH_mips64_n32, -ARCH_mips_o32, -ARCH_alpha_64bit, -ARCH_ppc64_64bit, -ARCH_ppc_32bit, -ARCH_aarch64_64bit, -ARCH_arm_oabi, -ARCH_arm_eabi, -ARCH_avr32_32bit, -ARCH_arc_32bit, -ARCH_s390x_64bit, -ARCH_s390_32bit, -ARCH_hppa_32bit, -ARCH_sh64_64bit, -ARCH_sh_32bit, -ARCH_x86_64_64bit, -ARCH_x86_64_x32, -ARCH_x86_32bit, -ARCH_cris_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 diff --git a/tools/asinfo/asinfo.1.in b/tools/asinfo/asinfo.1.in new file mode 100644 index 00000000..009c69ed --- /dev/null +++ b/tools/asinfo/asinfo.1.in @@ -0,0 +1,280 @@ +.\" Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...> +.\" Copyright (c) 1996-2017 The strace developers. +.\" 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. + +.\" Required option. +.de OR +. ie \\n(.$-1 \ +. RI "\fB\\$1\fP" "\ \\$2" +. el \ +. BR "\\$1" +.. +.TH ASINFO 1 "@ASINFO_MANPAGE_DATE@" "strace package @VERSION@" +.SH NAME +asinfo \- advanced system call information tool +.SH SYNOPSIS +.SY asinfo +.BR "" \fR[{ +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" } +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR]\fR] +.BR "" { +.BR "" { +.OR \-\-get\-sname expr +.BR "" | +.OR \-\-get\-snum expr +.BR "" } +.OP \-\-nargs +.BR "" } +.OP "\-\-raw" +.YS +.SY asinfo +.BR "" { +.OR \-\-set\-arch arch +.BR "" | +.OR \-\-get\-arch +.BR "" | +.OR \-\-list\-arch +.BR "" } +.BD "" [ +.OR \fR[\fP\-\-set\-abi abi +.BR "" | +.OR \-\-list\-abi\fR] +.OP "\-\-raw" + +.SH DESCRIPTION +.B asinfo +is a useful tool, which aimed to provide information about system calls, +architectures, and application binary interfaces (ABIs). In the simplest +case it provides mapping from system call name to number and reverse. +The main advantage of tool is it can work in single/multi arch modes with +the opportunity to show discrepancies in system call characteristics. +Also, the single arch mode allows program to take a guess about the +current architecture and ABI, if they are not specified. Furthermore, +.B asinfo +provides convenient filtering for selecting system calls. + +.SH OPTIONS +.SS "Architecture parameters" +.TP 7 +.BI "\-\-set\-arch " arch +Specify architecture/architectures manually. The format of the +.I arch +expression is: +.RS 9 +.IP +\fIarch1\/\fR[\fB,\fIarch2\/\fR]... +.RE +.IP +.TP +.B \-\-get\-arch +Select achitecture based on the current machine. +.TP +.B \-\-list-arch +Print out all supported architectures. +Combined use with any ABI option is permitted. +.SS "ABI parameters" +.TP 7 +.BI "\-\-set\-abi " abi +Specify ABI/ABIs manually. The format of the experession is: +.RS 9 +.IP +\fIabi1\/\fR[\fB,\fIabi2\/\fR]... +.RE +.IP +.IP +Note that ABI should be selected for each corresponding architecture. +In addition, the special value +.B all +allows to choose all ABIs for the respective architecture. +.TP +.B "\-\-list\-abi " +Select all ABIs for the chosen architecture/architectures. +.IP +If ABI parameters are not used and only single architecture is selected, tool +will take a guess about ABI based on the strace package build. +.SS "System call parameters" +.TP 7 +.BI "\-\-get\-sname " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out name of system calls and numbers for each architecture/ABI. +.TP +.BI "\-\-get\-snum " expr +Select system calls that satisfy a filtering expression +.I +expr +and print out number of system calls and names for each architecture/ABI. +.TP +.B \-\-nargs +Switch the second output system call characteristic to number of arguments. +.SS Output formatting +.TP 7 +.B "\-\-raw" +Reset alignment and remove titles, use ';' as a delimiter. +.SS Miscellaneous +.TP 7 +.B \-h +Print the help summary. +.TP +.B \-v +Print the version number. + +.SH "FILTERING EXPRESSION" +A filtering expression is a pattern that describes a set of syscall names, +syscall numbers, and syscall group. The format of the expression is: +.RS 2 +.IP +[\fB!\fR][\fB?\fR]\,\fIvalue1\/\fR[\fB,\fR[\fB?\fR]\,\fIvalue2\/\fR]... +.RE +.LP +where +.I value +is a symbol or number. Using an exclamation mark negates the set of values. +For example, +.BR \fIvalue\fR = write +means print strictly the write system call. By contrast, +.BR \fIvalue\fR = !write +means to dump every system call except write. Question mark before the +syscall qualification allows suppression of error in case no syscalls matched +the qualification provided, that can be particularly useful in multiarch mode, +when system call is not presented in all selected architectures. In addition, +the special values +.B all +and +.B none +have the obvious meanings. +.LP +Note that some shells use the exclamation point for history +expansion even inside quoted arguments. If so, you must escape +the exclamation point with a backslash. +.SS "Strict match" +.TP 7 +.B \fIvalue\fR=\,\fIset\fR +Print out only the specified set of system calls. For example, +.BR \fIvalue\fR = open,close,read,write +means to only show those four system calls. +.SS "Regex match" +.TP 7 +.B \fIvalue\fR=/\,\fIregex\fR +Show only those system calls that match the +.IR regex . +You can use +.B POSIX +Extended Regular Expression syntax (see +.BR regex (7)). +.SS "Class match" +.TP 7 +.BR \fIvalue\fR = %file +.TQ +.BR \fIvalue\fR = file " (deprecated)" +Show all system calls which take a file name as an argument. You +can think of this as an abbreviation for +.BR \fIvalue\fR = open,stat,chmod,unlink,... +Furthermore, using the abbreviation will ensure that you don't +accidentally forget to include a call like +.B lstat +in the list. +.PP +.BR \fIvalue\fR = %process +.TQ +.BR \fIvalue\fR = process " (deprecated)" +Show all system calls which involve process management. +.PP +.BR \fIvalue\fR = %network +.TQ +.BR \fIvalue\fR = network " (deprecated)" +Show all the network related system calls. +.PP +.BR \fIvalue\fR = %signal +.TQ +.BR \fIvalue\fR = signal " (deprecated)" +Show all signal related system calls. +.PP +.BR \fIvalue\fR = %ipc +.TQ +.BR \fIvalue\fR = ipc " (deprecated)" +Show all IPC related system calls. +.PP +.BR \fIvalue\fR = %desc +.TQ +.BR \fIvalue\fR = desc " (deprecated)" +Show all file descriptor related system calls. +.PP +.BR \fIvalue\fR = %memory +.TQ +.BR \fIvalue\fR = memory " (deprecated)" +Show all memory mapping related system calls. +.TP +.BR \fIvalue\fR = %stat +Show stat syscall variants. +.TP +.BR \fIvalue\fR = %lstat +Show lstat syscall variants. +.TP +.BR \fIvalue\fR = %fstat +Show fstat and fstatat syscall variants. +.TP +.BR \fIvalue\fR = %%stat +Show syscalls used for requesting file status (stat, lstat, fstat, fstatat, +statx, and their variants). +.TP +.BR \fIvalue\fR = %statfs +Show statfs, statfs64, statvfs, osf_statfs, and osf_statfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /^(.*_)?statv?fs +regular expression. +.TP +.BR \fIvalue\fR = %fstatfs +Show fstatfs, fstatfs64, fstatvfs, osf_fstatfs, and osf_fstatfs64 system calls. +The same effect can be achieved with +.BR \fIvalue\fR = /fstatv?fs +regular expression. +.TP +.BR \fIvalue\fR = %%statfs +Show syscalls related to file system statistics (statfs-like, fstatfs-like, +and ustat). The same effect can be achieved with +.BR \fIvalue\fR = /statv?fs|fsstat|ustat +regular expression. + +.SH "EXIT STATUS" +On success, +.B asinfo +returns 0. Otherwise, in case of wrong input or no matches found, 1. + +.SH "REPORTING BUGS" +Problems with +.B asinfo +should be reported to the +.B strace +mailing list at <str...@li...>. + +.SH "SEE ALSO" +.BR strace (1) diff --git a/tools/asinfo/gen_asinfo_files.sh b/tools/asinfo/gen_asinfo_files.sh new file mode 100755 index 00000000..bd7b33ae --- /dev/null +++ b/tools/asinfo/gen_asinfo_files.sh @@ -0,0 +1,160 @@ +#!/bin/sh +# +# Code generator simplifies addition of new architecture to asinfo tool +# +# Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...> +# 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. + +cur_pers="" + +gen_pers_line() +{ + local out_file="$1" + local line="$2" + local arch_abi="" + + LC_COLLATE=C + arch_abi="$(printf %s "${line}" | + sed 's/ARCH_DESC_DEFINE(//' | cut -d, -f 1,2 | + sed 's/,/_/g')" + cur_pers="${arch_abi}" + echo "ARCH_${arch_abi}," >> "${out_file}" +} + +gen_includes_block() +{ + local out_file="$1" + local line="$2" + local def is_def includes include nums num count + + ( + LC_COLLATE=C + echo "/* ${cur_pers} */" + def="$(printf %s "${line#*\*}" | cut -d] -f 1 | sed 's/.*[][]//g')" + #Generate define construction + if [ "${def#!}" != "" ] && [ $(printf %.1s "${def}") = "!" ]; then + cat <<-EOF + #ifdef ${def#!} + # undef ${def#!} + # define ${def#!}_DUMMY_UNDEFINE + #endif + EOF + is_def="def" + else if [ "${def#!}" != "" ]; then + cat <<-EOF + #ifndef ${def} + # define ${def} + # define ${def}_DUMMY_DEFINE + #endif + EOF + is_def="undef" + fi + fi + #Generate includes + includes="$(printf %s "${line#*\*}" | cut -d] -f 2 | sed 's/.*[][]//g')" + echo "static const struct_sysent ${cur_pers}_sysent[] = {" + for include in $(echo "${includes}" | sed "s/,/ /g") + do + echo " #include \"${include}\"" + done + echo "};" + #Undefine definitions, if it is required + if [ "${is_def}" = "def" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_UNDEFINE + # define ${def#!} 1 + # undef ${def#!}_DUMMY_UNDEFINE + #endif + EOF + else if [ "${is_def}" = "undef" ]; then + cat <<-EOF + #ifdef ${def#!}_DUMMY_DEFINE + # undef ${def#!} + # undef ${def#!}_DUMMY_DEFINE + #endif + EOF + fi + fi + #Generate arch specific numbers + nums="$(printf %s "${line#*\*}" | cut -d] -f 3 | sed 's/.*[][]//g')" + count=1 + for num in $(echo "${nums}" | sed "s/,/ /g") + do + echo "static const int ${cur_pers}_usr${count} = ${num};" + count=$((count+1)) + case "${num}" in + *[A-Za-z_]*) echo "#undef ${num}" ;; + *) ;; + esac + done + if [ $count -eq 1 ]; then + echo "static const int ${cur_pers}_usr${count} = 0;" + fi + echo "#undef SYS_socket_subcall" + ) >> "${out_file}" + echo "${def}" >> "${out_file}" +} + +main() +{ + set -- "${0%/*}" "${0%/*}" + + local input="$1" + local output="$2" + local defs_file="arch_definitions.h" + local pers_file="arch_personalities.h" + local includes_file="arch_includes.h" + local pline="" + + echo "ARCH_no_pers," > "${output}/${pers_file}" + echo -n > "${output}/${includes_file}" + + #Main work + while read line; do + line="$(printf %s "${line}" | sed 's/[[:space:]]//g')" + if $(printf %s "${line}" | + grep -F "ARCH_DESC_DEFINE" > /dev/null); then + gen_pers_line "${output}/${pers_file}" "${line}" + fi + if $(printf %s "${pline}" | grep -F "/*" > /dev/null); then + gen_includes_block "${output}/${includes_file}"\ + "${pline}" + fi + pline="${line}" + done < "${input}/${defs_file}" + #Makemodule.am + ( + printf "ARCH_AUX_FILES = ${includes_file} ${pers_file}" + echo + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${includes_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + printf '\$(top_srcdir)/tools/asinfo/%s: \$(top_srcdir)/tools/asinfo/%s \$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' "${pers_file}" "${defs_file}" + echo + echo ' \$(AM_V_GEN)\$(top_srcdir)/tools/asinfo/gen_asinfo_files.sh' + ) > "${output}/Makemodule.am" +} + +main "$@" -- 2.11.0 |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:06
|
The main purpose of this query tool is to present all information concluded
at sysent.h files in a convenient way.
The asinfo tool has the following staged architecture:
(command dispatcher)->(architecture dispatcher)->
(abi dispatcher)->(system call dispatcher).
Each dispatcher accepts proccesed data from the previous one.
This point can be illustrated by the following example:
$ asinfo --get-arch --get-sname write
First of all, arch_dispatcher will return the current architecture, based on
uname return value, after that in case of no options for abi_dispatcher,
it perceives empty parameter as get-abi parameter and returns ABI mode set at
compile time of strace package. Therefore, syscall_dispatcher accepts this
architecture/ABI and works with specific set of system calls. It is worth
mentioning that it supports all architectures/ABIs supported by strace.
Also, tool can work in multi-arch mode. for instance:
$ ./tools/asinfo/asinfo --set-arch mips64,mips --set-abi n64,all
--get-snum 100,8,ipc
For more info, use asinfo -h.
* Makefile.am (SUBDIRS): Add tools directory.
* configure.ac (AC_CONFIG_FILES): Add Makefiles.
* tools/Makefile.am: New file.
* tools/asinfo/Makefile.am: Likewise.
* tools/asinfo/dispatchers.h: New file. Prototype abi_dispatcher,
arch_dispatcher, and syscall_dispatcher.
* tools/asinfo/dispatchers.c: New file. Implement them.
* tools/asinfo/error_interface.h: New file. Introduce error_service to
improve informativeness of output errors. Prototype methods to work with
error_service.
* tools/asinfo/error_interface.c: New file. Implement it.
* tools/asinfo/arch_interface.h: New file. Introduce struct
arch_descriptor. Introduce arch_service. Prototype methods to simplify
work with the arch_service.
* tools/asinfo/arch_interface.c: New file. Implement it.
* tools/asinfo/syscall_interface.h: New file. Introduce syscall_service.
Prototype methods to simplify work with syscall_service.
* tools/asinfo/syscall_interface.c: New file. Implement it.
* tools/asinfo/request_msgs.h: New file. Introduce main requests.
* tools/asinfo/asinfo.c: New file. Implement support of all options.
Implement usage. Implement version.
* tools/asinfo/arch_definitions.h: New file. Introduce useful storage
for architectures.
* tools/asinfo/arch_includes.h: New file.
* tools/asinfo/personalities.h: Likewise.
* tools/asinfo/.gitignore: Likewise.
Signed-off-by: Edgar Kaziakhmedov <edg...@vi...>
---
Makefile.am | 2 +-
configure.ac | 2 +
tools/Makefile.am | 28 ++
tools/asinfo/.gitignore | 2 +
tools/asinfo/Makefile.am | 62 ++++
tools/asinfo/arch_definitions.h | 70 ++++
tools/asinfo/arch_includes.h | 272 +++++++++++++++
tools/asinfo/arch_interface.c | 654 ++++++++++++++++++++++++++++++++++++
tools/asinfo/arch_interface.h | 162 +++++++++
tools/asinfo/arch_personalities.h | 36 ++
tools/asinfo/asinfo.c | 331 ++++++++++++++++++
tools/asinfo/dispatchers.c | 244 ++++++++++++++
tools/asinfo/dispatchers.h | 48 +++
tools/asinfo/error_interface.c | 110 ++++++
tools/asinfo/error_interface.h | 95 ++++++
tools/asinfo/request_msgs.h | 93 ++++++
tools/asinfo/syscall_interface.c | 684 ++++++++++++++++++++++++++++++++++++++
tools/asinfo/syscall_interface.h | 142 ++++++++
18 files changed, 3036 insertions(+), 1 deletion(-)
create mode 100644 tools/Makefile.am
create mode 100644 tools/asinfo/.gitignore
create mode 100644 tools/asinfo/Makefile.am
create mode 100644 tools/asinfo/arch_definitions.h
create mode 100644 tools/asinfo/arch_includes.h
create mode 100644 tools/asinfo/arch_interface.c
create mode 100644 tools/asinfo/arch_interface.h
create mode 100644 tools/asinfo/arch_personalities.h
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/error_interface.c
create mode 100644 tools/asinfo/error_interface.h
create mode 100644 tools/asinfo/request_msgs.h
create mode 100644 tools/asinfo/syscall_interface.c
create mode 100644 tools/asinfo/syscall_interface.h
diff --git a/Makefile.am b/Makefile.am
index e90c7809..1c9c3dac 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 strace-log-merge.1
diff --git a/configure.ac b/configure.ac
index 729ef3f7..0492bd8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -904,6 +904,8 @@ AC_CONFIG_FILES([Makefile
tests-mx32/Makefile
strace.1
strace-log-merge.1
+ 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 <edg...@vi...>
+# 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/.gitignore b/tools/asinfo/.gitignore
new file mode 100644
index 00000000..09400c47
--- /dev/null
+++ b/tools/asinfo/.gitignore
@@ -0,0 +1,2 @@
+asinfo
+asinfo.1
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
new file mode 100644
index 00000000..5051766e
--- /dev/null
+++ b/tools/asinfo/Makefile.am
@@ -0,0 +1,62 @@
+# Automake input for asinfo.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edg...@vi...>
+# 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_LDFLAGS =
+asinfo_LDADD = -L$(top_srcdir) \
+ -L$(top_builddir) \
+ -lcommon
+
+asinfo_SOURCES = \
+ arch_definitions.h \
+ arch_includes.h \
+ arch_interface.c \
+ arch_interface.h \
+ arch_personalities.h \
+ asinfo.c \
+ dispatchers.c \
+ dispatchers.h \
+ error_interface.c \
+ error_interface.h \
+ request_msgs.h \
+ syscall_interface.c \
+ syscall_interface.h \
+ #end of asinfo_SOURCES
diff --git a/tools/asinfo/arch_definitions.h b/tools/asinfo/arch_definitions.h
new file mode 100644
index 00000000..37103160
--- /dev/null
+++ b/tools/asinfo/arch_definitions.h
@@ -0,0 +1,70 @@
+/* [],[bfin/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(blackfin, 32bit, PASS({}), PASS({"blackfin", "bfin"}) ),
+/* [],[ia64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ia64, 64bit, PASS({}), PASS({"ia64"}) ),
+/* [],[m68k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(m68k, 32bit, PASS({}), PASS({"m68k"}) ),
+/* [],[sparc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc64, 64bit, PASS({ARCH_sparc_32bit}), PASS({"sparc64"}) ),
+/* [],[sparc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sparc, 32bit, PASS({}), PASS({"sparc"}) ),
+/* [],[metag/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(metag, 32bit, PASS({}), PASS({"metag"}) ),
+/* [LINUX_MIPSN64],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n64.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n64, PASS({ARCH_mips64_n32, ARCH_mips_o32}), PASS({"mips64", "mips64le"}) ),
+/* [LINUX_MIPSN32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-n32.h],[0,0] */
+ARCH_DESC_DEFINE(mips64, n32, PASS({ARCH_mips_o32}), PASS({}) ),
+/* [LINUX_MIPSO32],[dummy.h,mips/syscallent-compat.h,mips/syscallent-o32.h],[0,0] */
+ARCH_DESC_DEFINE(mips, o32, PASS({}), PASS({"mips", "mipsle"}) ),
+/* [],[alpha/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(alpha, 64bit, PASS({}), PASS({"alpha"}) ),
+/* [],[powerpc64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc64, 64bit, PASS({ARCH_ppc_32bit}), PASS({"ppc64", "ppc64le", "powerpc64"}) ),
+/* [],[powerpc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(ppc, 32bit, PASS({}), PASS({"ppc", "ppcle", "powerpc"}) ),
+/* [],[aarch64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(aarch64, 64bit, PASS({ARCH_arm_eabi}), PASS({"aarch64", "arm64"}) ),
+/* [!__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, oabi, PASS({ARCH_arm_eabi}), PASS({"arm"}) ),
+/* [__ARM_EABI__],[arm/syscallent.h],[ARM_FIRST_SHUFFLED_SYSCALL,ARM_LAST_SPECIAL_SYSCALL] */
+ARCH_DESC_DEFINE(arm, eabi, PASS({}), PASS({}) ),
+/* [],[avr32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(avr32, 32bit, PASS({}), PASS({"avr32"}) ),
+/* [],[arc/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(arc, 32bit, PASS({}), PASS({"arc"}) ),
+/* [],[s390x/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390x, 64bit, PASS({}), PASS({"s390x"}) ),
+/* [],[s390/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(s390, 32bit, PASS({}), PASS({"s390"}) ),
+/* [],[hppa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(hppa, 32bit, PASS({}), PASS({"parisc", "hppa"}) ),
+/* [],[sh64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh64, 64bit, PASS({}), PASS({"sh64"}) ),
+/* [],[sh/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(sh, 32bit, PASS({}), PASS({"sh"}) ),
+/* [],[x86_64/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, 64bit, PASS({ARCH_x86_64_x32, ARCH_x86_32bit}), PASS({"x86_64", "amd64", "EM64T"}) ),
+/* [],[x86_64/syscallent2.h],[0,0] */
+ARCH_DESC_DEFINE(x86_64, x32, PASS({ARCH_x86_32bit}), PASS({}) ),
+/* [],[i386/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(x86, 32bit, PASS({}), PASS({"x86", "i386", "i486", "i586", "i686"}) ),
+/* [],[crisv10/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(cris, 32bit, PASS({}), PASS({"cris", "crisv10"}) ),
+/* [],[crisv32/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(crisv32, 32bit, PASS({}), PASS({"crisv32"}) ),
+/* [],[tile/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 64bit, PASS({ARCH_tile_32bit}), PASS({"tile", "tilegx"}) ),
+/* [],[tile/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(tile, 32bit, PASS({}), PASS({"tilepro"}) ),
+/* [],[microblaze/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(microblaze, 32bit, PASS({}), PASS({"microblaze"}) ),
+/* [],[nios2/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(nios2, 32bit, PASS({}), PASS({"nios2"}) ),
+/* [],[or1k/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(openrisc, 32bit, PASS({}), PASS({"openrisc", "or1k"}) ),
+/* [],[xtensa/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(xtensa, 32bit, PASS({}), PASS({"xtensa"}) ),
+/* [],[riscv/syscallent.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 64bit, PASS({ARCH_riscv_32bit}), PASS({"riscv"}) ),
+/* [],[riscv/syscallent1.h],[0,0] */
+ARCH_DESC_DEFINE(riscv, 32bit, PASS({}), PASS({}) )
diff --git a/tools/asinfo/arch_includes.h b/tools/asinfo/arch_includes.h
new file mode 100644
index 00000000..e73a8328
--- /dev/null
+++ b/tools/asinfo/arch_includes.h
@@ -0,0 +1,272 @@
+/* ARCH_blackfin */
+static const struct_sysent blackfin_32bit_sysent[] = {
+ #include "bfin/syscallent.h"
+};
+static const int blackfin_32bit_usr1 = 0;
+const int blackfin_32bit_usr2 = 0;
+/* ARCH_ia64 */
+struct_sysent ia64_64bit_sysent[] = {
+ #include "ia64/syscallent.h"
+};
+static const int ia64_64bit_usr1 = 0;
+static const int ia64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_m68k */
+static const struct_sysent m68k_32bit_sysent[] = {
+ #include "m68k/syscallent.h"
+};
+static const int m68k_32bit_usr1 = 0;
+static const int m68k_32bit_usr2 = 0;
+/* ARCH_sparc64 64bit ABI */
+static const struct_sysent sparc64_64bit_sysent[] = {
+ #include "sparc64/syscallent.h"
+};
+static const int sparc64_64bit_usr1 = 0;
+static const int sparc64_64bit_usr2 = 0;
+/* ARCH_sparc and 32bit ABI */
+static const struct_sysent sparc_32bit_sysent[] = {
+ #include "sparc/syscallent.h"
+};
+static const int sparc_32bit_usr1 = 0;
+static const int sparc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_metag */
+static const struct_sysent metag_32bit_sysent[] = {
+ #include "metag/syscallent.h"
+};
+static const int metag_32bit_usr1 = 0;
+static const int metag_32bit_usr2 = 0;
+/* ARCH_mips n64 ABI */
+#ifndef LINUX_MIPSN64
+# define LINUX_MIPSN64 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n64_usr1 = 0;
+static const int mips64_n64_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips n32 ABI */
+#ifndef LINUX_MIPSN32
+# define LINUX_MIPSN32 1
+# define NOW_DEFINED 1
+#endif
+static const struct_sysent mips64_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
+static const int mips64_n32_usr1 = 0;
+static const int mips64_n32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_mips o32 ABI */
+#ifndef LINUX_MIPSO32
+# define LINUX_MIPSO32 1
+# define NOW_DEFINED 1
+#endif
+static const 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
+static const int mips_o32_usr1 = 0;
+static const int mips_o32_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_alpha */
+static const struct_sysent alpha_64bit_sysent[] = {
+ #include "alpha/syscallent.h"
+};
+static const int alpha_64bit_usr1 = 0;
+static const int alpha_64bit_usr2 = 0;
+/* ARCH_ppc64 64bit ABI */
+static const struct_sysent ppc64_64bit_sysent[] = {
+ #include "powerpc64/syscallent.h"
+};
+static const int ppc64_64bit_usr1 = 0;
+static const int ppc64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_ppc and 32bit */
+static const struct_sysent ppc_32bit_sysent[] = {
+ #include "powerpc/syscallent.h"
+};
+static const int ppc_32bit_usr1 = 0;
+static const int ppc_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_aarch64 64bit ABI */
+static const struct_sysent aarch64_64bit_sysent[] = {
+ #include "aarch64/syscallent.h"
+};
+static const int aarch64_64bit_usr1 = 0;
+static const int aarch64_64bit_usr2 = 0;
+/* ARCH_arm OABI*/
+#ifdef __ARM_EABI__
+# undef __ARM_EABI__
+# define NOW_UNDEFINED 1
+#endif
+static const struct_sysent arm_oabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_oabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_oabi_usr2 = ARM_LAST_SPECIAL_SYSCALL;
+#undef ARM_FIRST_SHUFFLED_SYSCALL
+#undef ARM_LAST_SPECIAL_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
+static const struct_sysent arm_eabi_sysent[] = {
+ #include "arm/syscallent.h"
+};
+static const int arm_eabi_usr1 = ARM_FIRST_SHUFFLED_SYSCALL;
+static const int arm_eabi_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 */
+static const struct_sysent avr32_32bit_sysent[] = {
+ #include "avr32/syscallent.h"
+};
+static const int avr32_32bit_usr1 = 0;
+static const int avr32_32bit_usr2 = 0;
+/* ARCH_arc */
+static const struct_sysent arc_32bit_sysent[] = {
+ #include "arc/syscallent.h"
+};
+static const int arc_32bit_usr1 = 0;
+static const int arc_32bit_usr2 = 0;
+/* ARCH_s390x */
+static const struct_sysent s390x_64bit_sysent[] = {
+ #include "s390x/syscallent.h"
+};
+static const int s390x_64bit_usr1 = 0;
+static const int s390x_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_s390 */
+static const struct_sysent s390_32bit_sysent[] = {
+ #include "s390/syscallent.h"
+};
+static const int s390_32bit_usr1 = 0;
+static const int s390_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_hppa */
+static const struct_sysent hppa_32bit_sysent[] = {
+ #include "hppa/syscallent.h"
+};
+static const int hppa_32bit_usr1 = 0;
+static const int hppa_32bit_usr2 = 0;
+/* ARCH_sh64 */
+static const struct_sysent sh64_64bit_sysent[] = {
+ #include "sh64/syscallent.h"
+};
+static const int sh64_64bit_usr1 = 0;
+static const int sh64_64bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_sh */
+static const struct_sysent sh_32bit_sysent[] = {
+ #include "sh/syscallent.h"
+};
+static const int sh_32bit_usr1 = 0;
+static const int sh_32bit_usr2 = 0;
+/* ARCH_x86_64 64bit ABI mode */
+static const struct_sysent x86_64_64bit_sysent[] = {
+ #include "x86_64/syscallent.h"
+};
+static const int x86_64_64bit_usr1 = 0;
+static const int x86_64_64bit_usr2 = 0;
+/* ARCH_x86_64 x32 ABI mode */
+static const struct_sysent x86_64_x32_sysent[] = {
+ #include "x86_64/syscallent2.h"
+};
+static const int x86_64_x32_usr1 = 0;
+static const int x86_64_x32_usr2 = 0;
+/* ARCH_x86 */
+static const struct_sysent x86_32bit_sysent[] = {
+ #include "i386/syscallent.h"
+};
+static const int x86_32bit_usr1 = 0;
+static const int x86_32bit_usr2 = 0;
+/* ARCH_cris */
+static struct_sysent cris_32bit_sysent[] = {
+ #include "crisv10/syscallent.h"
+};
+static const int cris_32bit_usr1 = 0;
+static const int cris_32bit_usr2 = 0;
+/* ARCH_crisv32 */
+static const struct_sysent crisv32_32bit_sysent[] = {
+ #include "crisv32/syscallent.h"
+};
+static const int crisv32_32bit_usr1 = 0;
+static const int crisv32_32bit_usr2 = 0;
+#undef SYS_socket_subcall
+/* ARCH_tile 64bit ABI mode */
+static const struct_sysent tile_64bit_sysent[] = {
+ #include "tile/syscallent.h"
+};
+static const int tile_64bit_usr1 = 0;
+static const int tile_64bit_usr2 = 0;
+/* ARCH_tile 32bit ABI mode */
+static const struct_sysent tile_32bit_sysent[] = {
+ #include "tile/syscallent1.h"
+};
+static const int tile_32bit_usr1 = 0;
+static const int tile_32bit_usr2 = 0;
+/* ARCH_microblaze */
+static const struct_sysent microblaze_32bit_sysent[] = {
+ #include "microblaze/syscallent.h"
+};
+static const int microblaze_32bit_usr1 = 0;
+static const int microblaze_32bit_usr2 = 0;
+/* ARCH_nios2 */
+static const struct_sysent nios2_32bit_sysent[] = {
+ #include "nios2/syscallent.h"
+};
+static const int nios2_32bit_usr1 = 0;
+static const int nios2_32bit_usr2 = 0;
+/* ARCH_openrisc */
+struct_sysent openrisc_32bit_sysent[] = {
+ #include "or1k/syscallent.h"
+};
+static const int openrisc_32bit_usr1 = 0;
+static const int openrisc_32bit_usr2 = 0;
+/* ARCH_xtensa */
+static const struct_sysent xtensa_32bit_sysent[] = {
+ #include "xtensa/syscallent.h"
+};
+static const int xtensa_32bit_usr1 = 0;
+static const int xtensa_32bit_usr2 = 0;
+/* ARCH_riscv 64bit ABI mode */
+static const struct_sysent riscv_64bit_sysent[] = {
+ #include "riscv/syscallent.h"
+};
+static const int riscv_64bit_usr1 = 0;
+static const int riscv_64bit_usr2 = 0;
+/* ARCH_riscv 32bit ABI mode */
+static const struct_sysent riscv_32bit_sysent[] = {
+ #include "riscv/syscallent1.h"
+};
+static const int riscv_32bit_usr1 = 0;
+static const int riscv_32bit_usr2 = 0;
diff --git a/tools/asinfo/arch_interface.c b/tools/asinfo/arch_interface.c
new file mode 100644
index 00000000..8e02ffd0
--- /dev/null
+++ b/tools/asinfo/arch_interface.c
@@ -0,0 +1,654 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 <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. */
+#include "sysent_shorthand_defs.h"
+
+/* For the current functionality there is no need
+ to use sen and (*sys_func)() fields in sysent struct */
+#define SEN(syscall_name) 0, NULL
+
+/* Generated file based on arch_definitions.h */
+#include "arch_includes.h"
+
+/* Now undef them since short defines cause wicked namespace pollution. */
+#include "sysent_shorthand_undefs.h"
+
+#define PASS(...) __VA_ARGS__
+#define ARCH_DESC_DEFINE(arch, mode, comp_pers, arch_aliases) \
+ [ARCH_##arch##_##mode] = { \
+ .pers = ARCH_##arch##_##mode, \
+ .arch_name = arch_aliases, \
+ .abi_mode = #mode, \
+ .abi_mode_len = ARRAY_SIZE(#arch) - 1, \
+ .compat_pers = comp_pers, \
+ .max_scn = ARRAY_SIZE(arch##_##mode##_sysent), \
+ .syscall_list = arch##_##mode##_sysent, \
+ .user_num1 = &arch##_##mode##_usr1, \
+ .user_num2 = &arch##_##mode##_usr2, \
+ }
+
+/* Generate array of arch_descriptors for each personality */
+const struct arch_descriptor architectures[] = {
+ #include "arch_definitions.h"
+};
+
+#undef ARCH_DESC_DEFINE
+#undef PASS
+
+struct arch_service *
+al_create(unsigned capacity)
+{
+ ARCH_LIST_DEFINE(as) = NULL;
+
+ if (!capacity)
+ return NULL;
+ as = xcalloc(sizeof(*as), 1);
+ as->arch_list = xcalloc(sizeof(*(as->arch_list)), capacity);
+ as->flag = xcalloc(sizeof(*(as->flag)), capacity);
+ as->in_aname = xcalloc(sizeof(*(as->in_aname)), capacity);
+ as->err = es_create();
+ as->capacity = capacity;
+ as->next_free = 0;
+ return as;
+}
+
+int
+al_push(struct arch_service *m, const struct arch_descriptor *element)
+{
+ if (m->next_free >= m->capacity)
+ return -1;
+ m->arch_list[m->next_free] = element;
+ m->flag[m->next_free] = AD_FLAG_EMPTY;
+ 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->flag[index] = flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_add_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] | flag;
+ return 0;
+ }
+ return -1;
+}
+
+int
+al_sub_flag(struct arch_service *m, unsigned index, int flag)
+{
+ if (al_is_index_ok(m, index) == 0) {
+ m->flag[index] = m->flag[index] & ~flag;
+ return 0;
+ }
+ return -1;
+}
+
+const 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;
+}
+
+void
+al_free(struct arch_service *m)
+{
+ int i;
+ int size = al_size(m);
+
+ for (i = 0; i < size; i++)
+ if (al_in_aname(m, i) != NULL)
+ free(al_in_aname(m, i));
+ free(m->arch_list);
+ free(m->flag);
+ free(m->in_aname);
+ es_free(m->err);
+ free(m);
+}
+
+struct error_service *al_err(struct arch_service *m)
+{
+ return m->err;
+}
+
+enum arch_pers
+al_pers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->pers : ARCH_no_pers);
+}
+
+const char **
+al_arch_name(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (const char **)elem->arch_name : NULL);
+}
+
+enum arch_pers *
+al_cpers(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? (enum arch_pers *)elem->compat_pers : NULL);
+}
+
+const char *
+al_abi_mode(struct arch_service *m, unsigned index)
+{
+ const 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)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+
+ return (elem ? elem->abi_mode_len : -1);
+}
+
+int
+al_flag(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->flag[index] : -1);
+}
+
+int
+al_set_in_aname(struct arch_service *m, unsigned index, char *aname)
+{
+ int status = al_is_index_ok(m, index);
+
+ if (status)
+ return -1;
+ m->in_aname[index] = aname;
+ return 0;
+}
+
+char *
+al_in_aname(struct arch_service *m, unsigned index)
+{
+ int status = al_is_index_ok(m, index);
+
+ return (!status ? m->in_aname[index] : NULL);
+}
+
+int
+al_psize(struct arch_service *m)
+{
+ int i;
+ int a_size = al_size(m);
+ int psize = 0;
+
+ for (i = 0; i < a_size; i++)
+ if (al_flag(m, i) & AD_FLAG_PRINT)
+ psize++;
+ return psize;
+}
+
+int
+al_arch_name_len(struct arch_service *m, unsigned index, int delim_len)
+{
+ const char **arch_name = NULL;
+ int i;
+ int final_len = 0;
+
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ for (i = 0; (arch_name[i] != NULL) && (i < MAX_ALIASES); i++) {
+ final_len += strlen(arch_name[i]);
+ final_len += delim_len;
+ }
+ final_len -= delim_len;
+ return final_len;
+}
+
+int
+al_syscall_impl(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name &&
+ !(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ count++;
+ }
+ return count;
+}
+
+/* This method is purposed to count the supported ABI modes for the given
+ arch */
+int
+al_get_abi_modes(struct arch_service *m, unsigned index)
+{
+ const struct arch_descriptor *elem = al_get(m, index);
+ int i = 0;
+ int abi_count = 1;
+
+ if (!elem)
+ return -1;
+ for (i = 0; i < MAX_ALT_ABIS; i++)
+ if (elem->compat_pers[i] != ARCH_no_pers)
+ abi_count++;
+ return abi_count;
+}
+
+/* This method is purposed to find next one name of the same architecture.
+ For instance, x86_64 = amd64 */
+const char *
+al_next_alias(struct arch_service *m, unsigned index)
+{
+ static int next_alias = -1;
+ static const char **arch_name = NULL;
+ static unsigned lindex = 0;
+
+ if (lindex != index) {
+ lindex = index;
+ next_alias = -1;
+ }
+ if (al_pers(m, index) == ARCH_no_pers)
+ return NULL;
+ if (next_alias == -1) {
+ next_alias = 0;
+ while (!(al_flag(m, index) & AD_FLAG_MPERS))
+ index--;
+ arch_name = al_arch_name(m, index);
+ } else
+ next_alias++;
+ if (next_alias >= MAX_ALIASES || arch_name[next_alias] == NULL) {
+ next_alias = -1;
+ return NULL;
+ }
+ return arch_name[next_alias];
+}
+
+/* This method is purposed to return next one compat personality of the
+ same architecture */
+enum arch_pers
+al_next_cpers(struct arch_service *m, unsigned index)
+{
+ static int next_pers = -1;
+ enum arch_pers *a_pers = al_cpers(m, index);
+ static unsigned lindex = 0;
+
+ if (al_pers(m, index) == ARCH_no_pers)
+ return ARCH_no_pers;
+ if (lindex != index) {
+ lindex = index;
+ next_pers = -1;
+ }
+ if (next_pers == -1)
+ next_pers = 0;
+ else
+ next_pers++;
+ if (next_pers >= MAX_ALT_ABIS ||
+ a_pers[next_pers] == ARCH_no_pers) {
+ next_pers = -1;
+ return ARCH_no_pers;
+ }
+ return a_pers[next_pers];
+}
+
+enum impl_type
+al_ipc_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just semop sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "semop")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+enum impl_type
+al_sck_syscall(struct arch_service *m, unsigned index)
+{
+ const 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->syscall_list[i].sys_name == NULL)
+ continue;
+ /* It is enough to find just socket sybcall */
+ if (!strcmp(elem->syscall_list[i].sys_name, "socket")) {
+ if (!(elem->syscall_list[i].sys_flags &
+ TRACE_INDIRECT_SUBCALL))
+ impl_buf = IMPL_ext;
+ else if (impl_buf == IMPL_ext)
+ impl_buf = IMPL_int_ext;
+ else
+ impl_buf = IMPL_int;
+ }
+ }
+ return impl_buf;
+}
+
+/* This method is purposed to create extended list of architectures */
+struct arch_service *
+al_create_filled(void)
+{
+ static const int architectures_size = ARRAY_SIZE(architectures) - 1;
+ ARCH_LIST_DEFINE(as) = al_create(architectures_size);
+ ARCH_LIST_DEFINE(f_as);
+ enum arch_pers cpers;
+ int esize = 0;
+ const char **arch_name = NULL;
+ int i;
+
+ /* Push and calculate size of extended table */
+ for (i = 0; i < architectures_size; i++) {
+ al_push(as, &(architectures[i + 1]));
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] != NULL)
+ esize += al_get_abi_modes(as, i);
+ }
+ f_as = al_create(esize);
+ /* Fill extended teble */
+ for (i = 0; i < architectures_size; i++) {
+ arch_name = al_arch_name(as, i);
+ if (arch_name[0] == NULL)
+ continue;
+ al_push(f_as, al_get(as, i));
+ al_add_flag(f_as, al_size(f_as) - 1, AD_FLAG_MPERS);
+ while ((cpers = al_next_cpers(as, i)) != ARCH_no_pers)
+ al_push(f_as, &(architectures[cpers]));
+ }
+ free(as);
+ return f_as;
+}
+
+/* To look up arch in arch_descriptor array */
+int
+al_mark_matches(struct arch_service *m, char *arch_str)
+{
+ int arch_match = -1;
+ char *match_pointer = NULL;
+ const char *a_name = NULL;
+ int al_size_full = al_size(m);
+ unsigned prev_arch_len = 0;
+ int i;
+ int a_abi;
+ char *in_aname;
+
+ if (arch_str == NULL)
+ return -1;
+ /* Here we find the best match for arch_str in architecture list.
+ Best match means here that we have to find the longest name of
+ architecture in a_full_list with arch_str substring, beginning
+ from the first letter */
+ for (i = 0; i < al_size_full; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_MPERS))
+ continue;
+ while ((a_name = al_next_alias(m, i)) != NULL) {
+ match_pointer = strstr(arch_str, a_name);
+ if (match_pointer == NULL || match_pointer != arch_str)
+ continue;
+ if (arch_match == -1 ||
+ strlen(a_name) > prev_arch_len) {
+ prev_arch_len = strlen(a_name);
+ arch_match = i;
+ }
+ }
+ }
+ if (arch_match == -1)
+ return -1;
+ /* Now we find all ABI modes related to the architecture */
+ if ((a_abi = al_get_abi_modes(m, arch_match)) == -1)
+ return -1;
+ for (i = arch_match; i < (arch_match + a_abi); i++) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ in_aname = xcalloc(sizeof(*in_aname), strlen(arch_str) + 1);
+ strcpy(in_aname, arch_str);
+ al_set_in_aname(m, i, in_aname);
+ }
+ return 0;
+}
+
+/* Join all architectures from 'f' and architectures with AD_FLAG_PRINT
+ from 's' arch_service structures */
+struct arch_service *
+al_join_print(struct arch_service *f, struct arch_service *s)
+{
+ int size1 = (f ? al_size(f) : 0);
+ int psize2 = al_psize(s);
+ int size2 = al_size(s);
+ int i;
+ int start_point = 0;
+ ARCH_LIST_DEFINE(final) = al_create(size1 + psize2);
+
+ for (i = 0; i < size2; i++)
+ if (al_flag(s, i) & AD_FLAG_PRINT) {
+ start_point = i;
+ break;
+ }
+ for (i = 0; i < size1; i++) {
+ al_push(final, al_get(f, i));
+ al_set_flag(final, i, al_flag(f, i));
+ al_set_in_aname(final, i, al_in_aname(f, i));
+ al_set_in_aname(f, i, NULL);
+ }
+ for (i = 0; i < psize2; i++) {
+ al_push(final, al_get(s, start_point + i));
+ al_set_flag(final, size1 + i , al_flag(s, start_point + i));
+ al_set_in_aname(final, size1 + i,
+ al_in_aname(s, start_point + i));
+ al_set_in_aname(s, start_point + i, NULL);
+ al_sub_flag(s, start_point + i, AD_FLAG_PRINT);
+ }
+ if (f)
+ al_free(f);
+ return final;
+}
+
+/* To avoid duplication of for(;;) construction */
+void
+al_unmark_all(struct arch_service *m, int flag)
+{
+ int a_size = al_size(m);
+ int i;
+
+ for (i = 0; i < a_size; i++)
+ al_sub_flag(m, i, flag);
+}
+
+/* Select one compatible personality in range of one architecture */
+int
+al_mark_pers4arch(struct arch_service *m, unsigned index, const char *abi_mode)
+{
+ unsigned i = index;
+
+ while (!(al_flag(m, i) & AD_FLAG_MPERS) || (i == index)) {
+ if (strcmp(abi_mode, "all") == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ i++;
+ if ((al_is_index_ok(m, i)) ||
+ (al_flag(m, i) & AD_FLAG_MPERS))
+ return 0;
+ else
+ continue;
+ }
+ if (strcmp(al_abi_mode(m, i), abi_mode) == 0) {
+ al_add_flag(m, i, AD_FLAG_PRINT);
+ return 0;
+ }
+ i++;
+ }
+ return -1;
+}
+
+void
+al_dump(struct arch_service *m, int is_raw)
+{
+ static const char *title[] = {
+ "N",
+ "Architecture name",
+ "ABI mode",
+ /* Implemented syscalls */
+ "IMPL syscalls",
+ /* IPC implementation */
+ "IPC IMPL",
+ /* SOCKET implementation */
+ "SOCKET IMPL"
+ };
+ int title_len[] = {
+ 0,
+ strlen(title[1]),
+ strlen(title[2]),
+ strlen(title[3]),
+ strlen(title[4]),
+ strlen(title[5]),
+ };
+ static const char *impl_st[] = {
+ "external",
+ "internal",
+ "int/ext"
+ };
+ static const char *delim = "/";
+ int i = 0;
+ int N = 0;
+ int temp_len = 0;
+ int arch_size = al_size(m);
+ int arch_psize = al_psize(m);
+ const char *next_alias = NULL;
+ char *whole_arch_name;
+
+ /* Calculate length of the column with the number of architectures */
+ for (i = 1; arch_psize/i != 0; i *= 10)
+ title_len[0]++;
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ /* Calculate length of the column with the
+ architectures name */
+ temp_len = al_arch_name_len(m, i, strlen(delim));
+ if (temp_len > title_len[1])
+ title_len[1] = temp_len;
+ /* Calculate length of the column with the ABI mode */
+ if (al_abi_mode_len(m, i) > title_len[2])
+ title_len[2] = al_abi_mode_len(m, i);
+ }
+
+ whole_arch_name = xcalloc(title_len[1], sizeof(*whole_arch_name));
+ /* Output title */
+ if (!is_raw)
+ printf("| %*s | %*s | %*s | %*s | %*s | %*s |\n",
+ title_len[0], title[0], title_len[1], title[1],
+ title_len[2], title[2], title_len[3], title[3],
+ title_len[4], title[4], title_len[5], title[5]);
+ /* Output architectures */
+ for (i = 0; i < arch_size; i++) {
+ if (!(al_flag(m, i) & AD_FLAG_PRINT))
+ continue;
+ N++;
+ memset(whole_arch_name, 0, title_len[1]);
+ /* Put all the same arch back together */
+ next_alias = al_next_alias(m, i);
+ strcat(whole_arch_name, next_alias);
+ while ((next_alias = al_next_alias(m, i)) != NULL) {
+ strcat(whole_arch_name, delim);
+ strcat(whole_arch_name, next_alias);
+ }
+ if (is_raw) {
+ printf("%u;%s;%s;%d;%s;%s;\n", N, whole_arch_name,
+ al_abi_mode(m, i), al_syscall_impl(m, i),
+ impl_st[al_ipc_syscall(m, i)],
+ impl_st[al_ipc_syscall(m, i)]);
+ continue;
+ }
+ printf("| %*u | ", title_len[0], N);
+ printf("%*s | ", title_len[1], whole_arch_name);
+ printf("%*s | ", title_len[2], al_abi_mode(m, i));
+ printf("%*d | ", title_len[3], al_syscall_impl(m, i));
+ printf("%*s | ", title_len[4], impl_st[al_ipc_syscall(m, i)]);
+ printf("%*s |\n", title_len[5], impl_st[al_sck_syscall(m, i)]);
+ }
+ free(whole_arch_name);
+}
diff --git a/tools/asinfo/arch_interface.h b/tools/asinfo/arch_interface.h
new file mode 100644
index 00000000..1e7123fc
--- /dev/null
+++ b/tools/asinfo/arch_interface.h
@@ -0,0 +1,162 @@
+/*
+ * 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 <edg...@vi...>
+ * 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_H
+#define ASINFO_ARCH_INTERFACE_H
+
+#include "error_interface.h"
+#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 personalities
+ * arch_pers = ARCH_ + kernel_kernel/other_name + abi_mode */
+enum arch_pers {
+ #include "arch_personalities.h"
+};
+
+#define MAX_ALIASES 6
+#define MAX_ALT_ABIS 3
+
+struct arch_descriptor {
+ enum arch_pers pers;
+ const char *arch_name[MAX_ALIASES];
+ const char *abi_mode;
+ const int abi_mode_len;
+ enum arch_pers compat_pers[MAX_ALT_ABIS];
+ const int max_scn;
+ const struct_sysent *syscall_list;
+ /* In the most cases these fields are purposed to store specific for
+ given arch constants, for instance, ARM_FIRST_SHUFFLED_SYSCALL */
+ const int *user_num1;
+ const int *user_num2;
+};
+
+#define AD_FLAG_EMPTY 0
+/* to hide some abi modes belonging to one architecture */
+#define AD_FLAG_PRINT (1 << 0)
+/* main personality, like x86_64 64bit */
+#define AD_FLAG_MPERS (1 << 1)
+
+/* To provide push-back interface with arch_list */
+struct arch_service {
+ /* immutable field */
+ const struct arch_descriptor **arch_list;
+ /* User flags for each arch_descriptor */
+ int *flag;
+ /* To support conformity between ABI and ARCH */
+ char **in_aname;
+ struct error_service *err;
+ 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 capacity);
+
+int al_push(struct arch_service *m, const struct arch_descriptor *element);
+
+int al_set_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_add_flag(struct arch_service *m, unsigned index, int flag);
+
+int al_sub_flag(struct arch_service *m, unsigned index, int flag);
+
+const struct arch_descriptor *al_get(struct arch_service *m, unsigned index);
+
+unsigned int al_size(struct arch_service *m);
+
+void al_free(struct arch_service *m);
+
+struct error_service *al_err(struct arch_service *m);
+
+/* methods returning fields with error check */
+enum arch_pers al_pers(struct arch_service *m, unsigned index);
+
+const char **al_arch_name(struct arch_service *m, unsigned index);
+
+enum arch_pers *al_cpers(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);
+
+int al_set_in_aname(struct arch_service *m, unsigned index, char *aname);
+
+char *al_in_aname(struct arch_service *m, unsigned index);
+
+/* calculating methods */
+int al_psize(struct arch_service *m);
+
+int al_arch_name_len(struct arch_service *m, unsigned index, int delim_len);
+
+int al_syscall_impl(struct arch_service *m, unsigned index);
+
+int al_get_abi_modes(struct arch_service *m, unsigned index);
+
+const char *al_next_alias(struct arch_service *m, unsigned index);
+
+enum arch_pers al_next_cpers(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);
+
+struct arch_service *al_create_filled(void);
+
+int al_mark_matches(struct arch_service *m, char *arch_str);
+
+struct arch_service *al_join_print(struct arch_service *f,
+ struct arch_service *s);
+
+void al_unmark_all(struct arch_service *m, int flag);
+
+int al_mark_pers4arch(struct arch_service *m, unsigned index,
+ const char *abi_mode);
+
+void al_dump(struct arch_service *m, int is_raw);
+
+#endif /* !ASINFO_ARCH_INTERFACE_H */
diff --git a/tools/asinfo/arch_personalities.h b/tools/asinfo/arch_personalities.h
new file mode 100644
index 00000000..9499c5aa
--- /dev/null
+++ b/tools/asinfo/arch_personalities.h
@@ -0,0 +1,36 @@
+ARCH_no_pers,
+ARCH_blackfin_32bit,
+ARCH_ia64_64bit,
+ARCH_m68k_32bit,
+ARCH_sparc64_64bit,
+ARCH_sparc_32bit,
+ARCH_metag_32bit,
+ARCH_mips64_n64,
+ARCH_mips64_n32,
+ARCH_mips_o32,
+ARCH_alpha_64bit,
+ARCH_ppc64_64bit,
+ARCH_ppc_32bit,
+ARCH_aarch64_64bit,
+ARCH_arm_oabi,
+ARCH_arm_eabi,
+ARCH_avr32_32bit,
+ARCH_arc_32bit,
+ARCH_s390x_64bit,
+ARCH_s390_32bit,
+ARCH_hppa_32bit,
+ARCH_sh64_64bit,
+ARCH_sh_32bit,
+ARCH_x86_64_64bit,
+ARCH_x86_64_x32,
+ARCH_x86_32bit,
+ARCH_cris_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
diff --git a/tools/asinfo/asinfo.c b/tools/asinfo/asinfo.c
new file mode 100644
index 00000000..9b1ac9e5
--- /dev/null
+++ b/tools/asinfo/asinfo.c
@@ -0,0 +1,331 @@
+/*
+ * 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 <edg...@vi...>
+ * 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 <ctype.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_interface.h"
+#include "error_prints.h"
+#include "macros.h"
+#include "request_msgs.h"
+#include "syscall_interface.h"
+#include "xmalloc.h"
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
+
+static void
+usage(void)
+{
+ puts(
+ "usage: asinfo (--set-arch arch | --get-arch | --list-arch)\n"
+ " [--set-abi abi | --list-abi] [--raw]\n"
+ " or: asinfo [(--set-arch arch | --get-arch) [--set-abi abi | --list-abi]]\n"
+ " ((--get-sname expr | --get-snum expr) [--nargs]) [--raw]\n"
+ "\n"
+ "Architecture:\n"
+ " --set-arch arch use architecture ARCH for further work\n"
+ " argument format: arch1,arch2,...\n"
+ " --get-arch use architecture returned by uname for further work\n"
+ " --list-arch print out all architectures supported by strace\n"
+ " (combined use list-arch and any ABI option is permitted)\n"
+ "\n"
+ "ABI:\n"
+ " --set-abi abi use application binary interface ABI for further work\n"
+ " ('all' can be used as ABI to use all compatible personalities\n"
+ " for corresponding architecture)\n"
+ " argument format: abi1,abi2,...\n"
+ " --list-abi use all ABIs for specified architecture\n"
+ "\n"
+ "System call:\n"
+ " --get-sname expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall name | snum1 | snum2 | ...\n"
+ " --get-snum expr print all system calls that satisfy a filtering expression:\n"
+ " [!]all or [!][?]val1[,[?]val2]...\n"
+ " with the following format:\n"
+ " | N | syscall number | sname1 | sname2 | ...\n"
+ " --nargs change output format as follows:\n"
+ " | N | syscall name or number | nargs1 | sname2 | ...\n"
+ "\n"
+ "Output formatting:\n"
+ " --raw reset alignment and remove titles, use ';' as a delimiter\n"
+ "\n"
+ "Miscellaneous:\n"
+ " -h print help message\n"
+ " -v print version");
+ exit(0);
+}
+
+static void
+print_version(void)
+{
+ printf("asinfo (%s package) -- version %s\n"
+ "Copyright (c) 1991-%s The strace developers <%s>.\n"
+ "This is free software; see the source for copying conditions. There is NO\n"
+ "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+ PACKAGE_NAME, PACKAGE_VERSION, COPYRIGHT_YEAR, PACKAGE_URL);
+ exit(0);
+}
+
+void
+die(void)
+{
+ exit(1);
+}
+
+static int
+is_more1bit(unsigned int num)
+{
+ return !(num & (num - 1));
+}
+
+static unsigned
+strpar2req(char *option)
+{
+ /* Convertion table to store string with options */
+ static const char *options[] = {
+ [SD_REQ_GET_SNAME_BIT] = "--get-sname",
+ [SD_REQ_GET_SNUM_BIT] = "--get-snum",
+ [SD_REQ_NARGS_BIT] = "--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_BIT] = "--set-abi",
+ [ABD_REQ_LIST_ABI_BIT] = "--list-abi",
+ [SERV_REQ_RAW_BIT] = "--raw",
+ [SERV_REQ_HELP_BIT] = "-h",
+ [SERV_REQ_VERSION_BIT] = "-v"
+ };
+ unsigned i;
+
+ for (i = 0; i < ARRAY_SIZE(options); i++) {
+ if (options[i] && strcmp(option, options[i]) == 0)
+ return i;
+ }
+ return SERV_REQ_ERROR_BIT;
+}
+
+static char **
+arg2list(char *argument)
+{
+ int i;
+ int len = strlen(argument);
+ int occur = 1;
+ char **arg_list;
+
+ for (i = 0; i < len; i++) {
+ if (argument[i] == ',') {
+ if (i == 0 || i == len - 1 || argument[i + 1] == ',')
+ return NULL;
+ occur++;
+ }
+ }
+ arg_list = xcalloc(sizeof(*arg_list), occur + 1);
+ for (i = 0; i < occur; i++) {
+ arg_list[i] = argument;
+ argument = strchr(argument, ',');
+ if (argument) {
+ *argument = '\0';
+ argument++;
+ }
+ }
+ return arg_list;
+}
+
+/* The purpose of this function is to convert input parameters to number with
+ set bits, where each bit means specific work mode. Moreover, it checks input
+ for correctness and outputs error messages in case of wrong input */
+static unsigned
+command_dispatcher(int argc, char *argv[], char **args[])
+{
+ int i;
+ unsigned final_req = 0;
+ unsigned temp_req = 0;
+ int mult_arch = 0;
+ int mult_abi = 0;
+ unsigned non_req_arg = AD_REQ_GET_ARCH | AD_REQ_LIST_ARCH |
+ ABD_REQ_LIST_ABI | SD_REQ_NARGS |
+ SERV_REQ_RAW;
+
+ if (!program_invocation_name || !*program_invocation_name) {
+ static char name[] = "asinfo";
+ program_invocation_name =
+ (argv[0] && *argv[0]) ? argv[0] : name;
+ }
+
+ /* Try to find help or version parameter first */
+ for (i = 1; i < argc; i++) {
+ if (strpar2req(argv[i]) == SERV_REQ_HELP_BIT)
+ usage();
+ if (strpar2req(argv[i]) == SERV_REQ_VERSION_BIT)
+ print_version();
+ }
+ /* For now, is is necessary to convert string parameter to number of
+ request and make basic check */
+ for (i = 1; i < argc; i++) {
+ if ((temp_req = strpar2req(argv[i])) == SERV_REQ_ERROR_BIT)
+ error_msg_and_help("unrecognized option '%s'",
+ argv[i]);
+ if (final_req & 1 << temp_req)
+ error_msg_and_help("parameter '%s' has been used "
+ "more than once", argv[i]);
+ if (!((1 << temp_req) & non_req_arg) &&
+ (i + 1 >= argc || strlen(argv[i + 1]) == 0 ||
+ strpar2req(argv[i + 1]) != SERV_REQ_ERROR_BIT))
+ error_msg_and_help("parameter '%s' requires "
+ "argument", argv[i]);
+ final_req |= 1 << temp_req;
+ if (!((1 << temp_req) & non_req_arg)) {
+ if ((1 << temp_req) & SD_REQ_MASK) {
+ args[temp_req] = &argv[i + 1];
+ i++;
+ continue;
+ }
+ if ((args[temp_req] = arg2list(argv[i + 1])) != NULL) {
+ i++;
+ continue;
+ }
+ error_msg_and_help("argument '%s' of '%s' parameter "
+ "has a wrong format",
+ argv[i + 1], argv[i]);
+ }
+ }
+ /* Count our multuarchness */
+ if (args[AD_REQ_SET_ARCH_BIT])
+ while (args[AD_REQ_SET_ARCH_BIT][mult_arch] != NULL)
+ mult_arch++;
+ if (args[ABD_REQ_SET_ABI_BIT])
+ while (args[ABD_REQ_SET_ABI_BIT][mult_abi] != NULL)
+ mult_abi++;
+ /* final_req should be logically checked */
+ /* More than one option from one request group couldn't be set */
+ if ((is_more1bit(final_req & SD_REQ_MASK & ~SD_REQ_NARGS) == 0) ||
+ (is_more1bit(final_req & AD_REQ_MASK) == 0) ||
+ (is_more1bit(final_req & ABD_REQ_MASK) == 0))
+ error_msg_and_help("exclusive parameters");
+ /* Check on mutually exclusive options chain */
+ /* If at least one syscall option has been typed, therefore
+ arch_options couldn't be list-arch and
+ abi_option couldn't be list-abi */
+ if ((final_req & SD_REQ_MASK) &&
+ (((final_req & AD_REQ_MASK) && (final_req & AD_REQ_LIST_ARCH))))
+ error_msg_and_help("wrong parameters");
+ /* list-arch couldn't be used with any abi options */
+ if ((final_req & AD_REQ_LIST_ARCH) &&
+ (final_req & ABD_REQ_MASK))
+ error_msg_and_help("'--list-arch' cannot be used with any "
+ "ABI parameters");
+ /* ABI requests could be used just in a combination with arch
+ requests */
+ if ((final_req & ABD_REQ_MASK) &&
+ !(final_req & AD_REQ_MASK))
+ error_msg_and_help("ABI parameters could be used only with "
+ "architecture parameter");
+ /* set-abi must be used in case of multiple arch */
+ if ((mult_arch > 1) && !(final_req & ABD_REQ_MASK))
+ error_msg_and_help("ABI modes cannot be automatically "
+ "detected for multiple "
+ "architectures");
+ /* set-abi and set-arch have to take the same number of args */
+ if ((final_req & AD_REQ_SET_ARCH) && (final_req & ABD_REQ_SET_ABI) &&
+ (mult_arch != mult_abi))
+ error_msg_and_help("each architecture needs respective "
+ "ABI mode, and vice versa");
+ /* --nargs cannot be used alone */
+ if ((final_req & SD_REQ_NARGS) &&
+ !(final_req & SD_REQ_MASK & ~SD_REQ_NARGS))
+ error_msg_and_help("first set main output syscall "
+ "characteristics");
+ /* raw should not be single */
+ if (final_req == SERV_REQ_RAW)
+ error_msg_and_help("raw data implies existing data");
+ return final_req;
+}
+
+static char *
+seek_sc_arg(char **input_args[])
+{
+ int i;
+
+ for (i = SD_REQ_GET_SNAME_BIT; i < SYSCALL_REQ_BIT_LAST; i++)
+ if (input_args[i] != NULL)
+ return input_args[i][0];
+ return NULL;
+}
+
+int
+main(int argc, char *argv[])
+{
+ ARCH_LIST_DEFINE(arch_list);
+ SYSCALL_LIST_DEFINE(sc_list);
+ /* This array is purposed to store arguments for options in the
+ most convenient way */
+ char ***in_args = xcalloc(sizeof(*in_args), REQ_LAST_BIT);
+ unsigned reqs;
+
+ /* command_dispatcher turn */
+ reqs = command_dispatcher(argc, argv, in_args);
+ if (reqs == 0)
+ error_msg_and_help("must have OPTIONS");
+
+ /* arch_dispatcher turn */
+ arch_list = arch_dispatcher(reqs, in_args[AD_REQ_SET_ARCH_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* abi_dispatcher turn */
+ abi_dispatcher(arch_list, reqs, in_args[ABD_REQ_SET_ABI_BIT]);
+ if (es_error(al_err(arch_list)))
+ perror_msg_and_die("%s", es_get_serror(al_err(arch_list)));
+ /* syscall_dispatcher turn */
+ sc_list = syscall_dispatcher(arch_list, reqs, seek_sc_arg(in_args));
+ if (es_error(ss_err(sc_list)))
+ perror_msg_and_die("%s", es_get_serror(ss_err(sc_list)));
+ /* If we want to get info about only architectures thus we print out
+ architectures, otherwise system calls */
+ if (!(reqs & SD_REQ_MASK))
+ al_dump(arch_list, reqs & SERV_REQ_RAW);
+ else
+ ss_dump(sc_list, reqs & SERV_REQ_RAW);
+ return 0;
+}
diff --git a/tools/asinfo/dispatchers.c b/tools/asinfo/dispatchers.c
new file mode 100644
index 00000000..ec0f20f9
--- /dev/null
+++ b/tools/asinfo/dispatchers.c
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edg...@vi...>
+ * 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 "syscall_interface.h"
+#include "sysent.h"
+#include "xmalloc.h"
+
+struct arch_service *
+arch_dispatcher(unsigned request_type, char *arch[])
+{
+ struct utsname info_uname;
+ int i;
+ ARCH_LIST_DEFINE(arch_list) = al_create_filled();
+ ARCH_LIST_DEFINE(arch_final) = NULL;
+
+ /* If user don't type any option in ARCH_REQ group, it means
+ get current arch */
+ if ((request_type & AD_REQ_GET_ARCH) ||
+ (!(request_type & AD_REQ_MASK))) {
+ uname(&info_uname);
+ if (al_mark_matches(arch_list, info_uname.machine) == -1) {
+ es_set_error(al_err(arch_list), AD_UNSUP_ARCH);
+ es_set_option(al_err(arch_list), info_uname.machine,
+ NULL, NULL);
+ goto fail;
+ }
+ /* Cut off useless archs */
+ arch_final = al_join_print(arch_final, arch_list);
+ al_unmark_all(arch_final, AD_FLAG_P...
[truncated message content] |
|
From: Edgar K. <edg...@vi...> - 2017-12-10 13:54:00
|
As asinfo requires some strace source files to work, it is neccessary to group them into separate static library. * Makefile.am (strace_SOURCES): Delete basic_filters.c, error_prints.c, error_prints.h, filter.h, macros.h, number_set.c, number_set.h, string_to_uint.h, string_to_uint.c, sysent_shorthand_defs.h, sysent_shorthand_undefs, xmalloc.c and xmalloc.h. (libcommon_SOURCES): Add them. (strace_LDADD): Add libcommon.a. (noinst_LIBRARIES): Likewise. * .gitignore: Add libcommon.a. Signed-off-by: Edgar Kaziakhmedov <edg...@vi...> --- .gitignore | 1 + Makefile.am | 33 ++++++++++++++++++++------------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 94a0be39..30938836 100644 --- a/.gitignore +++ b/.gitignore @@ -29,6 +29,7 @@ /ioctlent[012].h /ioctls_all[012].h /ioctlsort[012] +/libcommon.a /libmpers-m32.a /libmpers-mx32.a /libstrace.a diff --git a/Makefile.am b/Makefile.am index c04125ec..e90c7809 100644 --- a/Makefile.am +++ b/Makefile.am @@ -83,12 +83,31 @@ libstrace_a_SOURCES = \ upoke.c \ # end of libstrace_a_SOURCES +strace_LDADD += libcommon.a +noinst_LIBRARIES += libcommon.a +libcommon_a_CPPFLAGS = $(strace_CPPFLAGS) +libcommon_a_CFLAGS = $(strace_CFLAGS) +libcommon_a_SOURCES = \ + basic_filters.c \ + error_prints.c \ + error_prints.h \ + filter.h \ + macros.h \ + number_set.c \ + number_set.h \ + string_to_uint.h \ + string_to_uint.c \ + sysent_shorthand_defs.h \ + sysent_shorthand_undefs.h \ + xmalloc.c \ + xmalloc.h \ + #end of libcommon_a_SOURCES + strace_SOURCES = \ access.c \ affinity.c \ aio.c \ alpha.c \ - basic_filters.c \ bind.c \ bjm.c \ block.c \ @@ -116,8 +135,6 @@ strace_SOURCES = \ dyxlat.c \ empty.h \ epoll.c \ - error_prints.c \ - error_prints.h \ evdev.c \ eventfd.c \ execve.c \ @@ -137,7 +154,6 @@ strace_SOURCES = \ file_handle.c \ file_ioctl.c \ filter_qualify.c \ - filter.h \ flock.c \ flock.h \ fs_x_ioctl.c \ @@ -176,7 +192,6 @@ strace_SOURCES = \ lookup_dcookie.c \ loop.c \ lseek.c \ - macros.h \ mem.c \ membarrier.c \ memfd_create.c \ @@ -210,8 +225,6 @@ strace_SOURCES = \ nsfs.h \ nsig.h \ numa.c \ - number_set.c \ - number_set.h \ oldstat.c \ open.c \ or1k_atomic.c \ @@ -291,15 +304,11 @@ strace_SOURCES = \ statx.c \ statx.h \ strace.c \ - string_to_uint.h \ - string_to_uint.c \ supported_personalities.h \ swapon.c \ syscall.c \ sysctl.c \ sysent.h \ - sysent_shorthand_defs.h \ - sysent_shorthand_undefs.h \ sysinfo.c \ syslog.c \ sysmips.c \ @@ -324,8 +333,6 @@ strace_SOURCES = \ xattr.c \ xlat.c \ xlat.h \ - xmalloc.c \ - xmalloc.h \ # end of strace_SOURCES if USE_LIBUNWIND -- 2.11.0 |