From 6d77b155bcd4725e09837604e6ea86f5f124ba9c Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Tue, 5 Dec 2023 20:10:48 +0100 Subject: Third commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- Makefile | 3 + TODO | 2 +- common.h | 1 + devtools/.gitignore | 2 + devtools/clean-c.c | 92 ++++++ devtools/list-c-types.c | 160 ++++++++++ libsyscalls.h | 25 +- libsyscalls_get_datatype_description.c | 69 ++-- libsyscalls_get_syscall_display_info.c | 38 ++- libsyscalls_get_syscall_errors.c | 2 +- linux/errors.c | 4 +- linux/signals.c | 4 +- linux/symbols.c | 36 ++- linux/syscall-table.c | 11 + linux/tests/os-dependent-arrays | 17 + linux/tests/os-dependent-primitives | 23 ++ linux/types.c | 1 + test | 561 ++------------------------------- tests/archinfo | 22 ++ tests/array-types | 33 ++ tests/enums | 24 ++ tests/errors | 59 ++++ tests/fixed-array-types | 33 ++ tests/fundamental-primitives | 161 ++++++++++ tests/is-struct | 20 ++ tests/load-archinfo | 41 +++ tests/load-functions | 60 ++++ tests/load-types | 4 + tests/os-dependent-arrays | 9 + tests/os-dependent-primitives | 15 + tests/signals | 43 +++ tests/split-register-classes | 22 ++ tests/split-register-types | 70 ++++ tests/syscall-errors | 46 +++ tests/syscall-ranges | 38 +++ tests/test-self-check | 47 +++ testutil/get-datatype-description.c | 30 +- testutil/get-error.c | 11 +- testutil/get-section-fraction.c | 17 +- testutil/get-signals.c | 20 +- testutil/get-syscall-errors.c | 20 +- testutil/get-syscall-range.c | 20 +- testutil/is-datatype-struct.c | 23 +- testutil/is-section-half.c | 20 +- testutil/is-section-quarter.c | 20 +- testutil/list-errors.c | 9 +- testutil/perror-all.c | 11 +- testutil/perror-bad.c | 11 +- testutil/strerror-all.c | 9 +- testutil/strerror-bad.c | 9 +- 50 files changed, 1384 insertions(+), 644 deletions(-) create mode 100644 devtools/.gitignore create mode 100644 devtools/clean-c.c create mode 100644 devtools/list-c-types.c create mode 100644 linux/tests/os-dependent-arrays create mode 100644 linux/tests/os-dependent-primitives create mode 100644 tests/archinfo create mode 100644 tests/array-types create mode 100644 tests/enums create mode 100644 tests/errors create mode 100644 tests/fixed-array-types create mode 100644 tests/fundamental-primitives create mode 100644 tests/is-struct create mode 100644 tests/load-archinfo create mode 100644 tests/load-functions create mode 100644 tests/load-types create mode 100644 tests/os-dependent-arrays create mode 100644 tests/os-dependent-primitives create mode 100644 tests/signals create mode 100644 tests/split-register-classes create mode 100644 tests/split-register-types create mode 100644 tests/syscall-errors create mode 100644 tests/syscall-ranges create mode 100644 tests/test-self-check 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 +#include +#include +#include + + +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 +#include +#include +#include +#include + + +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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 #include +#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 -- cgit v1.2.3-70-g09d2