[PATCH] asinfo: Introduce static query tool asinfo

Edgar Kaziakhmedov edgar.kaziakhmedov at virtuozzo.com
Tue Jul 18 08:54:33 UTC 2017


From: Edgar Kaziakhmedov <edgar.kaziakhmedov at virtuzzo.com>

The first version of asinfo tool. The asinfo tool has the
following architecture:
architecture dispatcher->system call dispatcher->filter dispatcher

As for arch. dispatcher, the asinfo has get-arch, list-arch, set-arch
%name_of_arch options, arch_dispatcher is purposed to process them.
Now, to find out the main principle of working, let’s consider the next
one case:
$ asinfo list-syscall set-filter signal
Firstly, arch_dispatcher will return the current architecture, after
that syscall_dispatcher will provide the list of system calls
(struct sc_base_info) for this architecture, finally filter_dispatcher,
working with syscallent’s database, will drop all system calls, which
are not signal-related.
For now, tool is able to show syscall typing its sequence number.

* Makefile.am (SUBDIRS): Add tools directory.
* configure.ac (AC_CONFIG_FILES): Add Makefile's.
* tools/Makefile.am: New file.
* tools/asinfo/Makefile.am: New file.
* tools/asinfo/arch_list.h: New file.
* tools/asinfo/dispatchers.h: New file. Prototype syscall_dispatcher
and arch_dispatcher.
* tools/asinfo/dispatchers.c: New file. Implement arch_dispatcher.
Import syscallent.h files.
* tools/asinfo/arch_interface.h: New file. Prototype methods to simplify
work with the list of arch_descriptor. Introduce struct arch_descriptor.
* tools/asinfo/arch_interface.c: New file. Implement them.
* tools/asinfo/request_msgs.h: New file. Introduce main type of requests.
Introduce structures for syscall_dispatcher.
* tools/asinfo/asinfo.c: New file. Implement support of all arch options and
initial support of syscall options.
* tools/asinfo/asinfo.1: New file. Empty man.

Signed-off-by: Edgar Kaziakhmedov <edgar.kaziakhmedov at virtuozzo.com>
---
 Makefile.am                   |   2 +-
 configure.ac                  |   2 +
 tools/Makefile.am             |  28 ++++++
 tools/asinfo/Makefile.am      |  57 ++++++++++++
 tools/asinfo/arch_interface.c | 101 +++++++++++++++++++++
 tools/asinfo/arch_interface.h |  75 ++++++++++++++++
 tools/asinfo/arch_list.h      |   4 +
 tools/asinfo/asinfo.1         |   0
 tools/asinfo/asinfo.c         | 199 ++++++++++++++++++++++++++++++++++++++++++
 tools/asinfo/dispatchers.c    | 184 ++++++++++++++++++++++++++++++++++++++
 tools/asinfo/dispatchers.h    |  54 ++++++++++++
 tools/asinfo/request_msgs.h   |  80 +++++++++++++++++
 12 files changed, 785 insertions(+), 1 deletion(-)
 create mode 100644 tools/Makefile.am
 create mode 100644 tools/asinfo/Makefile.am
 create mode 100644 tools/asinfo/arch_interface.c
 create mode 100644 tools/asinfo/arch_interface.h
 create mode 100644 tools/asinfo/arch_list.h
 create mode 100644 tools/asinfo/asinfo.1
 create mode 100644 tools/asinfo/asinfo.c
 create mode 100644 tools/asinfo/dispatchers.c
 create mode 100644 tools/asinfo/dispatchers.h
 create mode 100644 tools/asinfo/request_msgs.h

diff --git a/Makefile.am b/Makefile.am
index f08a8831..4e8ac7ab 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -35,7 +35,7 @@ endif
 if HAVE_MX32_RUNTIME
 TESTS_MX32 = tests-mx32
 endif
-SUBDIRS = tests $(TESTS_M32) $(TESTS_MX32)
+SUBDIRS = tests $(TESTS_M32) $(TESTS_MX32) tools
 
 bin_PROGRAMS = strace
 man_MANS = strace.1
diff --git a/configure.ac b/configure.ac
index 2c84b9a7..5118cdc4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -835,6 +835,8 @@ AC_CONFIG_FILES([Makefile
 		 tests/Makefile
 		 tests-m32/Makefile
 		 tests-mx32/Makefile
+		 tools/Makefile
+		 tools/asinfo/Makefile
 		 strace.spec
 		 debian/changelog])
 AC_OUTPUT
diff --git a/tools/Makefile.am b/tools/Makefile.am
new file mode 100644
index 00000000..6044e9ae
--- /dev/null
+++ b/tools/Makefile.am
@@ -0,0 +1,28 @@
+# Automake input for strace tools.
+#
+# Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+SUBDIRS = asinfo
diff --git a/tools/asinfo/Makefile.am b/tools/asinfo/Makefile.am
new file mode 100644
index 00000000..e93ce181
--- /dev/null
+++ b/tools/asinfo/Makefile.am
@@ -0,0 +1,57 @@
+# Automake input for asinfo.
+#
+# Copyright (c) 2017 Edgar Kaziakhmedov <edos at linux.com>
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in the
+#    documentation and/or other materials provided with the distribution.
+# 3. The name of the author may not be used to endorse or promote products
+#    derived from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+bin_PROGRAMS = asinfo
+man_MANS = asinfo.1
+
+OS = linux
+
+AUTOMAKE_OPTIONS = subdir-objects
+
+AM_CFLAGS = $(WARN_CFLAGS)
+AM_CPPFLAGS = -I$(builddir) \
+	      -I$(top_builddir)/$(OS) \
+	      -I$(top_srcdir)/$(OS) \
+	      -I$(top_builddir) \
+	      -I$(top_srcdir)
+asinfo_CPPFLAGS = $(AM_CPPFLAGS)
+asinfo_CFLAGS = $(AM_CFLAGS)
+
+asinfo_SOURCES = 		\
+	arch_interface.c	\
+	arch_interface.h	\
+	arch_list.h		\
+	asinfo.c		\
+	dispatchers.c		\
+	dispatchers.h		\
+	../../error_prints.c	\
+	../../error_prints.h	\
+	../../macros.h		\
+	requests_msgs.h		\
+	../../xmalloc.c		\
+	../../xmalloc.h		\
+	#end of asinfo_SOURCES
diff --git a/tools/asinfo/arch_interface.c b/tools/asinfo/arch_interface.c
new file mode 100644
index 00000000..3c11beae
--- /dev/null
+++ b/tools/asinfo/arch_interface.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "arch_interface.h"
+#include "xmalloc.h"
+
+struct arch_service *arch_list_create(unsigned size)
+{
+	struct arch_service *as = (struct arch_service *) \
+				  xcalloc(sizeof(*as), 1);
+	if (size) {
+		as->arch_list = (struct arch_descriptor **) \
+				xcalloc(sizeof(*(as->arch_list)), size);
+	}
+	as->capacity = size;
+	as->next_free = 0;
+	return as;
+}
+
+int arch_list_push(struct arch_service *m, struct arch_descriptor *element)
+{
+	if (m->next_free >= m->capacity) {
+		return -1;
+	}
+	m->arch_list[m->next_free] = element;
+	(m->next_free)++;
+	return 0;
+}
+
+struct arch_descriptor *arch_list_get(struct arch_service *m, unsigned index)
+{
+	if (index >= m->next_free) {
+		return NULL;
+	}
+	return m->arch_list[index];
+}
+
+unsigned arch_list_size(struct arch_service *m)
+{
+	return m->next_free;
+}
+
+void arch_list_free(struct arch_service *m)
+{
+	free(m->arch_list);
+	free(m);
+}
+
+const char* arch_list_name(struct arch_service *m, unsigned index)
+{
+	return m->arch_list[index]->arch_name;
+}
+
+int arch_list_snum(struct arch_service *m, unsigned index)
+{
+	return m->arch_list[index]->max_scn;
+}
+
+void arch_list_print(struct arch_service *m, const char *delim)
+{
+	unsigned i = 0;
+	unsigned max_len = 0;
+	for (i = 0; i < arch_list_size(m); i++) {
+		unsigned temp = strlen(m->arch_list[i]->arch_name);
+		if (temp > max_len) {
+			max_len = temp;
+		}
+	}
+	for (i = 0; i < arch_list_size(m); i++) {
+		printf("[%u] %*s %s %d\n", i + 1, max_len, arch_list_name(m, i),
+					   delim, arch_list_snum(m, i));
+	}
+}
diff --git a/tools/asinfo/arch_interface.h b/tools/asinfo/arch_interface.h
new file mode 100644
index 00000000..5e9a8256
--- /dev/null
+++ b/tools/asinfo/arch_interface.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef ASINFO_ARCH_INTERFACE
+#define ASINFO_ARCH_INTERFACE
+
+#include "sysent.h"
+
+enum arch_types {
+	AARCH64,
+	ARM,
+	x86_64,
+	x32
+};
+
+struct arch_descriptor {
+	enum arch_types arch_num;
+	const char *arch_name;
+	int max_scn;
+	struct_sysent *list_of_syscall;
+};
+
+/* To provide push-back interface with arch_list */
+struct arch_service {
+	struct arch_descriptor **arch_list;
+	unsigned capacity;
+	unsigned next_free;
+};
+
+#define ARCH_LIST_DEFINE(name) \
+	struct arch_service *(name)
+
+/* Push-back interface is purposed to simplify interaction with
+   array of struct arch_descriptor's pointers */
+
+struct arch_service *arch_list_create(unsigned size);
+
+int arch_list_push(struct arch_service *m, struct arch_descriptor *element);
+
+struct arch_descriptor *arch_list_get(struct arch_service *m, unsigned index);
+
+unsigned arch_list_size(struct arch_service *m);
+
+void arch_list_free(struct arch_service *m);
+
+const char* arch_list_name(struct arch_service *m, unsigned index);
+
+int arch_list_snum(struct arch_service *m, unsigned index);
+
+void arch_list_print(struct arch_service *m, const char *delim);
+
+#endif /* !ASINFO_ARCH_INTERFACE */
diff --git a/tools/asinfo/arch_list.h b/tools/asinfo/arch_list.h
new file mode 100644
index 00000000..4a7accf7
--- /dev/null
+++ b/tools/asinfo/arch_list.h
@@ -0,0 +1,4 @@
+[0] = { AARCH64,	"aarch64",	ARRAY_SIZE(aarch64_sysent0),	aarch64_sysent0		},
+[1] = { ARM,		"arm",		ARRAY_SIZE(arm_sysent0),	arm_sysent0		},
+[2] = { x86_64,		"x86_64",	ARRAY_SIZE(x86_64_sysent0),	x86_64_sysent0		},
+[3] = { x32,		"x32",		ARRAY_SIZE(x32_sysent0),	x32_sysent0		},
diff --git a/tools/asinfo/asinfo.1 b/tools/asinfo/asinfo.1
new file mode 100644
index 00000000..e69de29b
diff --git a/tools/asinfo/asinfo.c b/tools/asinfo/asinfo.c
new file mode 100644
index 00000000..66a91748
--- /dev/null
+++ b/tools/asinfo/asinfo.c
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdarg.h>
+#include <stdbool.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "arch_interface.h"
+#include "dispatchers.h"
+#include "error_prints.h"
+#include "macros.h"
+#include "request_msgs.h"
+#include "xmalloc.h"
+
+#ifndef HAVE_PROGRAM_INVOCATION_NAME
+char *program_invocation_name;
+#endif
+static const char *def_delim = ":";
+
+void ATTRIBUTE_NOINLINE
+die(void)
+{
+	exit(1);
+}
+
+/* To calculate sequence number of set bit */
+static inline unsigned
+fsbit_num(unsigned flag)
+{
+	unsigned i = 0;
+	while ((flag >>= 1) != 0) i++;
+	return i;
+}
+
+static unsigned
+option_to_request(char *option)
+{
+	const struct opt_to_req requests[] = {
+	[ 0] = { AD_REQ_SET_ARCH,	"set-arch"		},
+	[ 1] = { AD_REQ_GET_ARCH,	"get-arch"		},
+	[ 2] = { AD_REQ_LIST_ARCH,	"list-arch"		},
+	[ 3] = { SD_REQ_GET_NAME,	"get-name"		},
+	//[ 4] = { SD_REQ_GET_NUMBER,	"get-num"		},
+	//[ 5] = { SD_REQ_GET_NARGS,	"get-nargs"		},
+	//[ 6] = { SD_REQ_GET_PROTO,	"get-proto"		},
+	//[ 7] = { SD_REQ_GET_KERNEL,	"get-kernel"		},
+	//[ 8] = { SD_REQ_GET_LIST,	"list-syscall"		},
+	//[ 9] = { FD_SET_BASE_FILTER,	"set-filter"		},
+	//[10] = { FD_SET_ADV_FILTER,	"set-adv-filter"	}
+	};
+	unsigned i;
+
+	for (i = 0; i < ARRAY_SIZE(requests); i++) {
+		if (strcasecmp(option, requests[i].option) == 0)
+			return requests[i].req_t;
+	}
+	return 0;
+}
+
+static unsigned ATTRIBUTE_NOINLINE
+form_req(int argc, char *argv[], char *args[])
+{
+	if (!program_invocation_name || !*program_invocation_name) {
+		static char name[] = "strace";
+		program_invocation_name =
+			(argv[0] && *argv[0]) ? argv[0] : name;
+	}
+
+	int i;
+	unsigned ret_val = 0;
+	unsigned temp_ret = 0;
+	unsigned bit_pos = 0;
+
+	for (i = 1; i < argc; i++) {
+		if ((temp_ret = option_to_request(argv[i])) != 0) {
+			if ((ret_val & temp_ret) ||
+			    (!(temp_ret & (SD_REQ_GET_LIST +
+					   AD_REQ_LIST_ARCH +
+					   AD_REQ_GET_ARCH)) &&
+			    (i + 1 >= argc))) {
+				error_msg_and_help("option '%s' requires "
+						   "argument", argv[i]);
+			}
+			ret_val |= temp_ret;
+			bit_pos = fsbit_num(temp_ret);
+			if (!(temp_ret & (SD_REQ_GET_LIST + AD_REQ_LIST_ARCH +
+					  AD_REQ_GET_ARCH))) {
+				args[bit_pos] = argv[i + 1];
+				i += 1;
+			}
+		} else {
+			error_msg_and_help("unrecognized option '%s'", argv[i]);
+		}
+	}
+	return ret_val;
+}
+
+static int
+check_req(unsigned *request, char *args[])
+{
+	int a_flag = *request & (AD_REQ_MASK ^ AD_REQ_SET_ARCH);
+	int s_flag = *request & SD_REQ_MASK;
+	int dump = 1;
+	/* Check arch flags */
+	if (!(*request & AD_REQ_MASK)) {
+		*request |= AD_REQ_GET_ARCH;
+		dump = 0;
+	}
+	if (*request & AD_REQ_SET_ARCH) {
+		dump = 0;
+	}
+	/* Check for ambiguity */
+	if (!((*request & AD_REQ_MASK) == AD_REQ_SET_ARCH ||
+	      (*request & AD_REQ_MASK) == AD_REQ_GET_ARCH ||
+	      (*request & AD_REQ_MASK) == AD_REQ_LIST_ARCH)) {
+		return -1;
+	}
+	if (a_flag != 0 && s_flag != 0) {
+		return -1;
+	}
+	/* Check syscall flags, ambiguity */
+	if (!(*request & SD_REQ_MASK)) {
+		*request |= SD_REQ_GET_LIST;
+	}
+	if (!((*request & SD_REQ_MASK) == SD_REQ_GET_NAME ||
+	      (*request & SD_REQ_MASK) == SD_REQ_GET_NUMBER ||
+	      (*request & SD_REQ_MASK) == SD_REQ_GET_LIST)) {
+		return -1;
+	}
+	return dump;
+}
+
+int
+main(int argc, char *argv[])
+{
+	char **input_args = (char**)xcalloc(sizeof(char*),
+			    sizeof(unsigned) * CHAR_BIT);
+	unsigned requests;
+	int dump;
+
+	if ((requests = form_req(argc, argv, input_args)) == 0)
+		error_msg_and_help("must have OPTIONS");
+	if ((dump = check_req(&requests, input_args)) == -1)
+		error_msg_and_help("ambiguous options");
+
+	/* arch_dispatcher work */
+	ARCH_LIST_DEFINE(arch_list);
+	arch_list = arch_dispatcher(requests,
+				    input_args[fsbit_num(AD_REQ_SET_ARCH)]);
+	if (dump) {
+		arch_list_print(arch_list, def_delim);
+		goto done;
+	}
+	if (arch_list_size(arch_list) == 0) {
+		error_msg_and_help("unrecognized architecture '%s'",
+				   input_args[fsbit_num(AD_REQ_SET_ARCH)]);
+	}
+	/* syscall_dispatcher work */
+	SYSCALL_LIST_DEFINE(syscall_list);
+	syscall_list = syscall_dispatcher(arch_list, requests,
+			   input_args[fsbit_num(requests & SD_REQ_MASK)]);
+	if (syscall_list[0].sys_name != NULL) {
+		printf("%s\n", syscall_list[0].sys_name);
+	} else {
+		error_msg_and_help("unrecognized syscall number '%s'",
+				input_args[fsbit_num(requests & SD_REQ_MASK)]);
+	}
+done:
+	arch_list_free(arch_list);
+	free(input_args);
+	return 0;
+}
diff --git a/tools/asinfo/dispatchers.c b/tools/asinfo/dispatchers.c
new file mode 100644
index 00000000..95ca4923
--- /dev/null
+++ b/tools/asinfo/dispatchers.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/utsname.h>
+
+#include "arch_interface.h"
+#include "dispatchers.h"
+#include "macros.h"
+#include "request_msgs.h"
+#include "sysent.h"
+#include "xmalloc.h"
+
+/* Define these shorthand notations to simplify the syscallent files. */
+/* These flags could be useful to print group of syscalls */
+#define TD TRACE_DESC
+#define TF TRACE_FILE
+#define TI TRACE_IPC
+#define TN TRACE_NETWORK
+#define TP TRACE_PROCESS
+#define TS TRACE_SIGNAL
+#define TM TRACE_MEMORY
+#define TST TRACE_STAT
+#define TLST TRACE_LSTAT
+#define TFST TRACE_FSTAT
+#define TSTA TRACE_STAT_LIKE
+#define TSF TRACE_STATFS
+#define TFSF TRACE_FSTATFS
+#define TSFA TRACE_STATFS_LIKE
+#define NF SYSCALL_NEVER_FAILS
+#define MA MAX_ARGS
+#define SI STACKTRACE_INVALIDATE_CACHE
+#define SE STACKTRACE_CAPTURE_ON_ENTER
+#define CST COMPAT_SYSCALL_TYPES
+
+/*
+ * For the current functionality there is no need
+ * to use sen and (*sys_func)() fields in sysent struct
+ */
+#define SEN(syscall_name) 0, NULL
+
+struct_sysent aarch64_sysent0[] = {
+#include "aarch64/syscallent.h"
+};
+
+struct_sysent arm_sysent0[] = {
+#include "arm/syscallent.h"
+};
+
+struct_sysent x32_sysent0[] = {
+#include "x32/syscallent.h"
+};
+
+struct_sysent x86_64_sysent0[] = {
+#include "x86_64/syscallent.h"
+};
+
+#undef SEN
+#undef TD
+#undef TF
+#undef TI
+#undef TN
+#undef TP
+#undef TS
+#undef TM
+#undef TST
+#undef TLST
+#undef TFST
+#undef TSTA
+#undef TSF
+#undef TFSF
+#undef TSFA
+#undef NF
+#undef MA
+#undef SI
+#undef SE
+#undef CST
+
+struct arch_descriptor architectures[] = {
+#include "arch_list.h"
+};
+
+struct sc_base_info *
+syscall_dispatcher(struct arch_service *arch, int request_type,
+		   const char *data)
+{
+	SYSCALL_LIST_DEFINE(syscall_list);
+
+	if (request_type & SD_REQ_GET_NAME) {
+		long int nsys;
+		char *endptr;
+		nsys = strtol(data, &endptr, 10);
+		if (*endptr != '\0' || nsys < 0 ||
+		    nsys >= arch->arch_list[0]->max_scn) {
+			goto fail;
+		}
+		SYSCALL_LIST_ALLOC(syscall_list, 1);
+		syscall_list[0].sys_name =
+			arch->arch_list[0]->list_of_syscall[nsys].sys_name;
+		goto done;
+	}
+
+fail:
+	SYSCALL_LIST_ALLOC(syscall_list, 0);
+done:
+	return syscall_list;
+}
+
+struct arch_service *
+arch_dispatcher(unsigned request_type, const char* arch)
+{
+	struct utsname info_uname;
+	const char *loc_arch;
+	unsigned i;
+	ARCH_LIST_DEFINE(arch_list);
+	if ((!arch) && (request_type & AD_REQ_SET_ARCH)) {
+		goto fail;
+	}
+
+	if (request_type & AD_REQ_GET_ARCH) {
+		uname(&info_uname);
+		for (i = 0; i < ARRAY_SIZE(architectures); i++) {
+			loc_arch = architectures[i].arch_name;
+			if (strcasestr(info_uname.machine, loc_arch) != NULL) {
+				arch_list = arch_list_create(1);
+				arch_list_push(arch_list, &(architectures[i]));
+				goto done;
+			}
+		}
+	}
+
+	if (request_type & AD_REQ_SET_ARCH) {
+		for (i = 0; i < ARRAY_SIZE(architectures); i++) {
+			loc_arch = architectures[i].arch_name;
+			if (strcasestr(arch, loc_arch) != NULL) {
+				arch_list = arch_list_create(1);
+				arch_list_push(arch_list, &(architectures[i]));
+				goto done;
+			}
+		}
+	}
+
+	if (request_type & AD_REQ_LIST_ARCH) {
+		arch_list = arch_list_create(ARRAY_SIZE(architectures));
+		for (i = 0; i < ARRAY_SIZE(architectures); i++) {
+			arch_list_push(arch_list, &(architectures[i]));
+		}
+		goto done;
+	}
+
+fail:
+	arch_list = arch_list_create(0);
+done:
+	return arch_list;
+}
diff --git a/tools/asinfo/dispatchers.h b/tools/asinfo/dispatchers.h
new file mode 100644
index 00000000..a60f1595
--- /dev/null
+++ b/tools/asinfo/dispatchers.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRACE_ASINFO_COM_SCALLENT
+#define STRACE_ASINFO_COM_SCALLENT
+
+#include "arch_interface.h"
+#include "request_msgs.h"
+#include "sysent.h"
+
+#define SYSCALL_LIST_DEFINE(name) \
+	struct sc_base_info *(name)
+
+#define SYSCALL_LIST_ALLOC(name, size) \
+	(name) = (struct sc_base_info*) xcalloc(sizeof(*(name)), (size + 1))
+
+/* The main interaction with low-level structures, such as for now,
+ * struct_sysent, is happening here, the remaining processing should
+ * be done on the other levels.
+ */
+struct sc_base_info *syscall_dispatcher(struct arch_service *arch,
+					int request_type,
+					const char *arg);
+
+/* The function is purposed to interact with uname syscall
+ */
+struct arch_service *arch_dispatcher(unsigned request_type,
+				     const char* arch);
+
+#endif /* !STRACE_ASINFO_COM_SCALLENT */
diff --git a/tools/asinfo/request_msgs.h b/tools/asinfo/request_msgs.h
new file mode 100644
index 00000000..575e2735
--- /dev/null
+++ b/tools/asinfo/request_msgs.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2017 Edgar A. Kaziakhmedov <edos at linux.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef STRACE_ASINFO_REQ_MSGS
+#define STRACE_ASINFO_REQ_MSGS
+
+/* Request types for syscall_dispatcher,
+ * arch_dispatcher, and filter_dispatcher,
+ * which, in turn, could be combined
+ */
+enum request_types {
+	SD_REQ_GET_NAME		= 0x1<<0,
+	SD_REQ_GET_NUMBER	= 0x1<<1,
+	SD_REQ_GET_NARGS	= 0x1<<2,
+	SD_REQ_GET_PROTO	= 0x1<<3,
+	SD_REQ_GET_KERNEL	= 0x1<<4,
+	SD_REQ_GET_LIST		= 0x1<<5,
+	/* Reserved */
+	AD_REQ_SET_ARCH		= 0x1<<16,
+	AD_REQ_GET_ARCH		= 0x1<<17,
+	AD_REQ_LIST_ARCH	= 0x1<<18,
+	/* Reserved */
+	FD_SET_BASE_FILTER	= 0x1<<24,
+	FD_SET_ADV_FILTER	= 0x1<<25
+};
+
+#define SD_REQ_MASK (0x0000FFFFU)
+#define AD_REQ_MASK (0x00FF0000U)
+#define FD_REQ_MASK (0xFF000000U)
+
+/* To convert options to req_types */
+struct opt_to_req {
+	enum request_types req_t;
+	const char *option;
+};
+
+/* SD_REQ_GET_NAME, SD_REQ_GET_NUMBER */
+struct sc_base_info {
+	int sys_number;
+	const char *sys_name;
+	int sys_flags;
+};
+
+/* SD_REQ_GET_NARGS */
+struct sc_nargs {
+	struct sc_base_info sys_bi;
+	int nargs;
+};
+
+/* FD_SET_BASE_FILTER */
+struct sc_filter {
+	struct sc_base_info sys_bi;
+	int filter_options;
+};
+
+#endif /* !STRACE_ASINFO_REQ_MSGS */
-- 
2.11.0





More information about the Strace-devel mailing list