summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-12-05 00:03:04 +0100
committerMattias Andrée <maandree@kth.se>2023-12-05 00:03:04 +0100
commit58dd684c4e86944301959a140dbed9746df35779 (patch)
treea2702ea4f66b2a58711ee22eb7449c74b1ecf0d1
parentFirst commit (diff)
downloadlibsyscalls-58dd684c4e86944301959a140dbed9746df35779.tar.gz
libsyscalls-58dd684c4e86944301959a140dbed9746df35779.tar.bz2
libsyscalls-58dd684c4e86944301959a140dbed9746df35779.tar.xz
Second commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--.gitignore1
-rw-r--r--Makefile38
-rw-r--r--TODO2
-rw-r--r--config-figure-this-out-for-me.mk2
-rw-r--r--config.mk2
-rwxr-xr-xdevtools/create-linux-syscall1
-rwxr-xr-xdevtools/find-type-definition1
-rw-r--r--libsyscalls.h83
-rw-r--r--libsyscalls/internal-begin.h8
-rw-r--r--libsyscalls_get_datatype_description.c2
-rw-r--r--libsyscalls_get_syscall_display_info.c2
-rw-r--r--linux/download.mk2
-rw-r--r--linux/errors.mk2
-rw-r--r--linux/linux-support.mk4
-rw-r--r--linux/signals.mk2
-rw-r--r--linux/symbols.c14
-rw-r--r--linux/symbols.mk2
-rw-r--r--linux/syscall-table.mk2
-rw-r--r--linux/syscalls.h2
-rw-r--r--linux/syscalls.mk186
-rw-r--r--linux/types.mk2
-rw-r--r--mk/generate.mk1
-rwxr-xr-xtest588
-rw-r--r--testcases/errors-LINUX-AMD64150
-rw-r--r--testcases/errors-LINUX-PARISC_32152
l---------testcases/errors-LINUX-PARISC_641
-rw-r--r--testcases/signals-LINUX-AMD6464
-rw-r--r--testutil/get-datatype-description.c52
-rw-r--r--testutil/get-error.c27
-rw-r--r--testutil/get-section-fraction.c24
-rw-r--r--testutil/get-signals.c43
-rw-r--r--testutil/get-syscall-errors.c43
-rw-r--r--testutil/get-syscall-range.c41
-rw-r--r--testutil/is-datatype-struct.c29
-rw-r--r--testutil/is-section-half.c14
-rw-r--r--testutil/is-section-quarter.c14
-rw-r--r--testutil/list-errors.c21
-rw-r--r--testutil/perror-all.c23
-rw-r--r--testutil/perror-bad.c23
-rw-r--r--testutil/strerror-all.c25
-rw-r--r--testutil/strerror-bad.c25
-rwxr-xr-xutil/getdefs1
-rwxr-xr-xutil/getenum1
-rwxr-xr-xutil/make-enum1
-rwxr-xr-xutil/make-mask1
-rwxr-xr-xutil/make-multiextractor1
-rwxr-xr-xutil/make-sym-extractor1
-rwxr-xr-xutil/what-architecture-am-i-using1
48 files changed, 1593 insertions, 134 deletions
diff --git a/.gitignore b/.gitignore
index df605d8..591f261 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,7 @@
*.gcno
*.gcda
*.tmp
+*.tu
/*-src/
/generated/
/libsyscalls/short-enums.h
diff --git a/Makefile b/Makefile
index 7b0ecb3..01e23e2 100644
--- a/Makefile
+++ b/Makefile
@@ -1,3 +1,4 @@
+# See LICENSE file for copyright and license details.
.POSIX:
# Choose either yes or no (determines whether system call,
@@ -50,6 +51,9 @@ include $(CONFIGFILE)
#extended for each support operating system with the operating system's name as appropriate for filenames
OPERATING_SYSTEMS =
+#extended with supported architectures for each operating system
+TEST_ENV =
+
#extended for each support operating system with the number of syscall parameters they use
NPARAMS =
@@ -81,9 +85,26 @@ SUBHDR =\
libsyscalls/internal-end.h\
libsyscalls/short-enums.h
+TESTUTILS =\
+ testutil/get-datatype-description.tu\
+ testutil/get-error.tu\
+ testutil/get-section-fraction.tu\
+ testutil/get-signals.tu\
+ testutil/get-syscall-errors.tu\
+ testutil/get-syscall-range.tu\
+ testutil/is-section-half.tu\
+ testutil/is-section-quarter.tu\
+ testutil/is-datatype-struct.tu\
+ testutil/list-errors.tu\
+ testutil/perror-all.tu\
+ testutil/perror-bad.tu\
+ testutil/strerror-all.tu\
+ testutil/strerror-bad.tu
+
+
.SUFFIXES:
-.SUFFIXES: .lo .o .c
+.SUFFIXES: .lo .o .c .tu
include linux/$(LINUX_SUPPORT).mk
@@ -93,11 +114,14 @@ include $(CONFIGFILE)
# Reloading the user's config as the makefiles for the OS
# may have made changes to what is supported
+TEST_ENV += SUPPORTED_OSES="$(OPERATING_SYSTEMS)"
+
LOBJ = $(OBJ:.o=.lo)
$(OBJ): $(HDR)
$(LOBJ): $(HDR)
+$(TESTUTILS): $(HDR) libsyscalls.a
.c.o:
$(CC) -c -o $@ $< $(CFLAGS) $(IMPORTANT_CFLAGS) $(CPPFLAGS) $(IMPORTANT_CPPFLAGS)
@@ -105,6 +129,9 @@ $(LOBJ): $(HDR)
.c.lo:
$(CC) -fPIC -c -o $@ $< $(CFLAGS) $(IMPORTANT_CFLAGS) $(CPPFLAGS) $(IMPORTANT_CPPFLAGS)
+.c.tu:
+ $(CC) -o $@ $< libsyscalls.a $(CFLAGS) $(CPPFLAGS)
+
libsyscalls.a: $(OBJ)
@rm -f -- $@
$(AR) rc $@ $(OBJ)
@@ -113,6 +140,11 @@ libsyscalls.a: $(OBJ)
libsyscalls.$(LIBEXT): $(LOBJ)
$(CC) $(LIBFLAGS) -o $@ $(LOBJ) $(LDFLAGS)
+
+check: $(TESTUTILS)
+ env CPP="$(CPP)" $(TEST_ENV) ./test
+
+
install: libsyscalls.a libsyscalls.$(LIBEXT)
mkdir -p -- "$(DESTDIR)$(PREFIX)/lib"
mkdir -p -- "$(DESTDIR)$(PREFIX)/include/libsyscalls"
@@ -143,7 +175,7 @@ buildclean: semiclean
semiclean:
-rm -f -- *.o *.lo *.su *.gch *.gcov *.gcno *.gcda .*.tmp
-rm -f -- */*.o */*.lo */*.su */*.gch */*.gcov */*.gcno */*.gcda
- -rm -f -- *.a *.so *.so.* *.dll *.dylib *.$(LIBEXT)
+ -rm -f -- *.a *.so *.so.* *.dll *.dylib *.$(LIBEXT) */*.tu
-rm -f -- libsyscalls/short-enums.h
-.PHONY: all download install uninstall clean semiclean
+.PHONY: all download check install uninstall clean semiclean
diff --git a/TODO b/TODO
index 38e1a93..1571c00 100644
--- a/TODO
+++ b/TODO
@@ -1,5 +1,3 @@
-Add extraction tool
-Add test generation and regression testing
Add support for describing structs and unions
Add calling convention
Add value decoding
diff --git a/config-figure-this-out-for-me.mk b/config-figure-this-out-for-me.mk
index 2d470f7..8da5ff9 100644
--- a/config-figure-this-out-for-me.mk
+++ b/config-figure-this-out-for-me.mk
@@ -1,3 +1,4 @@
+# See LICENSE file for copyright and license details.
BASECONFIG !=\
set -e; \
if test -n "$(BASECONFIG)"; then \
@@ -56,4 +57,3 @@ IMPORTANT_CFLAGS !=\
if ! printf '%s\n' $(CC) $(CFLAGS) $(IMPORTANT_CFLAGS) | grep '^-std=c..$$' > /dev/null; then \
sed -n 's/^.*\(-std=c..\).*$$/\1/p' < .config.mk.tmp | sed 1q; \
fi
-
diff --git a/config.mk b/config.mk
index 144b7ac..c4d7eb3 100644
--- a/config.mk
+++ b/config.mk
@@ -2,6 +2,8 @@ PREFIX = /usr
MANPREFIX = $(PREFIX)/share/man
CC = cc -std=c2x
+CPP = $(CC) -E -
+# $(CPP) is only used for the check rule
CC_DEF_EXTRACT =
# If set, it will be used with -E -dM (must have the same meaning
diff --git a/devtools/create-linux-syscall b/devtools/create-linux-syscall
index 0b8e800..2a51543 100755
--- a/devtools/create-linux-syscall
+++ b/devtools/create-linux-syscall
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
+# See LICENSE file for copyright and license details.
import sys
diff --git a/devtools/find-type-definition b/devtools/find-type-definition
index 26e19f2..9523e7c 100755
--- a/devtools/find-type-definition
+++ b/devtools/find-type-definition
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
type="$1"
shift 1
diff --git a/libsyscalls.h b/libsyscalls.h
index f63d023..4c904b7 100644
--- a/libsyscalls.h
+++ b/libsyscalls.h
@@ -12,10 +12,10 @@
*
* The numbers are stored in `libsyscalls_error`
*
- * @param X(NAME, STR) Macro that expands, will be given two arguments:
- * the enum value name of the error (identifier),
- * and the description of the error (string literal)
- * @param D Macro that expands between each expansion of X
+ * @param X:macro(NAME, STR) Macro that expands, will be given two arguments:
+ * the enum value name of the error (identifier),
+ * and the description of the error (string literal)
+ * @param D:code Macro that expands between each expansion of X
*
* The primary purpose of the existance of this macro
* is to ease implementation of the library; it will
@@ -281,7 +281,7 @@ enum libsyscalls_syscall_category {
/* IPC that can but does not have to be over a network,
* "bind" system calls can create inodes in the file system */
-enum libsyscalls_syscall_network_enabled_ipc_subcategory {
+enum libsyscalls_network_enabled_ipc_syscall_subcategory {
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_ACCEPT,
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_LISTEN,
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_BIND,
@@ -289,7 +289,7 @@ enum libsyscalls_syscall_network_enabled_ipc_subcategory {
LIBSYSCALLS_NETWORK_ENABLED_IPC_SUBCAT_STAT
};
-enum libsyscalls_syscall_ipc_subcategory {
+enum libsyscalls_ipc_syscall_subcategory {
LIBSYSCALLS_IPC_SUBCAT_ADVISORY_FILE_LOCK,
LIBSYSCALLS_IPC_SUBCAT_MANDATORY_FILE_LOCK,
LIBSYSCALLS_IPC_SUBCAT_FILE_LOCK, /* may or may not be advisory (e.g. flock(2) since Linux 5.5) */
@@ -302,7 +302,7 @@ enum libsyscalls_syscall_ipc_subcategory {
};
/* syscalls that can work on either paths or FDs ([1]) are located here */
-enum libsyscalls_syscall_filesystem_subcategory {
+enum libsyscalls_filesystem_syscall_subcategory {
LIBSYSCALLS_FILESYSTEM_SUBCAT_STAT,
LIBSYSCALLS_FILESYSTEM_SUBCAT_MODIFY,
LIBSYSCALLS_FILESYSTEM_SUBCAT_SYNC, /* [1] some of these only work on file descriptors or memory maps */
@@ -319,7 +319,7 @@ enum libsyscalls_syscall_filesystem_subcategory {
};
/* syscalls that work FDs but not paths are located here */
-enum libsyscalls_syscall_file_descriptors_subcategory {
+enum libsyscalls_file_syscall_descriptors_subcategory {
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_STAT,
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_MODIFY,
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_DUP_OR_CLOSE, /* includes partial close (shutdown) */
@@ -340,7 +340,7 @@ enum libsyscalls_syscall_file_descriptors_subcategory {
LIBSYSCALLS_FILE_DESCRIPTORS_SUBCAT_POLL /* can work as pause or relative sleep */
};
-enum libsyscalls_syscall_processes_subcategory {
+enum libsyscalls_processes_syscall_subcategory {
LIBSYSCALLS_PROCESSES_SUBCAT_EXIT,
LIBSYSCALLS_PROCESSES_SUBCAT_STAT_SELF,
LIBSYSCALLS_PROCESSES_SUBCAT_STAT_CHILD, /* may also stat self */
@@ -354,11 +354,11 @@ enum libsyscalls_syscall_processes_subcategory {
LIBSYSCALLS_PROCESSES_SUBCAT_SESSION /* vhangup, setsid, setpgid */
};
-enum libsyscalls_syscall_logging_subcategory {
+enum libsyscalls_logging_syscall_subcategory {
LIBSYSCALLS_LOGGING_SUBCAT_PROCESSES
};
-enum libsyscalls_syscall_time_subcategory {
+enum libsyscalls_time_syscall_subcategory {
LIBSYSCALLS_TIME_SUBCAT_GET_OR_SET,
LIBSYSCALLS_TIME_SUBCAT_GET,
LIBSYSCALLS_TIME_SUBCAT_SET,
@@ -377,13 +377,13 @@ enum libsyscalls_syscall_time_subcategory {
LIBSYSCALLS_TIME_SUBCAT_SLEEP
};
-enum libsyscalls_syscall_signals_subcategory {
+enum libsyscalls_signals_syscall_subcategory {
LIBSYSCALLS_SIGNALS_SUBCAT_PAUSE,
LIBSYSCALLS_SIGNALS_SUBCAT_KILL
};
/* These may work on memory mapped files */
-enum libsyscalls_syscall_memory_subcategory {
+enum libsyscalls_memory_syscall_subcategory {
LIBSYSCALLS_MEMORY_SUBCAT_ALLOCATE,
LIBSYSCALLS_MEMORY_SUBCAT_READ,
LIBSYSCALLS_MEMORY_SUBCAT_WRITE,
@@ -394,7 +394,7 @@ enum libsyscalls_syscall_memory_subcategory {
LIBSYSCALLS_MEMORY_SUBCAT_STAT /* stats memory allocated to the process, not system resources */
};
-enum libsyscalls_syscall_system_subcategory {
+enum libsyscalls_system_syscall_subcategory {
LIBSYSCALLS_SYSTEM_SUBCAT_SWAP,
LIBSYSCALLS_SYSTEM_SUBCAT_REBOOT,
LIBSYSCALLS_SYSTEM_SUBCAT_GET_NAME,
@@ -404,7 +404,7 @@ enum libsyscalls_syscall_system_subcategory {
LIBSYSCALLS_SYSTEM_SUBCAT_FUNDAMENTAL
};
-enum libsyscalls_syscall_scheduling_subcategory {
+enum libsyscalls_scheduling_syscall_subcategory {
LIBSYSCALLS_SCHEDULING_SUBCAT_YEILD,
LIBSYSCALLS_SCHEDULING_SUBCAT_SET,
LIBSYSCALLS_SCHEDULING_SUBCAT_GET,
@@ -412,17 +412,17 @@ enum libsyscalls_syscall_scheduling_subcategory {
};
union libsyscalls_syscall_subcategory {
- enum_libsyscalls_syscall_network_enabled_ipc_subcategory network_enabled_ipc;
- enum_libsyscalls_syscall_ipc_subcategory ipc;
- enum_libsyscalls_syscall_filesystem_subcategory filesystem;
- enum_libsyscalls_syscall_file_descriptors_subcategory file_descriptors;
- enum_libsyscalls_syscall_processes_subcategory processes;
- enum_libsyscalls_syscall_logging_subcategory logging;
- enum_libsyscalls_syscall_time_subcategory time;
- enum_libsyscalls_syscall_signals_subcategory signals;
- enum_libsyscalls_syscall_memory_subcategory memory;
- enum_libsyscalls_syscall_system_subcategory system;
- enum_libsyscalls_syscall_scheduling_subcategory scheduling;
+ enum_libsyscalls_network_enabled_ipc_syscall_subcategory network_enabled_ipc;
+ enum_libsyscalls_ipc_syscall_subcategory ipc;
+ enum_libsyscalls_filesystem_syscall_subcategory filesystem;
+ enum_libsyscalls_file_descriptors_syscall_subcategory file_descriptors;
+ enum_libsyscalls_processes_syscall_subcategory processes;
+ enum_libsyscalls_logging_syscall_subcategory logging;
+ enum_libsyscalls_time_syscall_subcategory time;
+ enum_libsyscalls_signals_syscall_subcategory signals;
+ enum_libsyscalls_memory_syscall_subcategory memory;
+ enum_libsyscalls_system_syscall_subcategory system;
+ enum_libsyscalls_scheduling_syscall_subcategory scheduling;
};
/**
@@ -1145,8 +1145,23 @@ struct libsyscalls_datatype_description {
* Data types for register-splits ARE NOT shifted,
* there is always a value in .byteorder that is 0,
* unless .byteorder[0] is ~0
+ *
+ * To avoid problems checking for ~0, use
+ * the LIBSYSCALLS_IS_BYTEORDER_END macro
*/
unsigned char byteorder[32];
+
+ /**
+ * Test whether a value in `struct libsyscalls_datatype_description.byteorder`
+ * marks the end of the byteorder's shift value (testing
+ * that the value is ~0). Using this macro helps avoiding
+ * bugs caused by integer type promotion.
+ *
+ * @param SHIFT The value to test `struct libsyscalls_datatype_description.byteorder`
+ * @return :int Whether the value is ~0
+ */
+#define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
+ (!~((SHIFT) | ~LIBSYSCALLS_FIELD_MASK_(1ULL, struct libsyscalls_datatype_description, byteorder[0])))
};
@@ -1185,6 +1200,10 @@ libsyscalls_perror(const char *, enum libsyscalls_error);
* the selected architecture (`arch`) on the
* selected operating system (`os`)
*
+ * This function always fails if the selected combination
+ * of operating system (`os`) and architecture (`arch`) is
+ * unsupported
+ *
* Beware that range is used system call numbers are [*min_out, *max_out]
* (not [*min_out, *max_out - 1]) but there may still be numbers within
* this range that does not correspond to a system call
@@ -1211,6 +1230,10 @@ libsyscalls_get_syscall_range(enum libsyscalls_os, enum libsyscalls_arch, long l
* LIBSYSCALLS_E_NOSUCHSYSCALL - `syscallnr` does not correspond to a known
* system call for the selected architecture (`arch`)
* on the selected operating system (`os`)
+ *
+ * This function always fails if the selected combination
+ * of operating system (`os`) and architecture (`arch`) is
+ * unsupported
*/
LIBSYSCALLS_GCC_ATTRIBUTES_(__warn_unused_result__)
enum libsyscalls_error
@@ -1237,6 +1260,10 @@ libsyscalls_get_syscall(enum libsyscalls_os, enum libsyscalls_arch, long long in
* the selected architecture (`arch`) on the
* selected operating system (`os`)
* LIBSYSCALLS_E_NOERRORS - The operating system does not use named error numbers
+ *
+ * This function will always fail if the operating system (`os`)
+ * is not supported, however it may be successful even if the
+ * architecture (`arch`) not supported
*/
enum libsyscalls_error
libsyscalls_get_syscall_errors(enum libsyscalls_os, enum libsyscalls_arch, const struct libsyscalls_named_number **, size_t *);
@@ -1262,6 +1289,10 @@ libsyscalls_get_syscall_errors(enum libsyscalls_os, enum libsyscalls_arch, const
* the selected architecture (`arch`) on the
* selected operating system (`os`)
* LIBSYSCALLS_E_NOSIGNALS - The operating system does not use named signal numbers
+ *
+ * This function will always fail if the operating system (`os`)
+ * is not supported, however it may be successful even if the
+ * architecture (`arch`) not supported
*/
enum libsyscalls_error
libsyscalls_get_signals(enum libsyscalls_os, enum libsyscalls_arch, const struct libsyscalls_named_number **, size_t *);
diff --git a/libsyscalls/internal-begin.h b/libsyscalls/internal-begin.h
index 9741632..5c42b7e 100644
--- a/libsyscalls/internal-begin.h
+++ b/libsyscalls/internal-begin.h
@@ -74,3 +74,11 @@ typedef struct libsyscalls_symbol_printer_data LIBSYSCALLS_SYMBOL_PRINTER_DATA;
LIBSYSCALLS_LIST_FIXED_ARRAYS(LIBSYSCALLS_DATATYPE_X_, SUFFIX, LIBSYSCALLS_COMMA_,\
= LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS\
| LIBSYSCALLS_TYPEBITS##SUFFIX)
+
+#define LIBSYSCALLS_BITSIZEOF_(T) (sizeof(T) / sizeof(char) * CHAR_BIT)
+
+#define LIBSYSCALLS_FIELD_BITSIZEOF_(S, F) LIBSYSCALLS_BITSIZEOF_(((S *)0)->F)
+
+#define LIBSYSCALLS_MASK_(ONE, BITS) (((ONE) << ((BITS) - (ONE))) | (((ONE) << (BITS)) - (ONE)))
+
+#define LIBSYSCALLS_FIELD_MASK_(ONE, S, F) LIBSYSCALLS_MASK_(ONE, LIBSYSCALLS_FIELD_BITSIZEOF_(S, F))
diff --git a/libsyscalls_get_datatype_description.c b/libsyscalls_get_datatype_description.c
index 1a4cb59..d790531 100644
--- a/libsyscalls_get_datatype_description.c
+++ b/libsyscalls_get_datatype_description.c
@@ -390,7 +390,7 @@ not_os_dependent:
unsigned char bytebits;
for (i = 0; larger_type.byteorder[i]; i++)
- if (!~larger_type.byteorder[i])
+ if (LIBSYSCALLS_IS_BYTEORDER_END(larger_type.byteorder[i]))
abort();
bytebits = larger_type.byteorder[i];
bytemask = (1ULL << bytebits) - 1ULL;
diff --git a/libsyscalls_get_syscall_display_info.c b/libsyscalls_get_syscall_display_info.c
index 5b39284..4d59f5c 100644
--- a/libsyscalls_get_syscall_display_info.c
+++ b/libsyscalls_get_syscall_display_info.c
@@ -48,7 +48,7 @@ extract_signal(enum libsyscalls_os os, enum libsyscalls_arch arch,
if (libsyscalls_get_signals(os, arch, &signals, &nsignals))
return NULL;
- found = bsearch(&key, signals, nsignals, sizeof(key),
+ found = bsearch(&key, signals, nsignals, sizeof(key), /* TODO interpolation search may be better */
is_signed ? &signed_named_number_cmp : &unsigned_named_number_cmp);
if (!found)
return NULL;
diff --git a/linux/download.mk b/linux/download.mk
index 31da0b1..5555074 100644
--- a/linux/download.mk
+++ b/linux/download.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
LINUX_MIRROR = https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/snapshot
LINUX_TAREXT = tar.gz
LINUX_TARBALL = $(LINUX_MIRROR)/linux-$(LINUX_VERSION).$(LINUX_TAREXT)
diff --git a/linux/errors.mk b/linux/errors.mk
index b6b7197..f69bf73 100644
--- a/linux/errors.mk
+++ b/linux/errors.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
libsyscalls_get_syscall_errors.o: generated/linux-errors.h linux/errors.c
libsyscalls_get_syscall_errors.lo: generated/linux-errors.h linux/errors.c
diff --git a/linux/linux-support.mk b/linux/linux-support.mk
index 5efeafe..d596922 100644
--- a/linux/linux-support.mk
+++ b/linux/linux-support.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
LINUX_VERSION = 6.6
# Changing this number can potentially break the build,
# silently or violently, so make sure everything still
@@ -35,6 +37,8 @@ NPARAMS += 8
SUPPORTED_LINUX_ARCHES != printf '%s\n' $(SUPPORTED_LINUX_ARCHES) $(SUPPORTED_ARCHES) | sort | uniq -d
+TEST_ENV += SUPPORTED_LINUX_ARCHES="$(SUPPORTED_LINUX_ARCHES)"
+
include linux/download.mk
include linux/errors.mk
diff --git a/linux/signals.mk b/linux/signals.mk
index f7a8a45..8fb9f07 100644
--- a/linux/signals.mk
+++ b/linux/signals.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
libsyscalls_get_signals.o: generated/linux-signals.h linux/signals.c
libsyscalls_get_signals.lo: generated/linux-signals.h linux/signals.c
diff --git a/linux/symbols.c b/linux/symbols.c
index d91880f..cbc61f5 100644
--- a/linux/symbols.c
+++ b/linux/symbols.c
@@ -47,13 +47,13 @@ extract_linux_symbol_mode(struct libsyscalls_symbol_printer_data *data, unsigned
if (value & 07) goto digits1;
if (0) {
digits4:
- data->buf[i++] = '0' | (value & 07000);
+ data->buf[i++] = '0' | ((value / 01000) & 7);
digits3:
- data->buf[i++] = '0' | (value & 0700);
+ data->buf[i++] = '0' | ((value / 0100) & 7);
digits2:
- data->buf[i++] = '0' | (value & 070);
+ data->buf[i++] = '0' | ((value / 010) & 7);
digits1:
- data->buf[i++] = '0' | (value & 07);
+ data->buf[i++] = '0' | ((value / 01) & 7);
}
data->buf[i++] = ' ';
data->buf[i++] = '(';
@@ -95,11 +95,11 @@ extract_linux_symbol_umask(struct libsyscalls_symbol_printer_data *data, unsigne
if (value & 07) goto digits1;
if (0) {
digits3:
- data->buf[i++] = '0' | (value & 0700);
+ data->buf[i++] = '0' | ((value / 0700) & 7);
digits2:
- data->buf[i++] = '0' | (value & 070);
+ data->buf[i++] = '0' | ((value / 070) & 7);
digits1:
- data->buf[i++] = '0' | (value & 07);
+ data->buf[i++] = '0' | ((value / 07) & 7);
}
data->buf[i++] = ' ';
data->buf[i++] = '(';
diff --git a/linux/symbols.mk b/linux/symbols.mk
index f045222..97db4ab 100644
--- a/linux/symbols.mk
+++ b/linux/symbols.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
LINUX_SYMBOL_TABLES != sed -n 's/^.*LINUX_SYMBOL_PRINTER_\([A-Z0-9_]\+\)\b.*\$$\$$\$$.*\$$\$$\$$.*$$/\1/p' < linux/syscalls.h
LINUX_SYMBOL_TABLE_FILES != printf 'linux-src/symbols-$(LINUX_VERSION)/%s\n' $(LINUX_SYMBOL_TABLES)
diff --git a/linux/syscall-table.mk b/linux/syscall-table.mk
index 3f0d944..1b993e6 100644
--- a/linux/syscall-table.mk
+++ b/linux/syscall-table.mk
@@ -1,3 +1,5 @@
+# See LICENSE file for copyright and license details.
+
OBJ += linux/syscall-table.o
diff --git a/linux/syscalls.h b/linux/syscalls.h
index 94d714e..ed278cd 100644
--- a/linux/syscalls.h
+++ b/linux/syscalls.h
@@ -31,7 +31,7 @@ enum { /* LIBSYSCALLS_SYMBOL_PRINTER */
LINUX_SYMBOL_PRINTER_FACCESSAT, /* $$ SYMBOLS(ATFD, ACCESS_OK) $$ */
LINUX_SYMBOL_PRINTER_FANOTIFY_MARK, /* $$ SYMBOLS(FAN_MARK, FAN) $$ */
LINUX_SYMBOL_PRINTER_3STATX, /* $$ SYMBOLS(ATFD, AT_STATX, STATX) $$ */
-
+
LINUX_SYMBOL_PRINTER_ITIMER, /* enum $$$ getdefs ITIMER < include/uapi/linux/time.h $$$ */
LINUX_SYMBOL_PRINTER_SEEK, /* enum $$$ getdefs SEEK < include/uapi/linux/fs.h $$$ */
LINUX_SYMBOL_PRINTER_EPOLL_CTL, /* enum $$$ getdefs EPOLL_CTL < include/uapi/linux/eventpoll.h $$$ */
diff --git a/linux/syscalls.mk b/linux/syscalls.mk
index 7c13441..ddd1a63 100644
--- a/linux/syscalls.mk
+++ b/linux/syscalls.mk
@@ -1,13 +1,15 @@
+# See LICENSE file for copyright and license details.
+
LINUX_SYSCALL_DIR = linux-src/syscalls-$(LINUX_VERSION)
LINUX_SYSCALLS_ARCH_TBL_SPLIT_X64 != printf '$(LINUX_SYSCALL_DIR)/%s.tbl\n' amd64 x86
LINUX_SYSCALLS_ARCH_TBL_SPLIT_MIPS != printf '$(LINUX_SYSCALL_DIR)/%s.tbl\n' mips-n32 mips-o32 mips-n64
LINUX_SYSCALLS_ARCHES_SPLIT != grep '^LINUX_SYSCALLS_ARCH_TBL_SPLIT_' < linux/syscalls.mk | cut -d \% -f 2 | cut -d ' ' -f 2-
-LINUX_SYSCALLS_ARCHES_SIMPLE != (sed -n 's/^generated\/linux-syscalls-\([a-zA-Z0-9_-]\+\)\.h\s*:.*$$/\1/p' && \
+LINUX_SYSCALLS_ARCHES_SIMPLE != (sed -n 's/^generated\/linux-syscalls\/\([a-zA-Z0-9_-]\+\)\.h\s*:.*$$/\1/p' && \
printf '%s\n' $(LINUX_SYSCALLS_ARCHES_SPLIT)) < linux/syscalls.mk | sort | uniq -u
LINUX_SYSCALLS_ARCHES = $(LINUX_SYSCALLS_ARCHES_SIMPLE) $(LINUX_SYSCALLS_ARCHES_SPLIT)
-LINUX_SYSCALLS_ARCH_HDR != printf 'generated/linux-syscalls-%s.h\n' $(LINUX_SYSCALLS_ARCHES)
+LINUX_SYSCALLS_ARCH_HDR != printf 'generated/linux-syscalls/%s.h\n' $(LINUX_SYSCALLS_ARCHES)
LINUX_SYSCALLS_ARCH_TBL_SIMPLE != printf '$(LINUX_SYSCALL_DIR)/%s.tbl\n' $(LINUX_SYSCALLS_ARCHES_SIMPLE)
LINUX_SYSCALLS_ARCH_TBL_SPLIT != printf '$(LINUX_SYSCALL_DIR)/%s.tbl\n' $(LINUX_SYSCALLS_ARCHES_SPLIT)
LINUX_SYSCALLS_ARCH_TBL = $(LINUX_SYSCALLS_ARCH_TBL_SIMPLE) $(LINUX_SYSCALLS_ARCH_TBL_SPLIT)
@@ -18,41 +20,41 @@ LINUX_SYSCALLS_HDR =\
$(LINUX_SYSCALLS_ARCH_HDR)
-generated/linux-syscalls-alpha.h: $(LINUX_SYSCALL_DIR)/alpha.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/alpha.h: $(LINUX_SYSCALL_DIR)/alpha.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_ALPHA(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
320 idle sys_idle \
- | cat -- $(LINUX_SYSCALL_DIR)/alpha.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/alpha.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/alpha.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
$(LINUX_SYSCALL_DIR)/amd64.tbl.fixed: $(LINUX_SYSCALL_DIR)/amd64.tbl linux/syscalls.mk
- cat -- $(LINUX_SYSCALL_DIR)/amd64.tbl \
+ cat -- $(@:.fixed=) \
| sed 's/\s\+\(getpmsg\|putpmsg\|afs_syscall\|tuxcall\|security\|vserver\)\s*$$/& sys_ni_syscall/' \
| sed 's/^\s*[0-9]\+\s\+[a-z0-9]\+\s\+\([A-Za-z0-9_]\+\)\s*$$/& sys_\1/' \
> $@
-generated/linux-syscalls-amd64.h: $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/amd64.h: $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_AMD64(X, _X_COMPAT, D)\\\n' > $@
- cat -- $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|64\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_AMD64_X32(X, _X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|x32\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/amd64.tbl.fixed | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }' | \
grep '^\(common\|64\|x32\)$$')"
@@ -85,33 +87,33 @@ $(LINUX_SYSCALL_DIR)/arm.tbl.fixed: $(LINUX_SYSCALL_DIR)/arm.tbl linux/syscalls.
137 afs_syscall sys_afs_syscall \
166 vm86 sys_vm86 \
167 query_module sys_query_module \
- | cat -- $(LINUX_SYSCALL_DIR)/arm.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.fixed=) - \
| sed 's/\svserver\s*$$/& sys_ni_syscall/' \
| sed 's/\snfsservctl\s*$$/& sys_nfsservctl/' \
> $@
-generated/linux-syscalls-arm.h: $(LINUX_SYSCALL_DIR)/arm.tbl.fixed linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/arm.h: $(LINUX_SYSCALL_DIR)/arm.tbl.fixed linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_ARM_EABI(X, _X_COMPAT, D)\\\n' > $@
- cat -- $(LINUX_SYSCALL_DIR)/arm.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|eabi\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_ARM_OABI(X, X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/arm.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\" $$2}' \
| sed -n 's/\\\(common\|oabi\)$$/\\/p' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/arm.tbl.fixed | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/arm.tbl.fixed | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }' | \
grep '^\(common\|oabi\|eabi\)$$')"
-generated/linux-syscalls-ia64.h: $(LINUX_SYSCALL_DIR)/ia64.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/ia64.h: $(LINUX_SYSCALL_DIR)/ia64.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_IA64(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
$$(( 1120 - 1024 )) old_stat sys_stat \
@@ -120,16 +122,16 @@ generated/linux-syscalls-ia64.h: $(LINUX_SYSCALL_DIR)/ia64.tbl linux/syscalls.mk
$$(( 1132 - 1024 )) create_module sys_create_module \
$$(( 1135 - 1024 )) get_kernel_syms sys_get_kernel_syms \
$$(( 1136 - 1024 )) query_module sys_query_module \
- | cat -- $(LINUX_SYSCALL_DIR)/ia64.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX((" $$1 " + 1024), " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/ia64.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/ia64.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
-generated/linux-syscalls-m68k.h: $(LINUX_SYSCALL_DIR)/m68k.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/m68k.h: $(LINUX_SYSCALL_DIR)/m68k.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_M68K(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
17 break sys_ni_syscall \
@@ -149,57 +151,57 @@ generated/linux-syscalls-m68k.h: $(LINUX_SYSCALL_DIR)/m68k.tbl linux/syscalls.mk
113 vm86 sys_vm86 \
137 afs_syscall sys_ni_syscall \
278 vserver sys_ni_syscall \
- | cat -- $(LINUX_SYSCALL_DIR)/m68k.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/m68k.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/m68k.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
-generated/linux-syscalls-microblaze.h: $(LINUX_SYSCALL_DIR)/microblaze.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/microblaze.h: $(LINUX_SYSCALL_DIR)/microblaze.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_MICROBLAZE(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
251 set_zone_reclaim sys_set_zone_reclaim \
285 setaltroot sys_setaltroot \
- | cat -- $(LINUX_SYSCALL_DIR)/microblaze.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/microblaze.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/microblaze.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
-generated/linux-syscalls-mips-n32.h: $(LINUX_SYSCALL_DIR)/mips-n32.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/mips-n32.h: $(LINUX_SYSCALL_DIR)/mips-n32.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_MIPS_N32(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
242 setaltroot sys_setaltroot \
- | cat -- $(LINUX_SYSCALL_DIR)/mips-n32.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-n32.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-n32.tbl | awk '{ print $$2 }' | grep '^n32$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^n32$$')"
-generated/linux-syscalls-mips-n64.h: $(LINUX_SYSCALL_DIR)/mips-n64.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/mips-n64.h: $(LINUX_SYSCALL_DIR)/mips-n64.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_MIPS_N64(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
238 setaltroot sys_setaltroot \
- | cat -- $(LINUX_SYSCALL_DIR)/mips-n64.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-n64.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-n64.tbl | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | \
grep '^\(n64\|common\)$$')"
-generated/linux-syscalls-mips-o32.h: $(LINUX_SYSCALL_DIR)/mips-o32.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/mips-o32.h: $(LINUX_SYSCALL_DIR)/mips-o32.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_MIPS_O32(X, X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
18 old_stat sys_stat \
@@ -207,14 +209,14 @@ generated/linux-syscalls-mips-o32.h: $(LINUX_SYSCALL_DIR)/mips-o32.tbl linux/sys
82 select sys_old_select \
84 old_lstat sys_lstat \
279 setaltroot sys_setaltroot \
- | cat -- $(LINUX_SYSCALL_DIR)/mips-o32.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*\(18\|28\|82\|84\)\s\+o32.*$$/d' \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\"}' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-o32.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/mips-o32.tbl | awk '{ print $$2 }' | grep '^o32$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^o32$$')"
$(LINUX_SYSCALL_DIR)/parisc.tbl.fixed: $(LINUX_SYSCALL_DIR)/parisc.tbl linux/syscalls.mk
@@ -236,85 +238,85 @@ $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed: $(LINUX_SYSCALL_DIR)/parisc.tbl linux/sys
221 free_hugepages sys_free_hugepages \
263 vserver sys_ni_syscall \
303 timerfd sys_timerfd \
- | cat -- $(LINUX_SYSCALL_DIR)/parisc.tbl - > $@
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.fixed=) - > $@
-generated/linux-syscalls-parisc.h: $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/parisc.h: $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_PARISC_64(X, _X_COMPAT, D)\\\n' > $@
- cat -- $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|64\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_PARISC_32(X, X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\" $$2}' \
| sed -n 's/\\\(common\|32\)$$/\\/p' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/parisc.tbl.fixed | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl).fixed | awk '{ print $$2 }' | \
grep '^\(common\|64\|32\)$$')"
-generated/linux-syscalls-powerpc.h: $(LINUX_SYSCALL_DIR)/powerpc.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/powerpc.h: $(LINUX_SYSCALL_DIR)/powerpc.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_POWERPC_32(X, X_COMPAT, D)\\\n' > $@
- cat -- $(LINUX_SYSCALL_DIR)/powerpc.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\" $$2}' \
| sed -n 's/\\\(common\|32\)$$/\\/p' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_POWERPC_NOSPU(X, X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/powerpc.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\" $$2}' \
| sed -n 's/\\\(common\|nospu\)$$/\\/p' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_POWERPC_64(X, _X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/powerpc.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|64\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_POWERPC_SPU(X, _X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/powerpc.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|spu\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/powerpc.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/powerpc.tbl | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | \
grep '^\(common\|spu\|nospu\|64\|32\)$$')"
-generated/linux-syscalls-s390.h: $(LINUX_SYSCALL_DIR)/s390.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/s390.h: $(LINUX_SYSCALL_DIR)/s390.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_S390_32(X, _X_COMPAT, D)\\\n' > $@
- cat -- $(LINUX_SYSCALL_DIR)/s390.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| sed 's/^\s*\([0-9]\+\)\s\+\([A-Za-z0-9_]\+\)\s\+\([A-Za-z0-9_]\+\)\s\+-\s\+-\s*$$/\1 \2 \3 sys_\3 sys_\3/' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$5 ") D\\" $$2}' \
| sed -n 's/\\\(common\|32\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_S390_64(X, _X_COMPAT, D)\\\n' >> $@
- cat -- $(LINUX_SYSCALL_DIR)/s390.tbl \
+ cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| sed 's/^\s*\([0-9]\+\)\s\+\([A-Za-z0-9_]\+\)\s\+\([A-Za-z0-9_]\+\)\s\+-\s\+-\s*$$/\1 \2 \3 sys_\3 sys_\3/' \
| sed 's/^\s*\(89\)\s\+\(common\)\s\+\(readdir\)\s\+-\s\+/\1 \2 \3 sys_old_readdir /' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|64\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/s390.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/s390.tbl | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | \
grep '^\(common\|32\|64\)$$')"
-generated/linux-syscalls-sh.h: $(LINUX_SYSCALL_DIR)/sh.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/sh.h: $(LINUX_SYSCALL_DIR)/sh.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_SH(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
17 break sys_ni_syscall \
@@ -341,16 +343,16 @@ generated/linux-syscalls-sh.h: $(LINUX_SYSCALL_DIR)/sh.tbl linux/syscalls.mk
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/sh.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/sh.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
-generated/linux-syscalls-sparc.h: $(LINUX_SYSCALL_DIR)/sparc.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/sparc.h: $(LINUX_SYSCALL_DIR)/sparc.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_SPARC_32(X, X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
267 vserver sys_vserver \
- | cat -- $(LINUX_SYSCALL_DIR)/sparc.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed 's/compat_sys_\(truncate64\|ftruncate64\)/sparc___&/g' \
| sed '/^\s*267\s\+common\s\+vserver\s\+.*$$/d' \
| sed '/^\s*\(\x23.*\)\?$$/d' \
@@ -361,48 +363,48 @@ generated/linux-syscalls-sparc.h: $(LINUX_SYSCALL_DIR)/sparc.tbl linux/syscalls.
printf '\n\43define LIST_LINUX_SYSCALLS_FOR_SPARC_64(X, _X_COMPAT, D)\\\n' >> $@
printf '%i common %s %s\n' \
267 vserver sys_vserver \
- | cat -- $(LINUX_SYSCALL_DIR)/sparc.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed '/^\s*267\s\+common\s\+vserver\s\+.*$$/d' \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\" $$2}' \
| sed -n 's/\\\(common\|64\)$$/\\/p' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/sparc.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/sparc.tbl | awk '{ print $$2 }' | \
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | \
grep '^\(common\|32\|64\)$$')"
-generated/linux-syscalls-x86.h: $(LINUX_SYSCALL_DIR)/x86.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/x86.h: $(LINUX_SYSCALL_DIR)/x86.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_I386(X, X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
251 set_zone_reclaim sys_set_zone_reclaim \
285 setaltroot sys_setaltroot \
- | cat -- $(LINUX_SYSCALL_DIR)/x86.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed 's/\s\+\(break\|stty\|gtty\|ftime\|prof\|lock\|mpx\|ulimit\|profil\|idle\|afs_syscall\|getpmsg\|putpmsg\|vserver\)\s*$$/& sys_ni_syscall/' \
| sed 's/^\s*[0-9]\+\s\+[a-z0-9]\+\s\+\([A-Za-z0-9_]\+\)\s*$$/& sys_\1/' \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX_COMPAT(" $$1 ", " $$3 ", " $$4 ", " $$5 ") D\\"}' \
| sed 's/X_COMPAT(\(.*\), ) D\\$$/X(\1) D\\/' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/x86.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/x86.tbl | awk '{ print $$2 }' | grep '^i386$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^i386$$')"
-generated/linux-syscalls-xtensa.h: $(LINUX_SYSCALL_DIR)/xtensa.tbl linux/syscalls.mk
- mkdir -p -- generated
+generated/linux-syscalls/xtensa.h: $(LINUX_SYSCALL_DIR)/xtensa.tbl linux/syscalls.mk
+ mkdir -p -- generated/linux-syscalls
printf '\43define LIST_LINUX_SYSCALLS_FOR_XTENSA(X, _X_COMPAT, D)\\\n' > $@
printf '%i common %s %s\n' \
305 timerfd sys_timerfd \
- | cat -- $(LINUX_SYSCALL_DIR)/xtensa.tbl - \
+ | cat -- $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) - \
| sed 's/reserved152\s\+sys_ni_syscall/set_thread_area sys_set_thread_area/' \
| sed 's/reserved153\s\+sys_ni_syscall/get_thread_area sys_get_thread_area/' \
| sed 's/nfsservctl\s\+sys_ni_syscall/nfsservctl sys_nfsservctl/' \
| sed '/^\s*\(\x23.*\)\?$$/d' \
| awk '{ print "\tX(" $$1 ", " $$3 ", " $$4 ") D\\"}' \
| sed '$$s/ D\\$$//' >> $@
- test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/xtensa.tbl | awk '{ print $$2 }')" = \
- "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/xtensa.tbl | awk '{ print $$2 }' | grep '^common$$')"
+ test "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }')" = \
+ "$$(sed '/^\s*\(\x23.*\)\?$$/d' < $(LINUX_SYSCALL_DIR)/$(@F:.h=.tbl) | awk '{ print $$2 }' | grep '^common$$')"
$(LINUX_SYSCALLS_ARCH_TBL_SIMPLE): $(LINUX_SOURCE) linux/syscalls.mk
diff --git a/linux/types.mk b/linux/types.mk
index 0e27c13..0e10bee 100644
--- a/linux/types.mk
+++ b/linux/types.mk
@@ -1,2 +1,4 @@
+# See LICENSE file for copyright and license details.
+
libsyscalls_get_datatype_description.o: linux/types.c
libsyscalls_get_datatype_description.lo: linux/types.c
diff --git a/mk/generate.mk b/mk/generate.mk
index ec33cdc..17671f4 100644
--- a/mk/generate.mk
+++ b/mk/generate.mk
@@ -1,3 +1,4 @@
+# See LICENSE file for copyright and license details.
NPARAMS != printf '%d\n' 1 $(NPARAMS) | sort -n | sed -n '$$p'
IMPORTANT_CPPFLAGS += -DNPARAMS="$(NPARAMS)"
diff --git a/test b/test
new file mode 100755
index 0000000..803f45f
--- /dev/null
+++ b/test
@@ -0,0 +1,588 @@
+#!/bin/sh
+# See LICENSE file for copyright and license details.
+
+if test $# = 0; then
+ if "$0" fail for me; then
+ printf 'Testing is broken!\n' >&2
+ exit 2
+ fi
+ "$0" $$
+ r=$?
+ rm -f -- .?-$$.tmp
+ exit $r
+fi
+
+
+set -e
+test $# = 1
+pid=$1
+a=.a-$pid.tmp
+b=.b-$pid.tmp
+PATH="$(dirname -- "$0")/testutil:$PATH"
+export PATH
+
+
+
+stderr () {
+ ("$@") 2>&1 >/dev/null
+}
+
+getlist () {
+ getlist_list="$1"
+ shift 1
+ if test $# = 0; then set cat; fi
+ "$@" < libsyscalls.h \
+ | tr , '\n' \
+ | sed -n 's/^\s*LIBSYSCALLS_'"${getlist_list}"'_\([A-Z0-9_]\+\(\s*=\s*[ 0-9A-Fa-fxXULul()^&|!*/<>~+-]\+\)\?\)\b.*$/\1/p' \
+ | tr = ' ' \
+ | (i=0; while read name value; do
+ if test -n "$value"; then
+ i=$(( $(printf '%s\n' "$value" | tr -d 'ULul') ))
+ i=$(printf '%s\n' "$i" | cut -d . -f 1)
+ fi
+ printf '%i %s\n' $(( i++ )) $name;
+ done)
+}
+
+getnamelist () {
+ getlist "$@" | cut -d ' ' -f 2
+}
+
+getnumlist () {
+ getlist "$@" | cut -d ' ' -f 1
+}
+
+getname () {
+ (getlist "$1" | grep "^$2 " | cut -d ' ' -f 2 | tee /dev/stderr | grep . >/dev/null) 2>&1
+}
+
+getnum () {
+ (getlist "$1" | grep " $2"\$ | cut -d ' ' -f 1 | tee /dev/stderr | grep . >/dev/null) 2>&1
+}
+
+lookupname () {
+ (printf '%s\n' "$1" | grep "^$2 " | cut -d ' ' -f 2 | tee /dev/stderr | grep . >/dev/null) 2>&1
+}
+
+lookupnum () {
+ (printf '%s\n' "$1" | grep " $2"\$ | cut -d ' ' -f 1 | tee /dev/stderr | grep . >/dev/null) 2>&1
+}
+
+issupported () {
+ if test $# = 1; then
+ printf '%s\n' ${SUPPORTED_OSES} | grep -i "^$1"\$ > /dev/null
+ else
+ printf '%s\n' ${SUPPORTED_OSES} | grep -i "^$1"\$ > /dev/null &&
+ env | sed -n 's/^SUPPORTED_'"$1"'_ARCHES=//p' | xargs printf '%s\n' | grep -i "^$2"\$ > /dev/null
+ fi
+}
+
+
+
+set -v
+
+
+# self check
+(
+ set -e
+ stderr_printf () {
+ printf "$@" >&2
+ }
+ test "$(stderr_printf 'hello\n')" = ''
+ test "$(stderr stderr_printf 'hello\n' 2>&1)" = 'hello'
+ (! (false > $a) )
+ getname OS 0
+ (! getname OS)
+ getnum OS LINUX
+ (! getnum OS 0)
+ getnamelist OS | grep LINUX
+ getnamelist ARCH | grep AMD64_X32
+ getnumlist OS | grep '^0$'
+ getnumlist ARCH | grep 10
+ getnumlist OS ${CPP} | grep '^0$'
+ test -n "${CPP}"
+ test "$(getname OS 0)" = LINUX
+ test "$(getnum OS LINUX)" = 0
+ test "$(lookupnum "$(getlist OS)" LINUX)" = 0
+ test "$(lookupname "$(getlist OS)" 0)" = LINUX
+ printf 'a\n' > $a
+ printf 'b\n' > $b
+ (! diff -u $a $b)
+ printf 'a\n' > $b
+ diff -u $a $b
+ for os in ${SUPPORTED_OSES}; do
+ issupported $os
+ for arch in $(env | sed -n 's/^SUPPORTED_'"$os"'_ARCHES=//p' | xargs printf '%s\n'); do
+ issupported $os $arch
+ done
+ done
+) >/dev/null 2>/dev/null
+
+
+
+### enums ###
+
+cpp_enum_clean () {
+ $CPP < libsyscalls.h | grep -v '#' | tr '\n,{}' ' \n\n\n'
+}
+check_enum_good () {
+ test -n "$(getnamelist "$@")"
+ test -n "$(getnumlist "$@")"
+ test -z "$(getnamelist "$@" | sort | uniq -d)"
+ test -z "$(getnumlist "$@" | sort | uniq -d)"
+ (( "$(getnumlist "$@" | sort -n | sed -n \$p)" <= 0xFFFF ))
+}
+check_enum_good OS
+check_enum_good ARCH
+check_enum_good CAT
+for cat in $(getnamelist CAT); do
+ if test "$cat" = SUPPORT_PENDING || test "$cat" = NOT_IMPLEMENTED; then
+ continue
+ fi
+ check_enum_good ${cat}_SUBCAT
+ grep -i "enum.libsyscalls_${cat}_syscall_subcategory"'\s\+'"$cat"\\b < libsyscalls.h >/dev/null
+done
+check_enum_good SIGN
+check_enum_good ANNOTATION
+check_enum_good SECTION
+check_enum_good TYPE cpp_enum_clean
+types="$(getlist TYPE cpp_enum_clean)"
+
+
+
+### libsyscalls errors ###
+
+strerror-all.tu > $a
+stderr perror-all.tu > $b
+diff -u $a $b
+test $(wc -l < $a) -ge 10
+
+strerror-bad.tu > $a
+stderr perror-bad.tu > $b
+diff -u $a $b
+test $(wc -l < $a) = 2
+grep -i '\(un\|not \)recogni[sz]ed' > /dev/null < $a
+test "$(sed 1q < $a)" = "$(sed 1d < $a)"
+
+for t in perror-bad.tu perror-all.tu; do
+ stderr $t "" > $a
+ stderr $t > $b
+ diff -u $a $b
+
+ stderr $t "test" > $a
+ stderr $t > $b
+ (! diff -u $a $b >/dev/null)
+
+ stderr $t "test" > $a
+ stderr $t | sed 's/^/test: /' > $b
+ diff -u $a $b
+done
+
+strerror-all.tu > $a
+list-errors.tu > $b
+(! grep '^-' >/dev/null < $b)
+grep '^[0-9]\+ ' >/dev/null < $b
+grep '^[0-9]\+ LIBSYSCALLS_E_[A-Z]\+ ' >/dev/null < $b
+grep '^[0-9]\+ LIBSYSCALLS_E_[A-Z]\+ [A-Z].*[^.]$' >/dev/null < $b
+cut -d ' ' -f 3- < $b | diff -u $a -
+sed 1q < $b | grep '^0 LIBSYSCALLS_E_OK Success$' >/dev/null
+test -z "$(cut -d ' ' -f 1 < $b | sort | uniq -d)"
+test -z "$(cut -d ' ' -f 2 < $b | sort | uniq -d)"
+test -z "$(cut -d ' ' -f 3- < $b | sort | uniq -d)"
+
+test "$(get-error.tu LIBSYSCALLS_E_OK)" = 'Success'
+test "$(get-error.tu LIBSYSCALLS_E_OSNOSUP)" = 'Operating system not supported'
+test "$(get-error.tu LIBSYSCALLS_E_NOSUCHSYSCALL)" = 'No such system call'
+
+# This can be updated, its just to check that nothing is accidentally changed in LIBSYSCALLS_LIST_ERRORS
+cat > $a <<.
+0 LIBSYSCALLS_E_OK Success
+1 LIBSYSCALLS_E_OSNOSUP Operating system not supported
+2 LIBSYSCALLS_E_ARCHNOSUP Architecture not supported for selected operating system
+3 LIBSYSCALLS_E_NOSUCHSYSCALL No such system call
+4 LIBSYSCALLS_E_NOERRORS There is no error listing for selected operating system
+5 LIBSYSCALLS_E_NOSIGNALS There is no signal listing for selected operating system
+6 LIBSYSCALLS_E_NOMEM Failed to allocate required memory
+7 LIBSYSCALLS_E_INVAL Invalid arguments passed to function
+8 LIBSYSCALLS_E_NOSUCHTYPE Type does not exist on the selected operating system or architecture
+9 LIBSYSCALLS_E_ISSTRUCT Type is a structure or union
+.
+list-errors.tu | diff -u $a -
+
+
+
+### System call number ranges ###
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ get-syscall-range.tu $osn $archn $os $arch > $a
+ min="$(sed -n 's/min: //p' < $a)"
+ max="$(sed -n 's/max: //p' < $a)"
+ test -n "$min"
+ test -n "$max"
+ if test $min = x || test $max = x; then
+ (! issupported $os $arch)
+ continue
+ fi
+ issupported $os $arch
+ done
+done
+check_range () {
+ if issupported $1 $2; then
+ osn=$(getnum OS $1)
+ archn=$(getnum ARCH $2)
+ get-syscall-range.tu $osn $archn $1 $2 > $a
+ min="$(sed -n 's/min: //p' < $a)"
+ max="$(sed -n 's/max: //p' < $a)"
+ test $min -le $3
+ test $max -ge $4
+ test -z "$5" || test $min -ge $5
+ fi
+}
+check_range LINUX AMD64 0 453 0
+check_range LINUX AMD64_X32 0 547 0
+check_range LINUX M68K 0 452 0
+check_range LINUX PARISC_32 0 452 0
+check_range LINUX PARISC_64 0 452 0
+check_range LINUX SPARC_32 0 452 0
+check_range LINUX I386 0 452 0
+
+
+
+### System call errors ###
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ get-syscall-errors.tu $osn $archn $os $arch > $a
+ grep -v '^[0-9]\+ -' >/dev/null < $a
+ grep -v '^-' < $a > $b
+ grep '^\([0-9]\+\) \1 ' < $a | diff -u $a -
+ if issupported $os $arch; then
+ (! test "$(cat $a)" = x)
+ if test "$os" = LINUX; then
+ signed=1
+ grep '^[0-9]\+ [0-9]\+ [A-Z0-9_]\+$' >/dev/null < $a
+ test -z "$(grep -v '^[0-9]\+ [0-9]\+ [A-Z0-9_]\+$' < $a)"
+ required="ERESTARTSYS ERESTARTNOINTR ERESTARTNOHAND ERESTART_RESTARTBLOCK EPERM ENOENT EDOM ELOOP"
+ else
+ continue;
+ fi
+ for req in $required; do
+ grep '^-\?[0-9]\+ [0-9]\+ '"$req"\$ >/dev/null < $a
+ done
+ cut -d ' ' -f $(( 2 - signed )) < $a > $b && sort -n < $b | diff -u $b -
+ if test -f testcases/errors-$os-$arch; then
+ if ! diff -u testcases/errors-$os-$arch $a; then
+ printf '\x1b[33m%s\x1b[m\n' "Maybe new errors have been added for $os on $arch"
+ exit 1
+ fi
+ fi
+ else
+ # Can still be successful because it may be hardcorded to
+ # use the same table as another architecture that is supported,
+ # however it cannot be successful if the OS is not supported
+ issupported $os
+ fi
+ test -z "$(cut -d ' ' -f 1 < $a | sort | uniq -d)"
+ test -z "$(cut -d ' ' -f 2 < $a | sort | uniq -d)"
+ test -z "$(cut -d ' ' -f 3 < $a | sort | uniq -d)"
+ done
+done
+test -f testcases/errors-LINUX-AMD64
+test -f testcases/errors-LINUX-PARISC_32
+test -f testcases/errors-LINUX-PARISC_64
+(! diff -u testcases/errors-LINUX-AMD64 testcases/errors-LINUX-PARISC_32 >/dev/null)
+
+
+
+### Operating system signals ###
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ get-signals.tu $osn $archn $os $arch > $a
+ grep -v '^[0-9]\+ -' >/dev/null < $a
+ grep -v '^-' < $a > $b
+ grep '^\([0-9]\+\) \1 ' < $a | diff -u $a -
+ if issupported $os $arch; then
+ (! test "$(cat $a)" = x)
+ if test "$os" = LINUX; then
+ signed=1
+ grep '^[0-9]\+ [0-9]\+ [A-Z0-9_+]\+$' >/dev/null < $a
+ test -z "$(grep -v '^[0-9]\+ [0-9]\+ [A-Z0-9_+]\+$' < $a)"
+ required="SIGKILL SIGTERM SIGCONT SIGSTOP SIGHUP _SIGRTMIN _SIGRTMIN+8"
+ else
+ continue;
+ fi
+ for req in $required; do
+ grep '^-\?[0-9]\+ [0-9]\+ '"$req"\$ >/dev/null < $a
+ done
+ cut -d ' ' -f $(( 2 - signed )) < $a > $b && sort -n < $b | diff -u $b -
+ if test -f testcases/signals-$os-$arch; then
+ if ! diff -u testcases/signals-$os-$arch $a; then
+ printf '\x1b[33m%s\x1b[m\n' "Maybe new signals have been added for $os on $arch"
+ exit 1
+ fi
+ fi
+ else
+ # Can still be successful because it may be hardcorded to
+ # use the same table as another architecture that is supported,
+ # however it cannot be successful if the OS is not supported
+ issupported $os
+ fi
+ test -z "$(cut -d ' ' -f 1 < $a | sort | uniq -d)"
+ test -z "$(cut -d ' ' -f 2 < $a | sort | uniq -d)"
+ test -z "$(cut -d ' ' -f 3 < $a | sort | uniq -d)"
+ done
+done
+test -f testcases/signals-LINUX-AMD64
+
+
+
+### Split register classifications ###
+
+test $(getnamelist SECTION | grep '_HALF$' | wc -l) -ge 8
+for sec in $(getnamelist SECTION | grep '_HALF$'); do
+ secn=$(getnum SECTION $sec)
+ is-section-half.tu $secn
+ (! is-section-quarter.tu $secn)
+ test $(get-section-fraction.tu $secn) = 2
+done
+
+test $(getnamelist SECTION | grep '_QUARTER$' | wc -l) -ge 4
+for sec in $(getnamelist SECTION | grep '_QUARTER$'); do
+ secn=$(getnum SECTION $sec)
+ is-section-quarter.tu $secn
+ (! is-section-half.tu $secn)
+ test $(get-section-fraction.tu $secn) = 4
+done
+
+secn="$(getnum SECTION WHOLE)"
+test -n "$secn"
+test $(get-section-fraction.tu $secn) = 1
+
+
+
+### Data types ###
+
+#in this test, we are assuming that char is 8 bits
+intsizes="8 16 32 64"
+cat > $b <<.
+8Little 0
+16Little 0 8
+32Little 0 8 16 24
+64Little 0 8 16 24 32 40 48 56
+8Big 0
+16Big 8 0
+32Big 24 16 8 0
+64Big 56 48 40 32 24 16 8 0
+.
+byteorders="$(cat $b)"
+getbyteorder () {
+ printf '%s\n' "$byteorders" | grep "^$1$2 " | cut -d ' ' -f 2-
+}
+
+sed '1,/LIST_ARCH_SPECS/d' < libsyscalls_get_datatype_description.c \
+| sed '/#include/q' \
+| sed 's/\(TO''DO\)\s*([^)]*)/\1/g' \
+| sed -n 's/^\s*[A-Z_]\+(LIBSYSCALLS_ARCH_\([^)]*\)).*$/\1/p' \
+| sed 's/,\s*/ /g' > $b
+grep '^AMD64 8 64 64 Little TWOS_COMPLEMENT' >/dev/null < $b
+grep '^AMD64_X32 8 32 32 Little TWOS_COMPLEMENT' >/dev/null < $b
+grep '^M68K 8 32 32 Big TWOS_COMPLEMENT' >/dev/null < $b
+grep '^PARISC_32 8 32 32 Big TWOS_COMPLEMENT' >/dev/null < $b
+grep '^PARISC_64 8 64 64 Big TWOS_COMPLEMENT' >/dev/null < $b
+grep '^SPARC_32 8 32 32 Big TWOS_COMPLEMENT' >/dev/null < $b
+grep '^I386 8 32 32 Little TWOS_COMPLEMENT' >/dev/null < $b
+archinfo="$(cat $b)"
+getbytesize () {
+ printf '%s\n' "$archinfo" | grep "^$1 " | cut -d ' ' -f 2
+}
+getaddrsize () {
+ printf '%s\n' "$archinfo" | grep "^$1 " | cut -d ' ' -f 3
+}
+getsizesize () {
+ printf '%s\n' "$archinfo" | grep "^$1 " | cut -d ' ' -f 4
+}
+getendian () {
+ printf '%s\n' "$archinfo" | grep "^$1 " | cut -d ' ' -f 5
+}
+getsign () {
+ printf '%s\n' "$archinfo" | grep "^$1 " | cut -d ' ' -f 6
+}
+
+whole=$(getnum SECTION WHOLE)
+noannotation=$(getnum ANNOTATION NONE)
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ if ! issupported $os $arch; then
+ continue
+ fi
+
+ endian=$(getendian $arch)
+
+ sign_representation=$(getsign $arch)
+ if test ${sign_representation} = TWOS_COMPLEMENT; then
+ min_is_minus_max=0
+ elif test ${sign_representation} = ONES_COMPLEMENT; then
+ min_is_minus_max=1
+ elif test ${sign_representation} = SIGN_MAGNITUDE; then
+ min_is_minus_max=1
+ elif test ${sign_representation} = EXCESS_HALF; then
+ min_is_minus_max=0
+ else
+ false
+ fi
+ sign_representation=$(getnum SIGN ${sign_representation})
+
+ for n in $intsizes; do
+ type=INT$n
+ desc="$(get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type)"
+ printf '%s\n' "$desc" | grep "^width_in_bits = ${n}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^array_size = 1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^relative_position_of_array_size = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^absolute_position_of_array_size = -1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_signed = 1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_unsigned = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^min_is_minus_max = ${min_is_minus_max}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^sign_representation = ${sign_representation}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^annotation = ${noannotation}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^section = ${whole}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^byteorder = $(getbyteorder $n $endian)"\$ >/dev/null
+ done
+ for n in $intsizes; do
+ type=UINT$n
+ desc="$(get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type)"
+ printf '%s\n' "$desc" | grep "^width_in_bits = ${n}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^array_size = 1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^relative_position_of_array_size = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^absolute_position_of_array_size = -1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_signed = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_unsigned = 1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^annotation = ${noannotation}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^section = ${whole}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^byteorder = $(getbyteorder $n $endian)"\$ >/dev/null
+ done
+
+ type=VOID
+ desc="$(get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type | tee $a)"
+ printf '%s\n' "$desc" | grep "^width_in_bits = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^array_size = 1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^relative_position_of_array_size = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^absolute_position_of_array_size = -1"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_signed = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^is_unsigned = 0"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^annotation = ${noannotation}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^section = ${whole}"\$ >/dev/null
+ printf '%s\n' "$desc" | grep "^byteorder =\s*"\$ >/dev/null
+ type=NO_RETURN
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type | diff -u $a -
+
+ type=INT
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=INT_SIGNAL
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ sed 's/^\(annotation\) .*$/\1 = '"$(getnum ANNOTATION SIGNAL)"'/' < $a | diff -u - $b
+ type=INT_FD
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ sed 's/^\(annotation\) .*$/\1 = '"$(getnum ANNOTATION FD)"'/' < $a | diff -u - $b
+ type=INT_ATFD
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ sed 's/^\(annotation\) .*$/\1 = '"$(getnum ANNOTATION ATFD)"'/' < $a | diff -u - $b
+
+ type=LONG
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=LONG_FD
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ sed 's/^\(annotation\) .*$/\1 = '"$(getnum ANNOTATION FD)"'/' < $a | diff -u - $b
+ type=LONG_ATFD
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ sed 's/^\(annotation\) .*$/\1 = '"$(getnum ANNOTATION ATFD)"'/' < $a | diff -u - $b
+
+ for type in SCHAR SHORT INT LONG LLONG PTRDIFF INTPTR SSIZE; do
+ if test $type = SCHAR; then
+ utype=UCHAR
+ elif test $type = SSIZE; then
+ utype=SIZE
+ else
+ utype=U$type
+ fi
+
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ grep "^width_in_bits = ." < $a >/dev/null
+ grep "^array_size = 1"\$ < $a >/dev/null
+ grep "^relative_position_of_array_size = 0"\$ < $a >/dev/null
+ grep "^absolute_position_of_array_size = -1"\$ < $a >/dev/null
+ grep "^is_signed = 1"\$ < $a >/dev/null
+ grep "^is_unsigned = 0"\$ < $a >/dev/null
+ grep "^min_is_minus_max = ${min_is_minus_max}"\$ < $a >/dev/null
+ grep "^sign_representation = ${sign_representation}"\$ < $a >/dev/null
+ grep "^annotation = ${noannotation}"\$ < $a >/dev/null
+ grep "^section = ${whole}"\$ < $a >/dev/null
+ n="$(grep "^width_in_bits = ." < $a | cut -d ' ' -f 3)"
+ grep "^byteorder = $(getbyteorder $n $endian)"\$ < $a >/dev/null
+
+ sed -e 's/^\(is_signed =\) .$/\1 0/' -e 's/^\(is_unsigned =\) .$/\1 1/' < $a > $b
+ ( ! diff -u $b $a > /dev/null)
+ grep -v '^\(min_is_minus_max\|sign_representation\) = ' < $b > $a
+ ( ! diff -u $a $b > /dev/null)
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $utype) $os $arch $utype > $b
+ grep -v '^\(min_is_minus_max\|sign_representation\) = ' < $b | diff -u $a -
+
+ if test $type = SCHAR; then
+ xtypes=CHAR
+ elif test $type = INTPTR; then
+ xtypes="MEMORY_ADDRESS STRING STRINGS_THEN_NULL"
+ else
+ xtypes=
+ fi
+ for xtype in $xtypes; do
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $xtype) $os $arch $xtype \
+ | grep -v '^\(min_is_minus_max\|sign_representation\) = ' > $b
+ sed 's/^\(is_\(un\)signed =\) .$/\1 0/' < $a | diff -u - $b
+ done
+ done
+
+ type=INTPTR
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=PTRDIFF
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ diff -u $a $b
+
+ type=DYNAMIC
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=UNKNOWN
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ diff -u $a $b
+ done
+done
+
+printf '%s\n' "$types" | grep STRUCT >/dev/null
+printf '%s\n' "$types" | grep UNION >/dev/null
+structs="$(printf '%s\n' "$types" | grep '\(STRUCT\|UNION\)' | cut -d ' ' -f 1)"
+int=$(lookupnum "$types" INT)
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ if ! issupported $os $arch; then
+ continue
+ fi
+ ( ! is-datatype-struct.tu $osn $archn $int $os $arch INT )
+ for type in $structs; do
+ is-datatype-struct.tu $osn $archn $type $os $arch 'some struct or union'
+ done
+ done
+done
+
+
+
+# TODO test libsyscalls_get_syscall
+# TODO test libsyscalls_get_syscall_display_info
diff --git a/testcases/errors-LINUX-AMD64 b/testcases/errors-LINUX-AMD64
new file mode 100644
index 0000000..c48ca78
--- /dev/null
+++ b/testcases/errors-LINUX-AMD64
@@ -0,0 +1,150 @@
+1 1 EPERM
+2 2 ENOENT
+3 3 ESRCH
+4 4 EINTR
+5 5 EIO
+6 6 ENXIO
+7 7 E2BIG
+8 8 ENOEXEC
+9 9 EBADF
+10 10 ECHILD
+11 11 EAGAIN
+12 12 ENOMEM
+13 13 EACCES
+14 14 EFAULT
+15 15 ENOTBLK
+16 16 EBUSY
+17 17 EEXIST
+18 18 EXDEV
+19 19 ENODEV
+20 20 ENOTDIR
+21 21 EISDIR
+22 22 EINVAL
+23 23 ENFILE
+24 24 EMFILE
+25 25 ENOTTY
+26 26 ETXTBSY
+27 27 EFBIG
+28 28 ENOSPC
+29 29 ESPIPE
+30 30 EROFS
+31 31 EMLINK
+32 32 EPIPE
+33 33 EDOM
+34 34 ERANGE
+35 35 EDEADLK
+36 36 ENAMETOOLONG
+37 37 ENOLCK
+38 38 ENOSYS
+39 39 ENOTEMPTY
+40 40 ELOOP
+42 42 ENOMSG
+43 43 EIDRM
+44 44 ECHRNG
+45 45 EL2NSYNC
+46 46 EL3HLT
+47 47 EL3RST
+48 48 ELNRNG
+49 49 EUNATCH
+50 50 ENOCSI
+51 51 EL2HLT
+52 52 EBADE
+53 53 EBADR
+54 54 EXFULL
+55 55 ENOANO
+56 56 EBADRQC
+57 57 EBADSLT
+59 59 EBFONT
+60 60 ENOSTR
+61 61 ENODATA
+62 62 ETIME
+63 63 ENOSR
+64 64 ENONET
+65 65 ENOPKG
+66 66 EREMOTE
+67 67 ENOLINK
+68 68 EADV
+69 69 ESRMNT
+70 70 ECOMM
+71 71 EPROTO
+72 72 EMULTIHOP
+73 73 EDOTDOT
+74 74 EBADMSG
+75 75 EOVERFLOW
+76 76 ENOTUNIQ
+77 77 EBADFD
+78 78 EREMCHG
+79 79 ELIBACC
+80 80 ELIBBAD
+81 81 ELIBSCN
+82 82 ELIBMAX
+83 83 ELIBEXEC
+84 84 EILSEQ
+85 85 ERESTART
+86 86 ESTRPIPE
+87 87 EUSERS
+88 88 ENOTSOCK
+89 89 EDESTADDRREQ
+90 90 EMSGSIZE
+91 91 EPROTOTYPE
+92 92 ENOPROTOOPT
+93 93 EPROTONOSUPPORT
+94 94 ESOCKTNOSUPPORT
+95 95 EOPNOTSUPP
+96 96 EPFNOSUPPORT
+97 97 EAFNOSUPPORT
+98 98 EADDRINUSE
+99 99 EADDRNOTAVAIL
+100 100 ENETDOWN
+101 101 ENETUNREACH
+102 102 ENETRESET
+103 103 ECONNABORTED
+104 104 ECONNRESET
+105 105 ENOBUFS
+106 106 EISCONN
+107 107 ENOTCONN
+108 108 ESHUTDOWN
+109 109 ETOOMANYREFS
+110 110 ETIMEDOUT
+111 111 ECONNREFUSED
+112 112 EHOSTDOWN
+113 113 EHOSTUNREACH
+114 114 EALREADY
+115 115 EINPROGRESS
+116 116 ESTALE
+117 117 EUCLEAN
+118 118 ENOTNAM
+119 119 ENAVAIL
+120 120 EISNAM
+121 121 EREMOTEIO
+122 122 EDQUOT
+123 123 ENOMEDIUM
+124 124 EMEDIUMTYPE
+125 125 ECANCELED
+126 126 ENOKEY
+127 127 EKEYEXPIRED
+128 128 EKEYREVOKED
+129 129 EKEYREJECTED
+130 130 EOWNERDEAD
+131 131 ENOTRECOVERABLE
+132 132 ERFKILL
+133 133 EHWPOISON
+512 512 ERESTARTSYS
+513 513 ERESTARTNOINTR
+514 514 ERESTARTNOHAND
+515 515 ENOIOCTLCMD
+516 516 ERESTART_RESTARTBLOCK
+517 517 EPROBE_DEFER
+518 518 EOPENSTALE
+519 519 ENOPARAM
+521 521 EBADHANDLE
+522 522 ENOTSYNC
+523 523 EBADCOOKIE
+524 524 ENOTSUPP
+525 525 ETOOSMALL
+526 526 ESERVERFAULT
+527 527 EBADTYPE
+528 528 EJUKEBOX
+529 529 EIOCBQUEUED
+530 530 ERECALLCONFLICT
+531 531 ENOGRACE
diff --git a/testcases/errors-LINUX-PARISC_32 b/testcases/errors-LINUX-PARISC_32
new file mode 100644
index 0000000..eda7276
--- /dev/null
+++ b/testcases/errors-LINUX-PARISC_32
@@ -0,0 +1,152 @@
+1 1 EPERM
+2 2 ENOENT
+3 3 ESRCH
+4 4 EINTR
+5 5 EIO
+6 6 ENXIO
+7 7 E2BIG
+8 8 ENOEXEC
+9 9 EBADF
+10 10 ECHILD
+11 11 EAGAIN
+12 12 ENOMEM
+13 13 EACCES
+14 14 EFAULT
+15 15 ENOTBLK
+16 16 EBUSY
+17 17 EEXIST
+18 18 EXDEV
+19 19 ENODEV
+20 20 ENOTDIR
+21 21 EISDIR
+22 22 EINVAL
+23 23 ENFILE
+24 24 EMFILE
+25 25 ENOTTY
+26 26 ETXTBSY
+27 27 EFBIG
+28 28 ENOSPC
+29 29 ESPIPE
+30 30 EROFS
+31 31 EMLINK
+32 32 EPIPE
+33 33 EDOM
+34 34 ERANGE
+35 35 ENOMSG
+36 36 EIDRM
+37 37 ECHRNG
+38 38 EL2NSYNC
+39 39 EL3HLT
+40 40 EL3RST
+41 41 ELNRNG
+42 42 EUNATCH
+43 43 ENOCSI
+44 44 EL2HLT
+45 45 EDEADLK
+46 46 ENOLCK
+47 47 EILSEQ
+50 50 ENONET
+51 51 ENODATA
+52 52 ETIME
+53 53 ENOSR
+54 54 ENOSTR
+55 55 ENOPKG
+57 57 ENOLINK
+58 58 EADV
+59 59 ESRMNT
+60 60 ECOMM
+61 61 EPROTO
+64 64 EMULTIHOP
+66 66 EDOTDOT
+67 67 EBADMSG
+68 68 EUSERS
+69 69 EDQUOT
+70 70 ESTALE
+71 71 EREMOTE
+72 72 EOVERFLOW
+160 160 EBADE
+161 161 EBADR
+162 162 EXFULL
+163 163 ENOANO
+164 164 EBADRQC
+165 165 EBADSLT
+166 166 EBFONT
+167 167 ENOTUNIQ
+168 168 EBADFD
+169 169 EREMCHG
+170 170 ELIBACC
+171 171 ELIBBAD
+172 172 ELIBSCN
+173 173 ELIBMAX
+174 174 ELIBEXEC
+175 175 ERESTART
+176 176 ESTRPIPE
+177 177 EUCLEAN
+178 178 ENOTNAM
+179 179 ENAVAIL
+180 180 EISNAM
+181 181 EREMOTEIO
+182 182 ENOMEDIUM
+183 183 EMEDIUMTYPE
+184 184 ENOKEY
+185 185 EKEYEXPIRED
+186 186 EKEYREVOKED
+187 187 EKEYREJECTED
+215 215 ENOSYM
+216 216 ENOTSOCK
+217 217 EDESTADDRREQ
+218 218 EMSGSIZE
+219 219 EPROTOTYPE
+220 220 ENOPROTOOPT
+221 221 EPROTONOSUPPORT
+222 222 ESOCKTNOSUPPORT
+223 223 EOPNOTSUPP
+224 224 EPFNOSUPPORT
+225 225 EAFNOSUPPORT
+226 226 EADDRINUSE
+227 227 EADDRNOTAVAIL
+228 228 ENETDOWN
+229 229 ENETUNREACH
+230 230 ENETRESET
+231 231 ECONNABORTED
+232 232 ECONNRESET
+233 233 ENOBUFS
+234 234 EISCONN
+235 235 ENOTCONN
+236 236 ESHUTDOWN
+237 237 ETOOMANYREFS
+238 238 ETIMEDOUT
+239 239 ECONNREFUSED
+240 240 EREMOTERELEASE
+241 241 EHOSTDOWN
+242 242 EHOSTUNREACH
+244 244 EALREADY
+245 245 EINPROGRESS
+247 247 ENOTEMPTY
+248 248 ENAMETOOLONG
+249 249 ELOOP
+251 251 ENOSYS
+253 253 ECANCELLED
+254 254 EOWNERDEAD
+255 255 ENOTRECOVERABLE
+256 256 ERFKILL
+257 257 EHWPOISON
+512 512 ERESTARTSYS
+513 513 ERESTARTNOINTR
+514 514 ERESTARTNOHAND
+515 515 ENOIOCTLCMD
+516 516 ERESTART_RESTARTBLOCK
+517 517 EPROBE_DEFER
+518 518 EOPENSTALE
+519 519 ENOPARAM
+521 521 EBADHANDLE
+522 522 ENOTSYNC
+523 523 EBADCOOKIE
+524 524 ENOTSUPP
+525 525 ETOOSMALL
+526 526 ESERVERFAULT
+527 527 EBADTYPE
+528 528 EJUKEBOX
+529 529 EIOCBQUEUED
+530 530 ERECALLCONFLICT
+531 531 ENOGRACE
diff --git a/testcases/errors-LINUX-PARISC_64 b/testcases/errors-LINUX-PARISC_64
new file mode 120000
index 0000000..f5c14d9
--- /dev/null
+++ b/testcases/errors-LINUX-PARISC_64
@@ -0,0 +1 @@
+errors-LINUX-PARISC_32 \ No newline at end of file
diff --git a/testcases/signals-LINUX-AMD64 b/testcases/signals-LINUX-AMD64
new file mode 100644
index 0000000..4bc3c5d
--- /dev/null
+++ b/testcases/signals-LINUX-AMD64
@@ -0,0 +1,64 @@
+1 1 SIGHUP
+2 2 SIGINT
+3 3 SIGQUIT
+4 4 SIGILL
+5 5 SIGTRAP
+6 6 SIGABRT
+7 7 SIGBUS
+8 8 SIGFPE
+9 9 SIGKILL
+10 10 SIGUSR1
+11 11 SIGSEGV
+12 12 SIGUSR2
+13 13 SIGPIPE
+14 14 SIGALRM
+15 15 SIGTERM
+16 16 SIGSTKFLT
+17 17 SIGCHLD
+18 18 SIGCONT
+19 19 SIGSTOP
+20 20 SIGTSTP
+21 21 SIGTTIN
+22 22 SIGTTOU
+23 23 SIGURG
+24 24 SIGXCPU
+25 25 SIGXFSZ
+26 26 SIGVTALRM
+27 27 SIGPROF
+28 28 SIGWINCH
+29 29 SIGIO
+30 30 SIGPWR
+31 31 SIGSYS
+32 32 _SIGRTMIN
+33 33 _SIGRTMIN+1
+34 34 _SIGRTMIN+2
+35 35 _SIGRTMIN+3
+36 36 _SIGRTMIN+4
+37 37 _SIGRTMIN+5
+38 38 _SIGRTMIN+6
+39 39 _SIGRTMIN+7
+40 40 _SIGRTMIN+8
+41 41 _SIGRTMIN+9
+42 42 _SIGRTMIN+10
+43 43 _SIGRTMIN+11
+44 44 _SIGRTMIN+12
+45 45 _SIGRTMIN+13
+46 46 _SIGRTMIN+14
+47 47 _SIGRTMIN+15
+48 48 _SIGRTMIN+16
+49 49 _SIGRTMIN+17
+50 50 _SIGRTMIN+18
+51 51 _SIGRTMIN+19
+52 52 _SIGRTMIN+20
+53 53 _SIGRTMIN+21
+54 54 _SIGRTMIN+22
+55 55 _SIGRTMIN+23
+56 56 _SIGRTMIN+24
+57 57 _SIGRTMIN+25
+58 58 _SIGRTMIN+26
+59 59 _SIGRTMIN+27
+60 60 _SIGRTMIN+28
+61 61 _SIGRTMIN+29
+62 62 _SIGRTMIN+30
+63 63 _SIGRTMIN+31
+64 64 _SIGRTMIN+32
diff --git a/testutil/get-datatype-description.c b/testutil/get-datatype-description.c
new file mode 100644
index 0000000..0bec618
--- /dev/null
+++ b/testutil/get-datatype-description.c
@@ -0,0 +1,52 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_os os = (enum libsyscalls_os)atoi(argv[1]);
+ enum libsyscalls_arch arch = (enum libsyscalls_arch)atoi(argv[2]);
+ enum libsyscalls_datatype type = (enum libsyscalls_datatype)atoi(argv[3]);
+ struct libsyscalls_datatype_description desc;
+ enum libsyscalls_error err;
+ size_t i;
+
+ err = libsyscalls_get_datatype_description(os, arch, type, &desc);
+ if (err) {
+ fprintf(stderr, "libsyscalls_get_datatype_description %s %s %s: ", argv[4], argv[5], argv[6]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ printf("width_in_bits = %u\n", desc.width_in_bits);
+ printf("array_size = %u\n", desc.array_size);
+ printf("relative_position_of_array_size = %i\n", desc.relative_position_of_array_size);
+ printf("absolute_position_of_array_size = %i\n", desc.absolute_position_of_array_size);
+ printf("fill_is_known = %u\n", desc.fill_is_known);
+ printf("is_signed = %u\n", desc.is_signed);
+ printf("is_unsigned = %u\n", desc.is_unsigned);
+ printf("min_is_minus_max = %u\n", desc.min_is_minus_max);
+ printf("sign_representation = %lli\n", (long long int)desc.sign_representation);
+ printf("annotation = %lli\n", (long long int)desc.annotation);
+ printf("section = %lli\n", (long long int)desc.section);
+ printf("byteorder =");
+ for (i = 0; i < sizeof(desc.byteorder) / sizeof(*desc.byteorder); i++) {
+ if (LIBSYSCALLS_IS_BYTEORDER_END(desc.byteorder[i]))
+ goto end_of_byteorder;
+ printf(" %u", desc.byteorder[i]);
+ }
+end_of_byteorder:
+ printf("\n");
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/get-error.c b/testutil/get-error.c
new file mode 100644
index 0000000..8f066d7
--- /dev/null
+++ b/testutil/get-error.c
@@ -0,0 +1,27 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 1; i < argc; i++) {
+#define X(N, S)\
+ if (!strcmp(argv[i], #N))\
+ printf("%s\n", S)
+ LIBSYSCALLS_LIST_ERRORS(X, ;);
+#undef X
+ }
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/get-section-fraction.c b/testutil/get-section-fraction.c
new file mode 100644
index 0000000..cdb1530
--- /dev/null
+++ b/testutil/get-section-fraction.c
@@ -0,0 +1,24 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_datatype_section sec;
+
+ (void) argc;
+
+ sec = (enum libsyscalls_datatype_section)atoi(argv[1]);
+ printf("%u\n", LIBSYSCALLS_GET_SECTION_FRACTION(sec));
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/get-signals.c b/testutil/get-signals.c
new file mode 100644
index 0000000..846a0c1
--- /dev/null
+++ b/testutil/get-signals.c
@@ -0,0 +1,43 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_os os;
+ enum libsyscalls_arch arch;
+ const struct libsyscalls_named_number *signals;
+ size_t i, nsignals;
+ enum libsyscalls_error err;
+
+ (void) argc;
+
+ os = (enum libsyscalls_os)atoi(argv[1]);
+ arch = (enum libsyscalls_arch)atoi(argv[2]);
+
+ libsyscalls_get_signals(os, arch, &signals, &nsignals);
+ if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
+ printf("x\n");
+ return 0;
+ } else if (err == LIBSYSCALLS_E_NOSIGNALS) {
+ return 0;
+ } else if (err) {
+ fprintf(stderr, "test-get-syscall-signals %s %s: ", argv[3], argv[4]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ for (i = 0; i < nsignals; i++)
+ printf("%lli %llu %s\n", signals[i].number.s, signals[i].number.u, signals[i].name);
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/get-syscall-errors.c b/testutil/get-syscall-errors.c
new file mode 100644
index 0000000..c97e556
--- /dev/null
+++ b/testutil/get-syscall-errors.c
@@ -0,0 +1,43 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_os os;
+ enum libsyscalls_arch arch;
+ const struct libsyscalls_named_number *errors;
+ size_t i, nerrors;
+ enum libsyscalls_error err;
+
+ (void) argc;
+
+ os = (enum libsyscalls_os)atoi(argv[1]);
+ arch = (enum libsyscalls_arch)atoi(argv[2]);
+
+ libsyscalls_get_syscall_errors(os, arch, &errors, &nerrors);
+ if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
+ printf("x\n");
+ return 0;
+ } else if (err == LIBSYSCALLS_E_NOERRORS) {
+ return 0;
+ } else if (err) {
+ fprintf(stderr, "test-get-syscall-errors %s %s: ", argv[3], argv[4]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ for (i = 0; i < nerrors; i++)
+ printf("%lli %llu %s\n", errors[i].number.s, errors[i].number.u, errors[i].name);
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/get-syscall-range.c b/testutil/get-syscall-range.c
new file mode 100644
index 0000000..9f26b8e
--- /dev/null
+++ b/testutil/get-syscall-range.c
@@ -0,0 +1,41 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_os os;
+ enum libsyscalls_arch arch;
+ long long int min, max;
+ enum libsyscalls_error err;
+
+ (void) argc;
+
+ os = (enum libsyscalls_os)atoi(argv[1]);
+ arch = (enum libsyscalls_arch)atoi(argv[2]);
+
+ err = libsyscalls_get_syscall_range(os, arch, &min, &max);
+ if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
+ printf("min: x\n");
+ printf("max: x\n");
+ return 0;
+ } else if (err) {
+ fprintf(stderr, "test-get-syscall-range %s %s: ", argv[3], argv[4]);
+ libsyscalls_perror(NULL, err);
+ return 1;
+ }
+
+ printf("min: %lli\n", min);
+ printf("max: %lli\n", max);
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/is-datatype-struct.c b/testutil/is-datatype-struct.c
new file mode 100644
index 0000000..f1c7675
--- /dev/null
+++ b/testutil/is-datatype-struct.c
@@ -0,0 +1,29 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_os os = (enum libsyscalls_os)atoi(argv[1]);
+ enum libsyscalls_arch arch = (enum libsyscalls_arch)atoi(argv[2]);
+ enum libsyscalls_datatype type = (enum libsyscalls_datatype)atoi(argv[3]);
+ struct libsyscalls_datatype_description desc;
+ enum libsyscalls_error err;
+ size_t i;
+
+ err = libsyscalls_get_datatype_description(os, arch, type, &desc);
+ if (err == LIBSYSCALLS_E_ISSTRUCT) {
+ return 0;
+ } else if (err) {
+ fprintf(stderr, "libsyscalls_get_datatype_description %s %s %s: ", argv[4], argv[5], argv[6]);
+ libsyscalls_perror(NULL, err);
+ return 2;
+ }
+ return 1;
+}
diff --git a/testutil/is-section-half.c b/testutil/is-section-half.c
new file mode 100644
index 0000000..ee6ef50
--- /dev/null
+++ b/testutil/is-section-half.c
@@ -0,0 +1,14 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_datatype_section sec;
+ (void) argc;
+ sec = (enum libsyscalls_datatype_section)atoi(argv[1]);
+ return !LIBSYSCALLS_IS_SECTION_HALF(sec);
+}
diff --git a/testutil/is-section-quarter.c b/testutil/is-section-quarter.c
new file mode 100644
index 0000000..1fe28d2
--- /dev/null
+++ b/testutil/is-section-quarter.c
@@ -0,0 +1,14 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stdlib.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ enum libsyscalls_datatype_section sec;
+ (void) argc;
+ sec = (enum libsyscalls_datatype_section)atoi(argv[1]);
+ return !LIBSYSCALLS_IS_SECTION_QUARTER(sec);
+}
diff --git a/testutil/list-errors.c b/testutil/list-errors.c
new file mode 100644
index 0000000..5738b06
--- /dev/null
+++ b/testutil/list-errors.c
@@ -0,0 +1,21 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+int
+main(void)
+{
+#define X(N, S)\
+ printf("%li %s %s\n", (long int)N, #N, S)
+ LIBSYSCALLS_LIST_ERRORS(X, ;);
+#undef X
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/perror-all.c b/testutil/perror-all.c
new file mode 100644
index 0000000..2b37cff
--- /dev/null
+++ b/testutil/perror-all.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ size_t i, count;
+
+ (void) argc;
+
+#define X(...) 1
+ count = (LIBSYSCALLS_LIST_ERRORS(X, +));
+#undef X
+
+ for (i = 0; i < count; i++)
+ libsyscalls_perror(argv[1], (enum libsyscalls_error)i);
+
+ return fflush(stderr) || fclose(stderr);
+}
diff --git a/testutil/perror-bad.c b/testutil/perror-bad.c
new file mode 100644
index 0000000..55d36d3
--- /dev/null
+++ b/testutil/perror-bad.c
@@ -0,0 +1,23 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+int
+main(int argc, char *argv[])
+{
+ size_t count;
+
+ (void) argc;
+
+#define X(...) 1
+ count = (LIBSYSCALLS_LIST_ERRORS(X, +));
+#undef X
+
+ libsyscalls_perror(argv[1], (enum libsyscalls_error)-1);
+ libsyscalls_perror(argv[1], (enum libsyscalls_error)count);
+
+ return fflush(stderr) || fclose(stderr);
+}
diff --git a/testutil/strerror-all.c b/testutil/strerror-all.c
new file mode 100644
index 0000000..b875392
--- /dev/null
+++ b/testutil/strerror-all.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+int
+main(void)
+{
+ size_t i, count;
+
+#define X(...) 1
+ count = (LIBSYSCALLS_LIST_ERRORS(X, +));
+#undef X
+
+ for (i = 0; i < count; i++)
+ printf("%s\n", libsyscalls_strerror((enum libsyscalls_error)i));
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/testutil/strerror-bad.c b/testutil/strerror-bad.c
new file mode 100644
index 0000000..23d8836
--- /dev/null
+++ b/testutil/strerror-bad.c
@@ -0,0 +1,25 @@
+/* See LICENSE file for copyright and license details. */
+#include "../libsyscalls.h"
+
+#include <stddef.h>
+#include <stdio.h>
+
+
+int
+main(void)
+{
+ size_t count;
+
+#define X(...) 1
+ count = (LIBSYSCALLS_LIST_ERRORS(X, +));
+#undef X
+
+ printf("%s\n", libsyscalls_strerror((enum libsyscalls_error)-1));
+ printf("%s\n", libsyscalls_strerror((enum libsyscalls_error)count));
+
+ if (fflush(stdout) || fclose(stdout)) {
+ perror(NULL);
+ return 1;
+ }
+ return 0;
+}
diff --git a/util/getdefs b/util/getdefs
index 869dff6..43c0d0d 100755
--- a/util/getdefs
+++ b/util/getdefs
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/getenum b/util/getenum
index 84cb73e..343ce76 100755
--- a/util/getenum
+++ b/util/getenum
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/make-enum b/util/make-enum
index 7b63e3c..962baba 100755
--- a/util/make-enum
+++ b/util/make-enum
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/make-mask b/util/make-mask
index 1285f52..81e57a5 100755
--- a/util/make-mask
+++ b/util/make-mask
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/make-multiextractor b/util/make-multiextractor
index 487162e..18285de 100755
--- a/util/make-multiextractor
+++ b/util/make-multiextractor
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/make-sym-extractor b/util/make-sym-extractor
index 7fec6b8..6dfcfad 100755
--- a/util/make-sym-extractor
+++ b/util/make-sym-extractor
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
set -e
diff --git a/util/what-architecture-am-i-using b/util/what-architecture-am-i-using
index e64d255..80841ff 100755
--- a/util/what-architecture-am-i-using
+++ b/util/what-architecture-am-i-using
@@ -1,4 +1,5 @@
#!/bin/sh
+# See LICENSE file for copyright and license details.
dir="$(dirname -- "$0")"