diff options
Diffstat (limited to 'libsyscalls_get_syscall_display_info.c')
-rw-r--r-- | libsyscalls_get_syscall_display_info.c | 152 |
1 files changed, 12 insertions, 140 deletions
diff --git a/libsyscalls_get_syscall_display_info.c b/libsyscalls_get_syscall_display_info.c index add65e2..f18834c 100644 --- a/libsyscalls_get_syscall_display_info.c +++ b/libsyscalls_get_syscall_display_info.c @@ -43,146 +43,18 @@ trailing_zeroes(unsigned long long int x) } -#define USE_INTERPOLATION_SEARCH /* TODO validate; should be configurable and (if good) default on systems with intrinsic divsion */ -#ifndef USE_INTERPOLATION_SEARCH - - -PURE_FUNCTION -static int -signed_named_number_cmp(const void *a_, const void *b_) -{ - const struct libsyscalls_named_number *a = a_, *b = b_; - return a->number.s < b->number.s ? -1 : a->number.s > b->number.s; -} - - -PURE_FUNCTION -static int -unsigned_named_number_cmp(const void *a_, const void *b_) -{ - const struct libsyscalls_named_number *a = a_, *b = b_; - return a->number.u < b->number.u ? -1 : a->number.u > b->number.u; -} - - -#else - - -/* convertion to unsigned is a modulo (unsigned maximum + 1) operation */ -#define DIFF(TYPE, A, B) ((unsigned TYPE)(A) - (unsigned TYPE)(B)) - -#define INTERPOL_SEARCH(KEY, BASE, N, READ)\ - do {\ - double guess_d;\ - unsigned long long int guess;\ - size_t h = (N);\ - \ - if (!h--)\ - return NULL;\ - \ - if ((KEY) <= READ((BASE), 0))\ - return (KEY) == READ((BASE), 0) ? (BASE) : NULL;\ - if ((KEY) >= READ((BASE), h))\ - return (KEY) == READ((BASE), h) ? (BASE) : NULL;\ - if (READ((BASE), 0) == READ((BASE), h))\ - return NULL;\ - \ - guess = DIFF(long long int, (KEY), READ((BASE), 0));\ - if (h > ULLONG_MAX / guess)\ - goto use_double;\ - \ - for (;;) {\ - guess = DIFF(long long int, (KEY), READ((BASE), 0));\ - guess *= (unsigned long long int)h;\ - guess /= DIFF(long long int, READ((BASE), h), READ((BASE), 0));\ - \ - if (READ((BASE), guess) < (KEY)) {\ - h -= guess += 1;\ - (BASE) = &(BASE)[guess];\ - } else if (READ((BASE), guess) > (KEY)) {\ - h -= guess -= 1;\ - } else {\ - return &(BASE)[guess];\ - }\ - \ - if (READ((BASE), 0) == READ((BASE), h))\ - return (KEY) == READ((BASE), 0) ? (BASE) : NULL;\ - if ((KEY) < READ((BASE), 0))\ - return NULL;\ - if ((KEY) > READ((BASE), h))\ - return NULL;\ - }\ - \ - use_double:\ - for (;;) {\ - guess = DIFF(long long int, (KEY), READ((BASE), 0));\ - guess_d = (double)guess * (double)h;\ - guess = DIFF(long long int, READ((BASE), h), READ((BASE), 0));\ - guess_d /= (double)guess;\ - guess = (unsigned long long int)guess_d;\ - \ - if (READ((BASE), guess) < (KEY)) {\ - h -= guess += 1;\ - (BASE) = &(BASE)[guess];\ - } else if (READ((BASE), guess) > (KEY)) {\ - h -= guess -= 1;\ - } else {\ - return &(BASE)[guess];\ - }\ - \ - if (READ((BASE), 0) == READ((BASE), h))\ - return (KEY) == READ((BASE), 0) ? (BASE) : NULL;\ - if ((KEY) < READ((BASE), 0))\ - return NULL;\ - if ((KEY) > READ((BASE), h))\ - return NULL;\ - }\ - } while (0) - - -PURE_FUNCTION -static const struct libsyscalls_named_number * -interpol_search_signed_named_number(signed long long int key, const struct libsyscalls_named_number *base, size_t n) -{ -#define X(ARR, I) ((ARR)[I].number.s) - INTERPOL_SEARCH(key, base, n, X); -#undef X -} - - -PURE_FUNCTION -static const struct libsyscalls_named_number * -interpol_search_unsigned_named_number(unsigned long long int key, const struct libsyscalls_named_number *base, size_t n) -{ -#define X(ARR, I) ((ARR)[I].number.u) - INTERPOL_SEARCH(key, base, n, X); -#undef X -} - -#undef DIFF - - -#endif - - static const char * -extract_signal(enum libsyscalls_os os, enum libsyscalls_arch arch, unsigned long long int *valuep, char *fallback_out) +extract_signal(enum libsyscalls_os os, enum libsyscalls_arch arch, + unsigned long long int *valuep, char *fallback_out) { const struct libsyscalls_named_number *signals, *found; size_t nsignals; - struct libsyscalls_named_number key = {.number.u = *valuep}; int is_signed; if (libsyscalls_get_signals(os, arch, &signals, &nsignals, &is_signed)) return NULL; -#ifndef USE_INTERPOLATION_SEARCH - found = bsearch(&key, signals, nsignals, sizeof(key), - is_signed ? &signed_named_number_cmp : &unsigned_named_number_cmp); -#else - found = is_signed ? interpol_search_signed_named_number(key.number.s, signals, nsignals) - : interpol_search_unsigned_named_number(key.number.u, signals, nsignals); -#endif + found = libsyscalls_find_named_number(*valuep, is_signed, signals, nsignals); if (!found) return NULL; @@ -196,11 +68,11 @@ extract_signal(enum libsyscalls_os os, enum libsyscalls_arch arch, unsigned long 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, - const struct libsyscalls_syscall_abi *syscall, int nargs, int nsyms) + const struct libsyscalls_syscall_abi *syscall, + size_t nargs, size_t nsyms) { struct libsyscalls_syscall_display_info *ret; - size_t size, dataoff, paramoff; - int i; + size_t i, size, dataoff, paramoff; size = sizeof(*ret); @@ -209,14 +81,14 @@ build_syscall_display_info(void *data, size_t data_size, size_t data_align, size += 1; } dataoff = size; - size += (size_t)nsyms * data_size; + size += nsyms * data_size; if (size & (alignof(struct libsyscalls_syscall_type_info) - 1)) { size |= alignof(struct libsyscalls_syscall_type_info) - 1; size += 1; } paramoff = size; - size += (size_t)(nargs + 1) * sizeof(*ret->params); + size += (nargs + 1U) * sizeof(*ret->params); ret = calloc(1, size); if (!ret) @@ -231,8 +103,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 + (size_t)nsyms * data_size]; - memcpy(ret->params[i].data, &((char *)data)[(size_t)i * data_size], data_size); + ret->params[i].data = (void *)&((char *)ret)[dataoff + nsyms * data_size]; + memcpy(ret->params[i].data, &((char *)data)[i * data_size], data_size); nsyms++; } } @@ -240,8 +112,8 @@ 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 + (size_t)nsyms * data_size]; - memcpy(ret->retvalue->data, &((char *)data)[(size_t)i * data_size], data_size); + ret->retvalue->data = (void *)&((char *)ret)[dataoff + nsyms * data_size]; + memcpy(ret->retvalue->data, &((char *)data)[i * data_size], data_size); } return ret; |