/* See LICENSE file for copyright and license details. */ #include "../libsyscalls.h" #include #include #include #include #include #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) { fail: fprintf(stderr, "to-tracee-endian"); for (argv = &argv[1 - argc]; *argv; argv++) fprintf(stderr, " %s", *argv); fprintf(stderr, ": "); 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) { goto fail; } 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; }