diff options
Diffstat (limited to 'testutil/to-tracee-endian.c')
-rw-r--r-- | testutil/to-tracee-endian.c | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/testutil/to-tracee-endian.c b/testutil/to-tracee-endian.c new file mode 100644 index 0000000..4346883 --- /dev/null +++ b/testutil/to-tracee-endian.c @@ -0,0 +1,111 @@ +/* See LICENSE file for copyright and license details. */ +#include "../libsyscalls.h" + +#include <errno.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined(__clang__) +# pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang is just being silly */ +#endif + + +static void +make_hex(char *out, const char *in, size_t n) +{ + for (; n--; in++) { + *out++ = "0123456789ABCDEF"[((unsigned)*in >> 4) & 0xFU]; + *out++ = "0123456789ABCDEF"[((unsigned)*in >> 0) & 0xFU]; + } + *out = '\0'; +} + + +int +main(int argc, char **argv) +{ + struct libsyscalls_datatype_description type; + char *data, *end, *text0, *text1; + size_t dataoff, i, datasize; + unsigned long long int value; + enum libsyscalls_error err; + + _Static_assert(CHAR_BIT, "We only support 8-bit char at the moment in testutil/to-tracee-endian.c"); + + if (argc < 5) { + usage: + fprintf(stderr, "usage error\n"); + return 1; + } + +#if defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wconversion" +#endif + + errno = 0; + value = strtoull(argv[1], &end, 16); + if (errno || *end) + goto usage; + dataoff = (size_t)atol(argv[2]); + type.width_in_bits = (unsigned short int)atoi(argv[3]); + argv = &argv[4]; + i = 0; + for (; argv[i] && i < sizeof(type.byteorder) / sizeof(*type.byteorder); i++) + type.byteorder[i] = (unsigned)atoi(argv[i]); + if (argv[i]) + goto usage; + for (; i < sizeof(type.byteorder) / sizeof(*type.byteorder); i++) { + type.byteorder[i] = 0U; + type.byteorder[i] = ~type.byteorder[i]; + } + +#if defined(__clang__) +# pragma GCC diagnostic pop +#endif + + datasize = ((size_t)type.width_in_bits + dataoff + 7UL) / 8UL; + data = malloc(datasize); + text0 = malloc(datasize * 2UL + 1UL); + text1 = malloc(datasize * 2UL + 1UL); + + memset(data, 0, datasize); + err = libsyscalls_to_tracee_endian(value, &type, data, dataoff); + if (err == LIBSYSCALLS_E_INVAL) { + printf("inval\n"); + free(data); + goto out; + } else if (err) { + libsyscalls_perror(NULL, err); + return 1; + } + make_hex(text0, data, datasize); + + memset(data, ~0, datasize); + err = libsyscalls_to_tracee_endian(value, &type, data, dataoff); + if (err == LIBSYSCALLS_E_INVAL) { + printf("inval\n"); + free(data); + goto out; + } else if (err) { + libsyscalls_perror(NULL, err); + return 1; + } + make_hex(text1, data, datasize); + + free(data); + + printf("%s %s\n", text0, text1); + + free(text0); + free(text1); + +out: + if (fflush(stdout) || fclose(stdout)) { + perror(NULL); + return 1; + } + return 0; +} |