summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-12-05 20:10:48 +0100
committerMattias Andrée <maandree@kth.se>2023-12-05 20:10:48 +0100
commit6d77b155bcd4725e09837604e6ea86f5f124ba9c (patch)
tree7cfdf466bb94bbbe3e7929432bc048da5eaa2349
parentSecond commit (diff)
downloadlibsyscalls-6d77b155bcd4725e09837604e6ea86f5f124ba9c.tar.gz
libsyscalls-6d77b155bcd4725e09837604e6ea86f5f124ba9c.tar.bz2
libsyscalls-6d77b155bcd4725e09837604e6ea86f5f124ba9c.tar.xz
Third commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--Makefile3
-rw-r--r--TODO2
-rw-r--r--common.h1
-rw-r--r--devtools/.gitignore2
-rw-r--r--devtools/clean-c.c92
-rw-r--r--devtools/list-c-types.c160
-rw-r--r--libsyscalls.h25
-rw-r--r--libsyscalls_get_datatype_description.c69
-rw-r--r--libsyscalls_get_syscall_display_info.c38
-rw-r--r--libsyscalls_get_syscall_errors.c2
-rw-r--r--linux/errors.c4
-rw-r--r--linux/signals.c4
-rw-r--r--linux/symbols.c36
-rw-r--r--linux/syscall-table.c11
-rw-r--r--linux/tests/os-dependent-arrays17
-rw-r--r--linux/tests/os-dependent-primitives23
-rw-r--r--linux/types.c1
-rwxr-xr-xtest561
-rw-r--r--tests/archinfo22
-rw-r--r--tests/array-types33
-rw-r--r--tests/enums24
-rw-r--r--tests/errors59
-rw-r--r--tests/fixed-array-types33
-rw-r--r--tests/fundamental-primitives161
-rw-r--r--tests/is-struct20
-rw-r--r--tests/load-archinfo41
-rw-r--r--tests/load-functions60
-rw-r--r--tests/load-types4
-rw-r--r--tests/os-dependent-arrays9
-rw-r--r--tests/os-dependent-primitives15
-rw-r--r--tests/signals43
-rw-r--r--tests/split-register-classes22
-rw-r--r--tests/split-register-types70
-rw-r--r--tests/syscall-errors46
-rw-r--r--tests/syscall-ranges38
-rw-r--r--tests/test-self-check47
-rw-r--r--testutil/get-datatype-description.c30
-rw-r--r--testutil/get-error.c11
-rw-r--r--testutil/get-section-fraction.c17
-rw-r--r--testutil/get-signals.c20
-rw-r--r--testutil/get-syscall-errors.c20
-rw-r--r--testutil/get-syscall-range.c20
-rw-r--r--testutil/is-datatype-struct.c23
-rw-r--r--testutil/is-section-half.c20
-rw-r--r--testutil/is-section-quarter.c20
-rw-r--r--testutil/list-errors.c9
-rw-r--r--testutil/perror-all.c11
-rw-r--r--testutil/perror-bad.c11
-rw-r--r--testutil/strerror-all.c9
-rw-r--r--testutil/strerror-bad.c9
50 files changed, 1384 insertions, 644 deletions
diff --git a/Makefile b/Makefile
index 01e23e2..996315d 100644
--- a/Makefile
+++ b/Makefile
@@ -143,6 +143,9 @@ libsyscalls.$(LIBEXT): $(LOBJ)
check: $(TESTUTILS)
env CPP="$(CPP)" $(TEST_ENV) ./test
+ @if grep '^alias t=:' < ./test >/dev/null; then \
+ printf '\033[1;33m%s\033[m\n' 'Warning! tests have been disabled' >&2; \
+ fi
install: libsyscalls.a libsyscalls.$(LIBEXT)
diff --git a/TODO b/TODO
index 1571c00..c140623 100644
--- a/TODO
+++ b/TODO
@@ -1,4 +1,4 @@
-Add support for describing structs and unions
+Add support for describing structs and unions (and arrays thereof)
Add calling convention
Add value decoding
Add value encoding
diff --git a/common.h b/common.h
index f2ac824..b9b7174 100644
--- a/common.h
+++ b/common.h
@@ -17,6 +17,7 @@
#define MISALIGNMENT(ADDR, ALIGN) (((ADDR) - ((ADDR) % (uintptr_t)(ALIGN))) % (uintptr_t)(ALIGN))
#define ALIGN_BUF(BUF, ALIGN) (&(BUF)[(size_t)MISALIGNMENT((uintptr_t)(char *)(BUF), (ALIGN))])
+#define ELEMSOF(ARR) (sizeof(ARR) / sizeof *(ARR))
struct libsyscalls_symbol_printer_data {
diff --git a/devtools/.gitignore b/devtools/.gitignore
new file mode 100644
index 0000000..e2d9408
--- /dev/null
+++ b/devtools/.gitignore
@@ -0,0 +1,2 @@
+/clean-c
+/list-c-types
diff --git a/devtools/clean-c.c b/devtools/clean-c.c
new file mode 100644
index 0000000..2f56087
--- /dev/null
+++ b/devtools/clean-c.c
@@ -0,0 +1,92 @@
+/* See LICENSE file for copyright and license details. */
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static char quote = 0;
+static char comment = 0;
+
+static size_t
+clean(char *text, size_t len)
+{
+ char *w = text;
+ size_t off;
+
+ for (off = 0; off < len; off++) {
+ if (comment == '/') {
+ if (text[off] == '\n')
+ comment = 0;
+ } else if (comment == '*') {
+ if (text[off] == '*' && off + 1 < len && text[off + 1] == '/') {
+ comment = 0;
+ off += 1;
+ }
+ } else {
+ *w++ = text[off];
+ switch (text[off]) {
+ case '\"':
+ case '\'':
+ quote = quote == text[off] ? 0 : text[off];
+ break;
+
+ case '\\':
+ if (off + 1 < len) {
+ off++;
+ w -= !!quote;
+ *w++ = text[off] == '\n' ? ' ' : text[off];
+ }
+ break;
+
+ case '/':
+ if (off + 1 < len) {
+ if (text[off + 1] == '*' || text[off + 1] == '/') {
+ comment = text[off++ + 1];
+ w[-1] = ' ';
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ return (size_t)(w - text);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf[8 << 10];
+ size_t size, off;
+ ssize_t r;
+
+ (void) argc;
+
+ for (;;) {
+ r = read(STDIN_FILENO, buf, sizeof(buf));
+ if (r <= 0) {
+ if (!r)
+ break;
+ if (errno == EINTR)
+ continue;
+ perror(argv[0]);
+ return 1;
+ }
+ size = clean(buf, (size_t)r);
+ for (off = 0; off < size; off += (size_t)r) {
+ r = write(STDOUT_FILENO, &buf[off], size - off);
+ if (r <= 0) {
+ if (errno == EINTR)
+ continue;
+ perror(argv[0]);
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/devtools/list-c-types.c b/devtools/list-c-types.c
new file mode 100644
index 0000000..ec37a53
--- /dev/null
+++ b/devtools/list-c-types.c
@@ -0,0 +1,160 @@
+/* See LICENSE file for copyright and license details. */
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+
+static char quote = 0;
+static int in_name = 0;
+static size_t typedef_keyword = 0;
+static size_t struct_keyword = 0;
+static size_t union_keyword = 0;
+static size_t enum_keyword = 0;
+static int printing = 0;
+static size_t levels = 0;
+static size_t brackets = 0;
+
+static size_t
+extract(char *text, size_t len, int *outputln)
+{
+ const char *keyword;
+ char *w = text, c;
+ size_t off;
+
+ *outputln = 0;
+
+ for (off = 0; off < len; off++) {
+ if (!text[off])
+ text[off] = ' ';
+
+ if (printing) {
+ *w++ = text[off];
+ levels += text[off] == '{';
+ levels -= text[off] == '}';
+ if (!levels && text[off] == ';') {
+ if ((size_t)(w - text) == len)
+ *outputln = 1;
+ else
+ *w++ = '\n';
+ printing = 0;
+ }
+ continue;
+ }
+
+ switch (text[off]) {
+ case '\"':
+ case '\'':
+ in_name = 0;
+ quote = quote == text[off] ? 0 : text[off];
+ break;
+
+ case '\\':
+ off++;
+ break;
+
+ default:
+ if (quote)
+ break;
+
+ brackets += text[off] == '(' || text[off] == '[' || text[off] == '{';
+ brackets -= text[off] == ')' || text[off] == ']' || text[off] == '}';
+ if (brackets)
+ break;
+
+ if (!"typedef"[typedef_keyword]) {
+ keyword = "typedef";
+ goto found_keyword;
+ } else if (!"struct"[struct_keyword]) {
+ keyword = "struct";
+ goto found_keyword;
+ } else if (!"union"[union_keyword]) {
+ keyword = "union";
+ goto found_keyword;
+ } else if (!"enum"[enum_keyword]) {
+ keyword = "enum";
+ goto found_keyword;
+ } else if (!in_name) {
+ if (text[off] != "typedef"[typedef_keyword++])
+ typedef_keyword = 0;
+ if (text[off] != "struct"[struct_keyword++])
+ struct_keyword = 0;
+ if (text[off] != "union"[union_keyword++])
+ union_keyword = 0;
+ if (text[off] != "enum"[enum_keyword++])
+ enum_keyword = 0;
+ if (typedef_keyword || struct_keyword || union_keyword || enum_keyword)
+ break;
+ }
+
+ if (isalnum(text[off]) || text[off] == '_')
+ in_name = 1;
+ else
+ goto not_alnum;
+
+ break;
+ found_keyword:
+ if (isalnum(text[off]) || text[off] == '_') {
+ in_name = 1;
+ goto reset_keyword;
+ }
+ c = text[off];
+ w = stpcpy(w, keyword);
+ *w++ = c;
+ printing = 1;
+ not_alnum:
+ in_name = 0;
+ reset_keyword:
+ typedef_keyword = 0;
+ struct_keyword = 0;
+ union_keyword = 0;
+ enum_keyword = 0;
+ break;
+ }
+ }
+
+ return (size_t)(w - text);
+}
+
+int
+main(int argc, char *argv[])
+{
+ char buf[8 << 10];
+ size_t size, off;
+ ssize_t r;
+ int outputln = 0;
+
+ (void) argc;
+
+ for (;;) {
+ r = read(STDIN_FILENO, buf, sizeof(buf));
+ if (r <= 0) {
+ if (!r)
+ break;
+ if (errno == EINTR)
+ continue;
+ perror(argv[0]);
+ return 1;
+ }
+ size = extract(buf, (size_t)r, &outputln);
+ write_again:
+ for (off = 0; off < size; off += (size_t)r) {
+ r = write(STDOUT_FILENO, &buf[off], size - off);
+ if (r <= 0) {
+ if (errno == EINTR)
+ continue;
+ perror(argv[0]);
+ return 1;
+ }
+ }
+ if (outputln) {
+ outputln = 0;
+ buf[0] = '\n';
+ size = 1;
+ goto write_again;
+ }
+ }
+
+ return 0;
+}
diff --git a/libsyscalls.h b/libsyscalls.h
index 4c904b7..066de20 100644
--- a/libsyscalls.h
+++ b/libsyscalls.h
@@ -1129,8 +1129,9 @@ struct libsyscalls_datatype_description {
enum libsyscalls_datatype_section section;
/**
- * This is a ~0 terminated array describing the order
- * of the bytes the the data type
+ * This is a ~0 terminated array — but, it can also
+ * be terminated by the end of the array — describing
+ * the order of the bytes the the data type
*
* The lowest non-zero values contains the width of
* a byte (in bytes), however no such value exists
@@ -1146,8 +1147,17 @@ struct libsyscalls_datatype_description {
* 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
+ * To avoid problems checking for ~0, use the
+ * LIBSYSCALLS_IS_BYTEORDER_END macro; please also be
+ * aware that both the type and length can change in
+ * the future: do not assume it's `unsigned char`,
+ * and do not assume it has 32 elements, do not only
+ * `LIBSYSCALLS_IS_BYTEORDER_END` to detect ~0, but
+ * also check that no more than
+ * `sizeof(x.byteorder) / sizeof(*x.byteorder)`
+ * elements are read (where x is the instance of the
+ * structure) (you should definitely have your own
+ * macro for that one)
*/
unsigned char byteorder[32];
@@ -1160,8 +1170,13 @@ struct libsyscalls_datatype_description {
* @param SHIFT The value to test `struct libsyscalls_datatype_description.byteorder`
* @return :int Whether the value is ~0
*/
-#define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
+#ifdef UINTMAX_C
+# define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
+ (!~((SHIFT) | ~LIBSYSCALLS_FIELD_MASK_(UINTMAX_C(1), struct libsyscalls_datatype_description, byteorder[0])))
+#else
+# define LIBSYSCALLS_IS_BYTEORDER_END(SHIFT)\
(!~((SHIFT) | ~LIBSYSCALLS_FIELD_MASK_(1ULL, struct libsyscalls_datatype_description, byteorder[0])))
+#endif
};
diff --git a/libsyscalls_get_datatype_description.c b/libsyscalls_get_datatype_description.c
index d790531..8d46812 100644
--- a/libsyscalls_get_datatype_description.c
+++ b/libsyscalls_get_datatype_description.c
@@ -26,9 +26,9 @@ enum endian {
X(LIBSYSCALLS_ARCH_M68K, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
/*
X(LIBSYSCALLS_ARCH_MICROBLAZE, 8, TODO, TODO, TODO, TODO) D\
- X(LIBSYSCALLS_ARCH_MIPS_O32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D /* mips32 * /\
- X(LIBSYSCALLS_ARCH_MIPS_N32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D /* mips64, 32-bit convention * /\
- X(LIBSYSCALLS_ARCH_MIPS_N64, 8, 64, 64, TODO(bi), TWOS_COMPLEMENT) D /* mips64 * /\
+ X(LIBSYSCALLS_ARCH_MIPS_O32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D / * mips32 * /\
+ X(LIBSYSCALLS_ARCH_MIPS_N32, 8, 32, 32, TODO(bi), TWOS_COMPLEMENT) D / * mips64, 32-bit convention * /\
+ X(LIBSYSCALLS_ARCH_MIPS_N64, 8, 64, 64, TODO(bi), TWOS_COMPLEMENT) D / * mips64 * /\
*/\
X(LIBSYSCALLS_ARCH_PARISC_32, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
X(LIBSYSCALLS_ARCH_PARISC_64, 8, 64, 64, Big, TWOS_COMPLEMENT) D\
@@ -39,7 +39,7 @@ enum endian {
X(LIBSYSCALLS_ARCH_POWERPC_SPU, 8, 64, 64, TODO(bi), TODO) D\
X(LIBSYSCALLS_ARCH_S390_32, 8, 32, 32, Big, TODO) D\
X(LIBSYSCALLS_ARCH_S390_64, 8, 64, 64, Big, TODO) D\
- X(LIBSYSCALLS_ARCH_SH, 8, 32, 32, TODO(bi), TODO) D /* not sh-5 * /\
+ X(LIBSYSCALLS_ARCH_SH, 8, 32, 32, TODO(bi), TODO) D / * not sh-5 * /\
*/\
X(LIBSYSCALLS_ARCH_SPARC_32, 8, 32, 32, Big, TWOS_COMPLEMENT) D\
/*
@@ -69,7 +69,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
if (!description_out)
description_out = &description_discard;
- if (datatype & ~(LIBSYSCALLS_TYPEBITSMASK | (LIBSYSCALLS_TYPEBITSMASK - 1)))
+ if ((unsigned)datatype & ~(LIBSYSCALLS_TYPEBITSMASK | (LIBSYSCALLS_TYPEBITSMASK - 1U)))
return LIBSYSCALLS_E_INVAL;
datatype ^= class = datatype & LIBSYSCALLS_TYPEBITSMASK;
@@ -111,7 +111,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
if (datatype >= LIBSYSCALLS_TYPEOFFSET_STRUCTS_AND_UNIONS)
return LIBSYSCALLS_E_ISSTRUCT;
- memset(description_out->byteorder, ~0U, sizeof(description_out->byteorder));
+ memset(description_out->byteorder, ~0, sizeof(description_out->byteorder));
#define CASE(ARCH, CHARBITS, INTPTR_BITS, SIZE_BITS, ENDIAN, SIGN)\
case ARCH: description_out->sign_representation = LIBSYSCALLS_SIGN_##SIGN; break
@@ -132,13 +132,14 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
break;
case LIBSYSCALLS_SIGN_TWOS_COMPLEMENT:
case LIBSYSCALLS_SIGN_EXCESS_HALF:
+ case LIBSYSCALLS_SIGN_UNDETERMINED:
break;
}
if (datatype >= LIBSYSCALLS_TYPEOFFSET_FIXED_ARRAYS) {
if (class != LIBSYSCALLS_TYPEBITS_SCALAR)
return LIBSYSCALLS_E_INVAL;
- switch (datatype) {
+ switch ((int)datatype) {
case LIBSYSCALLS_TYPE_2_INTS:
datatype = LIBSYSCALLS_TYPE_INT;
description_out->array_size = 2;
@@ -160,7 +161,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
goto unannotated;
} else if (datatype >= LIBSYSCALLS_TYPEOFFSET_ANNOTATED_NUMERICALS) {
- switch (datatype) {
+ switch ((int)datatype) {
case LIBSYSCALLS_TYPE_INT_SIGNAL:
datatype = LIBSYSCALLS_TYPE_INT;
description_out->annotation = LIBSYSCALLS_ANNOTATION_SIGNAL;
@@ -197,7 +198,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
} else {
description_out->is_unsigned = (datatype - LIBSYSCALLS_TYPE_SCHAR) & 1;
description_out->is_signed = 1 ^ description_out->is_unsigned;
- datatype &= ~1;
+ datatype -= description_out->is_unsigned;
}
goto arch_or_os_dependent;
@@ -210,10 +211,10 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
goto unannotated;
} else if (datatype >= LIBSYSCALLS_TYPEOFFSET_SPLIT_PRIMITIVES) {
+ enum libsyscalls_datatype t = datatype;
if (class != LIBSYSCALLS_TYPEBITS_SCALAR)
return LIBSYSCALLS_E_INVAL;
- enum libsyscalls_datatype t = datatype;
- switch (datatype) {
+ switch ((int)datatype) {
case LIBSYSCALLS_TYPE_UINT64_HIGH_32:
case LIBSYSCALLS_TYPE_UINT64_LOW_32:
case LIBSYSCALLS_TYPE_UINT64_FRONT_32:
@@ -233,7 +234,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
default:
return LIBSYSCALLS_E_INVAL;
}
- switch (t) {
+ switch ((int)t) {
case LIBSYSCALLS_TYPE_UINT64_HIGH_32:
description_out->section = LIBSYSCALLS_SECTION_UPPER_HALF;
break;
@@ -255,7 +256,7 @@ libsyscalls_get_datatype_description(enum libsyscalls_os os, enum libsyscalls_ar
} else {
if (class)
return LIBSYSCALLS_E_INVAL;
- switch (datatype) {
+ switch ((int)datatype) {
case LIBSYSCALLS_TYPE_UNKNOWN:
case LIBSYSCALLS_TYPE_DYNAMIC:
datatype = LIBSYSCALLS_TYPE_DYNAMIC;
@@ -280,7 +281,7 @@ arch_or_os_dependent:
divide_array_size_with_type_size_out = 0;
arch_dependent:
- switch (datatype) {
+ switch ((int)datatype) {
/* Note that LIBSYSCALLS_TYPE_INTN does not have the same semantics
* as POSIX's intN_t: these are not necessarily two's complement
* encoded and can have any range of valid numbers as long as that
@@ -338,7 +339,7 @@ os_dependent:
return r;
#undef CASE
- switch (datatype) {
+ switch ((int)datatype) {
case LIBSYSCALLS_TYPE_INT8:
case LIBSYSCALLS_TYPE_INT16:
case LIBSYSCALLS_TYPE_INT32:
@@ -367,9 +368,20 @@ not_os_dependent:
if (description_out->width_in_bits % charbits)
return LIBSYSCALLS_E_NOSUCHTYPE;
- if (description_out->width_in_bits > (size_t)UCHAR_MAX * sizeof(*description_out->byteorder) ||
- description_out->width_in_bits > sizeof(description_out->byteorder) / sizeof(*description_out->byteorder) * charbits)
+ if (description_out->width_in_bits > (size_t)1 << LIBSYSCALLS_BITSIZEOF_(*description_out->byteorder) ||
+ description_out->width_in_bits > ELEMSOF(description_out->byteorder) * charbits) {
abort();
+ }
+
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wimplicit-int-conversion" /* we don't want to hardcode the type here */
+#elif defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wconversion"
+#endif
switch (endian) {
case Big:
@@ -384,24 +396,35 @@ not_os_dependent:
abort();
}
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#elif defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+
if (half) {
unsigned long long int bytemask, coverage = 0;
unsigned long long int remmask;
- unsigned char bytebits;
+ unsigned char bytebits = UCHAR_MAX;
- for (i = 0; larger_type.byteorder[i]; i++)
- if (LIBSYSCALLS_IS_BYTEORDER_END(larger_type.byteorder[i]))
- abort();
- bytebits = larger_type.byteorder[i];
+ for (i = 0; !LIBSYSCALLS_IS_BYTEORDER_END(larger_type.byteorder[i]); i++)
+ if (larger_type.byteorder[i] && larger_type.byteorder[i] < bytebits)
+ bytebits = larger_type.byteorder[i];
bytemask = (1ULL << bytebits) - 1ULL;
remmask = 0xFFFFFFFFULL; /* we known from the code above that we are working with 32-bit sections */
- for (i = 0; larger_type.byteorder[i]; i++) {
+ for (i = 0; !LIBSYSCALLS_IS_BYTEORDER_END(larger_type.byteorder[i]); i++) {
coverage |= (remmask & bytemask) << larger_type.byteorder[i];
remmask >>= bytebits;
}
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
/* we known from the code above that we are working with split 64-bit integers */
+ if (half == +1)
+ coverage ^= 0xFFFFFFFFFFFFFFFFull;
if (coverage == 0xFFFFFFFF00000000ull) description_out->section = LIBSYSCALLS_SECTION_UPPER_HALF;
else if (coverage == 0x00000000FFFFFFFFull) description_out->section = LIBSYSCALLS_SECTION_LOWER_HALF;
else if (coverage == 0x0000FFFFFFFF0000ull) description_out->section = LIBSYSCALLS_SECTION_INNER_HALF;
diff --git a/libsyscalls_get_syscall_display_info.c b/libsyscalls_get_syscall_display_info.c
index 4d59f5c..f9bbf1a 100644
--- a/libsyscalls_get_syscall_display_info.c
+++ b/libsyscalls_get_syscall_display_info.c
@@ -5,13 +5,17 @@
#include <stdlib.h>
#include <string.h>
+#if defined(__GNUC__)
+# pragma GCC diagnostic ignored "-Winline"
+#endif
+
#define LOWEST_BIT(X) ((X) & ~((X) - 1))
#define POST_HIGHEST_OF_CONSECUTIVELY_BITS(X) ((X) + LOWEST_BIT(X))
static inline signed char
-trailing_zeroes(unsigned long long int x) {
+trailing_zeroes(unsigned long long int x) { /* TODO use builtin function if available */
int r = 0;
if (x == 0)
return -1;
@@ -53,11 +57,18 @@ extract_signal(enum libsyscalls_os os, enum libsyscalls_arch arch,
if (!found)
return NULL;
+ (void)fallback_out;
+
*valuep = 0;
return found->name;
}
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
+#endif
+
static struct libsyscalls_syscall_display_info *
build_syscall_display_info(void *data, size_t data_size, size_t data_align,
libsyscalls_symbol_printer_function **funcs,
@@ -74,14 +85,14 @@ build_syscall_display_info(void *data, size_t data_size, size_t data_align,
size += 1;
}
dataoff = size;
- size += nsyms * data_size;
+ size += (size_t)nsyms * data_size;
- if (size & (alignof(*ret->params) - 1)) {
- size |= alignof(*ret->params) - 1;
+ if (size & (alignof(struct libsyscalls_syscall_type_info) - 1)) {
+ size |= alignof(struct libsyscalls_syscall_type_info) - 1;
size += 1;
}
paramoff = size;
- size += (nargs + 1) * sizeof(*ret->params);
+ size += (size_t)(nargs + 1) * sizeof(*ret->params);
ret = calloc(1, size);
if (!ret)
@@ -96,8 +107,8 @@ build_syscall_display_info(void *data, size_t data_size, size_t data_align,
ret->params[i].type = syscall->parameters_types[i];
if (funcs[i]) {
ret->params[i].function = funcs[i];
- ret->params[i].data = (void *)&((char *)ret)[dataoff + nsyms * data_size];
- memcpy(ret->params[i].data, &((char *)data)[i * data_size], data_size);
+ ret->params[i].data = (void *)&((char *)ret)[dataoff + (size_t)nsyms * data_size];
+ memcpy(ret->params[i].data, &((char *)data)[(size_t)i * data_size], data_size);
nsyms++;
}
}
@@ -105,17 +116,26 @@ build_syscall_display_info(void *data, size_t data_size, size_t data_align,
ret->retvalue->expect_zero = syscall->expect_zero;
if (funcs[i]) {
ret->retvalue->function = funcs[i];
- ret->retvalue->data = (void *)&((char *)ret)[dataoff + nsyms * data_size];
- memcpy(ret->retvalue->data, &((char *)data)[i * data_size], data_size);
+ ret->retvalue->data = (void *)&((char *)ret)[dataoff + (size_t)nsyms * data_size];
+ memcpy(ret->retvalue->data, &((char *)data)[(size_t)i * data_size], data_size);
}
return ret;
}
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
#include "generated/symbols.c"
+
+#if defined(__GNUC__) && !defined(__clang__)
+# pragma GCC diagnostic ignored "-Wnonnull-compare" /* Why should I trust that the user is using the same compiler? */
+#endif
+
enum libsyscalls_error
libsyscalls_get_syscall_display_info(enum libsyscalls_os os, enum libsyscalls_arch arch,
const struct libsyscalls_syscall_abi *syscall,
diff --git a/libsyscalls_get_syscall_errors.c b/libsyscalls_get_syscall_errors.c
index 14b1e05..1af1589 100644
--- a/libsyscalls_get_syscall_errors.c
+++ b/libsyscalls_get_syscall_errors.c
@@ -28,5 +28,5 @@ libsyscalls_get_syscall_errors(enum libsyscalls_os os, enum libsyscalls_arch arc
return LIBSYSCALLS_E_OSNOSUP;
}
-#undef CASE
+#undef CASE
}
diff --git a/linux/errors.c b/linux/errors.c
index d8a0e7f..94c3cd2 100644
--- a/linux/errors.c
+++ b/linux/errors.c
@@ -10,7 +10,7 @@ get_linux_syscall_errors(enum libsyscalls_arch arch, const struct libsyscalls_na
{
#define CASE(ARCH)\
*errs_out = linux_errors_for_##ARCH;\
- *nerrs_out = sizeof(linux_errors_for_##ARCH) / sizeof(*linux_errors_for_##ARCH);\
+ *nerrs_out = ELEMSOF(linux_errors_for_##ARCH);\
goto out
switch ((int)arch) {
@@ -121,7 +121,7 @@ get_linux_syscall_errors(enum libsyscalls_arch arch, const struct libsyscalls_na
}
*errs_out = linux_errors_for_generic;
- *nerrs_out = sizeof(linux_errors_for_generic) / sizeof(*linux_errors_for_generic);
+ *nerrs_out = ELEMSOF(linux_errors_for_generic);
out:
return LIBSYSCALLS_E_OK;
diff --git a/linux/signals.c b/linux/signals.c
index 7d7f868..743fc89 100644
--- a/linux/signals.c
+++ b/linux/signals.c
@@ -10,7 +10,7 @@ get_linux_signals(enum libsyscalls_arch arch, const struct libsyscalls_named_num
{
#define CASE(ARCH)\
*sigs_out = linux_signals_for_##ARCH;\
- *nsigs_out = sizeof(linux_signals_for_##ARCH) / sizeof(*linux_signals_for_##ARCH);\
+ *nsigs_out = ELEMSOF(linux_signals_for_##ARCH);\
goto out
switch ((int)arch) {
@@ -121,7 +121,7 @@ get_linux_signals(enum libsyscalls_arch arch, const struct libsyscalls_named_num
}
*sigs_out = linux_signals_for_generic;
- *nsigs_out = sizeof(linux_signals_for_generic) / sizeof(*linux_signals_for_generic);
+ *nsigs_out = ELEMSOF(linux_signals_for_generic);
out:
return LIBSYSCALLS_E_OK;
diff --git a/linux/symbols.c b/linux/symbols.c
index cbc61f5..7a3c8e5 100644
--- a/linux/symbols.c
+++ b/linux/symbols.c
@@ -32,6 +32,11 @@ extract_linux_symbol_signal(struct libsyscalls_symbol_printer_data *data, unsign
}
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
+#endif
+
static const char *
extract_linux_symbol_mode(struct libsyscalls_symbol_printer_data *data, unsigned long long int *valuep, char *fallback_out)
{
@@ -128,6 +133,10 @@ extract_linux_symbol_umask(struct libsyscalls_symbol_printer_data *data, unsigne
return data->buf;
}
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
static const char *
extract_linux_symbol_dev(struct libsyscalls_symbol_printer_data *data, unsigned long long int *valuep, char *fallback_out)
@@ -162,7 +171,7 @@ extract_linux_symbol_dev(struct libsyscalls_symbol_printer_data *data, unsigned
static const char *
extract_linux_symbol_clockid_t(struct libsyscalls_symbol_printer_data *data, unsigned long long int *valuep, char *fallback_out)
{
- if (*valuep >= 0)
+ if ((long long int)*valuep >= 0)
return NULL;
else if ((*valuep & 7) == 2)
sprintf(data->buf, "%lli (pid: %llu)", (long long int)*valuep, ~*valuep / 8);
@@ -171,7 +180,8 @@ extract_linux_symbol_clockid_t(struct libsyscalls_symbol_printer_data *data, uns
else if ((*valuep & 7) == 6)
sprintf(data->buf, "%lli (tid: %llu)", (long long int)*valuep, ~*valuep / 8);
else
- sprintf(data->buf, "%lli (~%llu*8 + %u)", (long long int)*valuep, ~*valuep / 8, *valuep & 7);
+ sprintf(data->buf, "%lli (~%llu*8 + %llu)", (long long int)*valuep, ~*valuep / 8, *valuep & 7);
+ (void) fallback_out;
*valuep = 0;
return data->buf;
}
@@ -269,6 +279,11 @@ have_fun:
}
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage"
+#endif
+
static struct libsyscalls_syscall_display_info *
get_linux_syscall_display_info(enum libsyscalls_arch arch, const struct libsyscalls_syscall_abi *syscall,
long long int syscall_number, unsigned long long int *syscall_argument)
@@ -277,7 +292,7 @@ get_linux_syscall_display_info(enum libsyscalls_arch arch, const struct libsysca
libsyscalls_symbol_printer_function **funcs;
int i, nargs, nsyms;
size_t data_size = offsetof(LIBSYSCALLS_SYMBOL_PRINTER_DATA, buf);
- size_t data_align = alignof(*data);
+ size_t data_align = alignof(LIBSYSCALLS_SYMBOL_PRINTER_DATA);
size_t bufspace, bufspace1, bufspace2;
LIBSYSCALLS_SYMBOL_PRINTER first, second;
@@ -299,9 +314,18 @@ get_linux_syscall_display_info(enum libsyscalls_arch arch, const struct libsysca
}
{
- char data_vla_buf[(nargs + 1) * data_size + data_align];
+#if defined(__clang__)
+# pragma clang diagnostic push
+# pragma clang diagnostic ignored "-Wvla"
+#endif
+
+ char data_vla_buf[(size_t)(nargs + 1) * data_size + data_align];
libsyscalls_symbol_printer_function *funcs_vla[nargs + 1];
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
+
data = (void *)ALIGN_BUF(data_vla_buf, data_align);
funcs = funcs_vla;
@@ -319,3 +343,7 @@ get_linux_syscall_display_info(enum libsyscalls_arch arch, const struct libsysca
return build_syscall_display_info(data, data_size, data_align, funcs, syscall, nargs, nsyms);
}
}
+
+#if defined(__clang__)
+# pragma clang diagnostic pop
+#endif
diff --git a/linux/syscall-table.c b/linux/syscall-table.c
index 6bcd480..5a5d9c2 100644
--- a/linux/syscall-table.c
+++ b/linux/syscall-table.c
@@ -5,8 +5,19 @@
#include "../generated/linux-syscall-table.h"
#include "../generated/linux-syscalls.h"
+
+#if defined(__GNUC__)
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wunused-variable" /* unused = not available on any architecutre the library is being compiled for */
+#endif
+
#include "syscalls.h"
+#if defined(__GNUC__)
+# pragma GCC diagnostic pop
+#endif
+
+
/* generated/linux-syscall-dedup.h removes references to duplicate symbols, then compiler optimisation removes them */
#if defined(__clang__)
diff --git a/linux/tests/os-dependent-arrays b/linux/tests/os-dependent-arrays
new file mode 100644
index 0000000..3140ce4
--- /dev/null
+++ b/linux/tests/os-dependent-arrays
@@ -0,0 +1,17 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ if ! issupported $os $arch; then
+ continue
+ fi
+
+ ptype=ULONG
+ atype=FD_SET
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $ptype) $os $arch $ptype > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $atype) $os $arch $atype > $b
+ sed 's/^\(array_size\) = 1$/\1 = '"$(( 1024 / $(sed -n 's/^width_in_bits = //p' < $a) ))"/ < $a \
+ | sed 's/^\(is_unsigned\) = 1/\1 = 0/' \
+ | diff -u - $b
+done
diff --git a/linux/tests/os-dependent-primitives b/linux/tests/os-dependent-primitives
new file mode 100644
index 0000000..bc20bf3
--- /dev/null
+++ b/linux/tests/os-dependent-primitives
@@ -0,0 +1,23 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+for arch in $(getnamelist ARCH); do
+ archn=$(getnum ARCH $arch)
+ if ! issupported $os $arch; then
+ continue
+ fi
+
+ typeisas SCHAR INT8
+ typeisas SHORT INT16
+ typeisas INT INT32
+ typeisas LONG INTPTR
+ typeisas LLONG INT64
+
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" LONG) $os $arch LONG \
+ | sed 's/^\(is_unsigned\) = 0$/\1 = 1/' \
+ | sed 's/^\(sign_representation\) = .*$/\1 = '"$(getnum SIGN UNDETERMINED)"/ \
+ | sed 's/^\(annotation\) = .*$/\1 = '"$(getnum ANNOTATION UNDETERMINED)"/ \
+ | sed 's/^\(section\) = .*$/\1 = '"$(getnum SECTION UNDETERMINED)"/ > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" DYNAMIC) $os $arch DYNAMIC > $b
+ diff -u $a $b
+done
diff --git a/linux/types.c b/linux/types.c
index fee69fe..66bb276 100644
--- a/linux/types.c
+++ b/linux/types.c
@@ -50,5 +50,6 @@ get_linux_datatype_description(enum libsyscalls_arch arch, enum libsyscalls_data
/* something only defined on some other operating system */
return LIBSYSCALLS_E_NOSUCHTYPE;
}
+ (void) arch;
return LIBSYSCALLS_E_OK;
}
diff --git a/test b/test
index 803f45f..c825493 100755
--- a/test
+++ b/test
@@ -6,6 +6,7 @@ if test $# = 0; then
printf 'Testing is broken!\n' >&2
exit 2
fi
+ set +e
"$0" $$
r=$?
rm -f -- .?-$$.tmp
@@ -21,566 +22,50 @@ b=.b-$pid.tmp
PATH="$(dirname -- "$0")/testutil:$PATH"
export PATH
+. tests/load-functions
-
-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
-}
-
+alias t=.
+# this is for test development; set to : to skip tests
+# have already been written and passed, set to . otherwise
set -v
+test -n "${SUPPORTED_OSES}" # This check that the test's environment has set up, if this fails, run through `make check`
-# 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 ###
+(. tests/test-self-check;) >/dev/null 2>/dev/null
-#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
+t tests/enums
+. tests/load-types
- endian=$(getendian $arch)
+t tests/errors
- 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})
+t tests/syscall-ranges
- 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
+t tests/syscall-errors
- 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 -
+t tests/signals
- 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
+t tests/split-register-classes
- 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
+. tests/load-archinfo
+t tests/archinfo
- 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
+t tests/fundamental-primitives
- 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
+t tests/is-struct
- 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 -
+t tests/array-types
- 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
+t tests/fixed-array-types
- 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
+t tests/split-register-types
- 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
+t tests/os-dependent-primitives
-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
+t tests/os-dependent-arrays
diff --git a/tests/archinfo b/tests/archinfo
new file mode 100644
index 0000000..5034766
--- /dev/null
+++ b/tests/archinfo
@@ -0,0 +1,22 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+printf '%s\n' "$archinfo" | grep '^AMD64 8 64 64 Little TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^AMD64_X32 8 32 32 Little TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^M68K 8 32 32 Big TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^PARISC_32 8 32 32 Big TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^PARISC_64 8 64 64 Big TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^SPARC_32 8 32 32 Big TWOS_COMPLEMENT' >/dev/null
+printf '%s\n' "$archinfo" | grep '^I386 8 32 32 Little TWOS_COMPLEMENT' >/dev/null
+test $(getbytesize AMD64) = 8
+test $(getbytesize I386) = 8
+test $(getaddrsize I386) = 32
+test $(getaddrsize AMD64) = 64
+test $(getsizesize AMD64) = 64
+test $(getsizesize I386) = 32
+test $(getendian I386) = Little
+test $(getendian AMD64) = Little
+test $(getendian M68K) = Big
+test $(getsign I386) = TWOS_COMPLEMENT
+test $(getsign AMD64) = TWOS_COMPLEMENT
+test $(getsign M68K) = TWOS_COMPLEMENT
diff --git a/tests/array-types b/tests/array-types
new file mode 100644
index 0000000..5bb0429
--- /dev/null
+++ b/tests/array-types
@@ -0,0 +1,33 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+patypes="$(printf '%s\n' "$types" | cut -d ' ' -f 2 | grep -v '\(STRUCT\|UNION\)' | sed -n 's/_ARRAY$//p')"
+test -n "$patypes"
+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
+
+ for ptype in $patypes CHAR; do
+ atype="${ptype}_ARRAY"
+ if test $atype = CHAR_ARRAY; then
+ atype=BUFFER
+ fi
+ auftype="${atype}_UNKNOWN_FILL"
+
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $ptype) $os $arch $ptype \
+ | sed 's/^\(array_size\) = 1$/\1 = 0/' \
+ | sed 's/^\(fill_is_known\) = .*$/\1 = 1/' \
+ | sed 's/^\(relative_position_of_array_size\) = .*$/\1 = 1/' \
+ | sed 's/^\(absolute_position_of_array_size\) = .*$/\1 = -1/' > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $atype) $os $arch $atype > $b
+ diff -u $a $b
+
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $auftype) $os $arch $auftype > $b
+ sed 's/^\(fill_is_known\) = .*$/\1 = 0/' < $a | diff -u - $b
+ done
+ done
+done
diff --git a/tests/enums b/tests/enums
new file mode 100644
index 0000000..43afe3d
--- /dev/null
+++ b/tests/enums
@@ -0,0 +1,24 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
diff --git a/tests/errors b/tests/errors
new file mode 100644
index 0000000..f14ddfc
--- /dev/null
+++ b/tests/errors
@@ -0,0 +1,59 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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 -
diff --git a/tests/fixed-array-types b/tests/fixed-array-types
new file mode 100644
index 0000000..070920e
--- /dev/null
+++ b/tests/fixed-array-types
@@ -0,0 +1,33 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
+
+ ptype=INT
+ atype=2_INTS
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $ptype) $os $arch $ptype \
+ | sed 's/^\(array_size\) = 1$/\1 = 2/' > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $atype) $os $arch $atype > $b
+ diff -u $a $b
+
+ ptype=INT_FD
+ atype=2_INTS_FD
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $ptype) $os $arch $ptype \
+ | sed 's/^\(array_size\) = 1$/\1 = 2/' > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $atype) $os $arch $atype > $b
+ diff -u $a $b
+
+ ptype=UINT32
+ atype=2_UINT32S
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $ptype) $os $arch $ptype \
+ | sed 's/^\(array_size\) = 1$/\1 = 2/' > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $atype) $os $arch $atype > $b
+ diff -u $a $b
+ done
+done
diff --git a/tests/fundamental-primitives b/tests/fundamental-primitives
new file mode 100644
index 0000000..4068934
--- /dev/null
+++ b/tests/fundamental-primitives
@@ -0,0 +1,161 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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 # that's all we have for now
+ fi
+ sign_representation=$(getnum SIGN ${sign_representation})
+
+ for n in $intsizes; do
+ type=INT$n
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ grep "^width_in_bits = ${n}"\$ < $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
+ grep "^byteorder = $(getbyteorder $n $endian)"\$ < $a >/dev/null
+
+ type=UINT$n
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ grep "^width_in_bits = ${n}"\$ < $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 = 0"\$ < $a >/dev/null
+ grep "^is_unsigned = 1"\$ < $a >/dev/null
+ grep "^annotation = ${noannotation}"\$ < $a >/dev/null
+ grep "^section = ${whole}"\$ < $a >/dev/null
+ grep "^byteorder = $(getbyteorder $n $endian)"\$ < $a >/dev/null
+ done
+
+ type=INT$(getaddrsize $arch)
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=INTPTR
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ diff -u $a $b
+
+ type=INT$(getsizesize $arch)
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ type=SSIZE
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $b
+ diff -u $a $b
+
+ type=VOID
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type > $a
+ grep "^width_in_bits = 0"\$ < $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 = 0"\$ < $a >/dev/null
+ grep "^is_unsigned = 0"\$ < $a >/dev/null
+ grep "^annotation = ${noannotation}"\$ < $a >/dev/null
+ grep "^section = ${whole}"\$ < $a >/dev/null
+ grep "^byteorder =\s*"\$ < $a >/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
diff --git a/tests/is-struct b/tests/is-struct
new file mode 100644
index 0000000..310e615
--- /dev/null
+++ b/tests/is-struct
@@ -0,0 +1,20 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
diff --git a/tests/load-archinfo b/tests/load-archinfo
new file mode 100644
index 0000000..4c38f6b
--- /dev/null
+++ b/tests/load-archinfo
@@ -0,0 +1,41 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+#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
+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
+}
diff --git a/tests/load-functions b/tests/load-functions
new file mode 100644
index 0000000..f0c5311
--- /dev/null
+++ b/tests/load-functions
@@ -0,0 +1,60 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
+}
+
+cpp_enum_clean () {
+ $CPP < libsyscalls.h 2>/dev/null | grep -v '#' | tr '\n,{}' ' \n\n\n'
+}
diff --git a/tests/load-types b/tests/load-types
new file mode 100644
index 0000000..1113609
--- /dev/null
+++ b/tests/load-types
@@ -0,0 +1,4 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+types="$(getlist TYPE cpp_enum_clean)"
diff --git a/tests/os-dependent-arrays b/tests/os-dependent-arrays
new file mode 100644
index 0000000..13c119b
--- /dev/null
+++ b/tests/os-dependent-arrays
@@ -0,0 +1,9 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ if issupported $os; then
+ . $(printf '%s\n' $os | tr '[A-Z]' '[a-z]')/tests/os-dependent-arrays
+ fi
+done
diff --git a/tests/os-dependent-primitives b/tests/os-dependent-primitives
new file mode 100644
index 0000000..c0438af
--- /dev/null
+++ b/tests/os-dependent-primitives
@@ -0,0 +1,15 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+typeisas () {
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $1) $os $arch $1 > $a
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $2) $os $arch $2 > $b
+ diff -u $a $b
+}
+
+for os in $(getnamelist OS); do
+ osn=$(getnum OS $os)
+ if issupported $os; then
+ . $(printf '%s\n' $os | tr '[A-Z]' '[a-z]')/tests/os-dependent-primitives
+ fi
+done
diff --git a/tests/signals b/tests/signals
new file mode 100644
index 0000000..7e58621
--- /dev/null
+++ b/tests/signals
@@ -0,0 +1,43 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
diff --git a/tests/split-register-classes b/tests/split-register-classes
new file mode 100644
index 0000000..71622bb
--- /dev/null
+++ b/tests/split-register-classes
@@ -0,0 +1,22 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
diff --git a/tests/split-register-types b/tests/split-register-types
new file mode 100644
index 0000000..3b3070b
--- /dev/null
+++ b/tests/split-register-types
@@ -0,0 +1,70 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+upper_half=$(getnum SECTION UPPER_HALF)
+lower_half=$(getnum SECTION LOWER_HALF)
+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
+
+ for stype in INT64_HIGH_32 INT64_LOW_32 INT64_FRONT_32 INT64_BACK_32; do
+ utype=U$stype
+ rtype="$(printf '%s\n' "$stype" | sed 's/^\(INT\)[0-9]\+_[A-Z]\+_\([0-9]\+\)$/\1\2/')"
+ test ! "$rtype" = "$stype"
+ rtypen=$(lookupnum "$types" $rtype)
+ stypen=$(lookupnum "$types" $stype)
+ utypen=$(lookupnum "$types" $utype)
+ test -n "$rtypen"
+ test -n "$stypen"
+ test -n "$utypen"
+
+ get-datatype-description.tu $osn $archn $rtypen $os $arch $rtype \
+ | grep -v "^section = " > $a
+ get-datatype-description.tu $osn $archn $stypen $os $arch $stype \
+ | grep -v "^section = " > $b
+ diff -u $a $b
+
+ get-datatype-description.tu $osn $archn $stypen $os $arch $stype \
+ | sed -e 's/^\(is_signed =\) .$/\1 0/' -e 's/^\(is_unsigned =\) .$/\1 1/' > $a
+ get-datatype-description.tu $osn $archn $utypen $os $arch $utype > $b
+ diff -u $a $b
+ done
+
+ type=INT64_HIGH_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${upper_half}"\$ >/dev/null
+
+ type=INT64_LOW_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${lower_half}"\$ >/dev/null
+
+ endian=$(getendian $arch)
+ if test $endian = Little; then
+
+ type=INT64_FRONT_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${lower_half}"\$ >/dev/null
+
+ type=INT64_BACK_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${upper_half}"\$ >/dev/null
+
+ elif test $endian = Big; then
+
+ type=INT64_FRONT_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${upper_half}"\$ >/dev/null
+
+ type=INT64_BACK_32
+ get-datatype-description.tu $osn $archn $(lookupnum "$types" $type) $os $arch $type \
+ | grep "^section = ${lower_half}"\$ >/dev/null
+
+ else
+ false # that's all we have for now
+ fi
+ done
+done
diff --git a/tests/syscall-errors b/tests/syscall-errors
new file mode 100644
index 0000000..0d36428
--- /dev/null
+++ b/tests/syscall-errors
@@ -0,0 +1,46 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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)
diff --git a/tests/syscall-ranges b/tests/syscall-ranges
new file mode 100644
index 0000000..e42679a
--- /dev/null
+++ b/tests/syscall-ranges
@@ -0,0 +1,38 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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
diff --git a/tests/test-self-check b/tests/test-self-check
new file mode 100644
index 0000000..8e42f18
--- /dev/null
+++ b/tests/test-self-check
@@ -0,0 +1,47 @@
+# -*- sh -*-
+# See LICENSE file for copyright and license details.
+
+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' > $a
+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
diff --git a/testutil/get-datatype-description.c b/testutil/get-datatype-description.c
index 0bec618..9c26626 100644
--- a/testutil/get-datatype-description.c
+++ b/testutil/get-datatype-description.c
@@ -6,18 +6,30 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+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]);
+ int os, arch, type;
struct libsyscalls_datatype_description desc;
enum libsyscalls_error err;
size_t i;
- err = libsyscalls_get_datatype_description(os, arch, type, &desc);
+ if (argc != 7) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
+ type = atoi(argv[3]);
+
+ err = libsyscalls_get_datatype_description((enum libsyscalls_os)os, (enum libsyscalls_arch)arch,
+ (enum libsyscalls_datatype)type, &desc);
if (err) {
fprintf(stderr, "libsyscalls_get_datatype_description %s %s %s: ", argv[4], argv[5], argv[6]);
libsyscalls_perror(NULL, err);
@@ -28,10 +40,10 @@ main(int argc, char *argv[])
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("fill_is_known = %u\n", (unsigned)desc.fill_is_known);
+ printf("is_signed = %u\n", (unsigned)desc.is_signed);
+ printf("is_unsigned = %u\n", (unsigned)desc.is_unsigned);
+ printf("min_is_minus_max = %u\n", (unsigned)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);
diff --git a/testutil/get-error.c b/testutil/get-error.c
index 8f066d7..d390a60 100644
--- a/testutil/get-error.c
+++ b/testutil/get-error.c
@@ -5,12 +5,21 @@
#include <stdio.h>
#include <string.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
int i;
+ if (argc < 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
for (i = 1; i < argc; i++) {
#define X(N, S)\
if (!strcmp(argv[i], #N))\
diff --git a/testutil/get-section-fraction.c b/testutil/get-section-fraction.c
index cdb1530..2b86206 100644
--- a/testutil/get-section-fraction.c
+++ b/testutil/get-section-fraction.c
@@ -5,16 +5,23 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- enum libsyscalls_datatype_section sec;
+ int sec;
- (void) argc;
+ if (argc != 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
- sec = (enum libsyscalls_datatype_section)atoi(argv[1]);
- printf("%u\n", LIBSYSCALLS_GET_SECTION_FRACTION(sec));
+ sec = atoi(argv[1]);
+ printf("%u\n", LIBSYSCALLS_GET_SECTION_FRACTION((enum libsyscalls_datatype_section)sec));
if (fflush(stdout) || fclose(stdout)) {
perror(NULL);
diff --git a/testutil/get-signals.c b/testutil/get-signals.c
index 846a0c1..f97484f 100644
--- a/testutil/get-signals.c
+++ b/testutil/get-signals.c
@@ -5,22 +5,28 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- enum libsyscalls_os os;
- enum libsyscalls_arch arch;
+ int os, arch;
const struct libsyscalls_named_number *signals;
size_t i, nsignals;
enum libsyscalls_error err;
- (void) argc;
+ if (argc != 5) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
- os = (enum libsyscalls_os)atoi(argv[1]);
- arch = (enum libsyscalls_arch)atoi(argv[2]);
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
- libsyscalls_get_signals(os, arch, &signals, &nsignals);
+ err = libsyscalls_get_signals((enum libsyscalls_os)os, (enum libsyscalls_arch)arch, &signals, &nsignals);
if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
printf("x\n");
return 0;
diff --git a/testutil/get-syscall-errors.c b/testutil/get-syscall-errors.c
index c97e556..d1ddfd7 100644
--- a/testutil/get-syscall-errors.c
+++ b/testutil/get-syscall-errors.c
@@ -5,22 +5,28 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- enum libsyscalls_os os;
- enum libsyscalls_arch arch;
+ int os, arch;
const struct libsyscalls_named_number *errors;
size_t i, nerrors;
enum libsyscalls_error err;
- (void) argc;
+ if (argc != 5) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
- os = (enum libsyscalls_os)atoi(argv[1]);
- arch = (enum libsyscalls_arch)atoi(argv[2]);
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
- libsyscalls_get_syscall_errors(os, arch, &errors, &nerrors);
+ err = libsyscalls_get_syscall_errors((enum libsyscalls_os)os, (enum libsyscalls_arch)arch, &errors, &nerrors);
if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
printf("x\n");
return 0;
diff --git a/testutil/get-syscall-range.c b/testutil/get-syscall-range.c
index 9f26b8e..2c40b71 100644
--- a/testutil/get-syscall-range.c
+++ b/testutil/get-syscall-range.c
@@ -5,21 +5,27 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
- enum libsyscalls_os os;
- enum libsyscalls_arch arch;
+ int os, arch;
long long int min, max;
enum libsyscalls_error err;
- (void) argc;
+ if (argc != 5) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
- os = (enum libsyscalls_os)atoi(argv[1]);
- arch = (enum libsyscalls_arch)atoi(argv[2]);
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
- err = libsyscalls_get_syscall_range(os, arch, &min, &max);
+ err = libsyscalls_get_syscall_range((enum libsyscalls_os)os, (enum libsyscalls_arch)arch, &min, &max);
if (err == LIBSYSCALLS_E_OSNOSUP || err == LIBSYSCALLS_E_ARCHNOSUP) {
printf("min: x\n");
printf("max: x\n");
diff --git a/testutil/is-datatype-struct.c b/testutil/is-datatype-struct.c
index f1c7675..e9eb2ef 100644
--- a/testutil/is-datatype-struct.c
+++ b/testutil/is-datatype-struct.c
@@ -6,18 +6,29 @@
#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+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]);
+ int os, arch, type;
struct libsyscalls_datatype_description desc;
enum libsyscalls_error err;
- size_t i;
- err = libsyscalls_get_datatype_description(os, arch, type, &desc);
+ if (argc != 7) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
+ os = atoi(argv[1]);
+ arch = atoi(argv[2]);
+ type = atoi(argv[3]);
+
+ err = libsyscalls_get_datatype_description((enum libsyscalls_os)os, (enum libsyscalls_arch)arch,
+ (enum libsyscalls_datatype)type, &desc);
if (err == LIBSYSCALLS_E_ISSTRUCT) {
return 0;
} else if (err) {
diff --git a/testutil/is-section-half.c b/testutil/is-section-half.c
index ee6ef50..60de62a 100644
--- a/testutil/is-section-half.c
+++ b/testutil/is-section-half.c
@@ -1,14 +1,24 @@
/* See LICENSE file for copyright and license details. */
#include "../libsyscalls.h"
+#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+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);
+ int sec;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
+ sec = atoi(argv[1]);
+ return !LIBSYSCALLS_IS_SECTION_HALF((enum libsyscalls_datatype_section)sec);
}
diff --git a/testutil/is-section-quarter.c b/testutil/is-section-quarter.c
index 1fe28d2..fd076f8 100644
--- a/testutil/is-section-quarter.c
+++ b/testutil/is-section-quarter.c
@@ -1,14 +1,24 @@
/* See LICENSE file for copyright and license details. */
#include "../libsyscalls.h"
+#include <stdio.h>
#include <stdlib.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+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);
+ int sec;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
+ sec = atoi(argv[1]);
+ return !LIBSYSCALLS_IS_SECTION_QUARTER((enum libsyscalls_datatype_section)sec);
}
diff --git a/testutil/list-errors.c b/testutil/list-errors.c
index 5738b06..365e091 100644
--- a/testutil/list-errors.c
+++ b/testutil/list-errors.c
@@ -6,8 +6,15 @@
int
-main(void)
+main(int argc, char **argv)
{
+ (void) argv;
+
+ if (argc != 1) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
#define X(N, S)\
printf("%li %s %s\n", (long int)N, #N, S)
LIBSYSCALLS_LIST_ERRORS(X, ;);
diff --git a/testutil/perror-all.c b/testutil/perror-all.c
index 2b37cff..d7ee45b 100644
--- a/testutil/perror-all.c
+++ b/testutil/perror-all.c
@@ -4,13 +4,20 @@
#include <stddef.h>
#include <stdio.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
size_t i, count;
- (void) argc;
+ if (argc < 1 || argc > 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
#define X(...) 1
count = (LIBSYSCALLS_LIST_ERRORS(X, +));
diff --git a/testutil/perror-bad.c b/testutil/perror-bad.c
index 55d36d3..338781b 100644
--- a/testutil/perror-bad.c
+++ b/testutil/perror-bad.c
@@ -4,13 +4,20 @@
#include <stddef.h>
#include <stdio.h>
+#if defined(__clang__)
+# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */
+#endif
+
int
-main(int argc, char *argv[])
+main(int argc, char **argv)
{
size_t count;
- (void) argc;
+ if (argc < 1 || argc > 2) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
#define X(...) 1
count = (LIBSYSCALLS_LIST_ERRORS(X, +));
diff --git a/testutil/strerror-all.c b/testutil/strerror-all.c
index b875392..75a3d77 100644
--- a/testutil/strerror-all.c
+++ b/testutil/strerror-all.c
@@ -6,10 +6,17 @@
int
-main(void)
+main(int argc, char **argv)
{
size_t i, count;
+ (void) argv;
+
+ if (argc != 1) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
#define X(...) 1
count = (LIBSYSCALLS_LIST_ERRORS(X, +));
#undef X
diff --git a/testutil/strerror-bad.c b/testutil/strerror-bad.c
index 23d8836..0436d29 100644
--- a/testutil/strerror-bad.c
+++ b/testutil/strerror-bad.c
@@ -6,10 +6,17 @@
int
-main(void)
+main(int argc, char **argv)
{
size_t count;
+ (void) argv;
+
+ if (argc != 1) {
+ fprintf(stderr, "usage error\n");
+ return 3;
+ }
+
#define X(...) 1
count = (LIBSYSCALLS_LIST_ERRORS(X, +));
#undef X