/* See LICENSE file for copyright and license details. */ #ifdef REQUIRE_FLEXABLE_OR_NPARAMS # if defined(__clang__) # define LIBSYSCALLS_FLEXABLE_OR_NPARAMS_ # pragma clang diagnostic ignored "-Wgnu-flexible-array-initializer" # elif defined(__GNUC__) # define LIBSYSCALLS_FLEXABLE_OR_NPARAMS_ # pragma GCC diagnostic ignored "-Wpedantic" # else # define LIBSYSCALLS_FLEXABLE_OR_NPARAMS_ NPARAMS # warning Setting LIBSYSCALLS_FLEXABLE_OR_NPARAMS_ to NPARAMS as it is not known that the compiler supports static allocation of structs with flexible arrays # endif #endif #ifdef REQUIRE_FLEXABLE_OR_NFIELDS # if defined(__clang__) # define LIBSYSCALLS_FLEXABLE_OR_NFIELDS_ # pragma clang diagnostic ignored "-Wgnu-flexible-array-initializer" # elif defined(__GNUC__) # define LIBSYSCALLS_FLEXABLE_OR_NFIELDS_ # pragma GCC diagnostic ignored "-Wpedantic" # else # define LIBSYSCALLS_FLEXABLE_OR_NFIELDS_ NFIELDS # warning Setting LIBSYSCALLS_FLEXABLE_OR_NFIELDS_ to NFIELDS as it is not known that the compiler supports static allocation of structs with flexible arrays # endif #endif #include "libsyscalls.h" #include #include #include #include #include #include #if defined(__clang__) /* We expect the user to use -Weverything */ # pragma clang diagnostic ignored "-Wimplicit-fallthrough" /* we use GCC's fall though comments */ # pragma clang diagnostic ignored "-Wcovered-switch-default" /* the user may input something invalid due to version differences */ # pragma clang diagnostic ignored "-Wc++98-compat" /* don't care about C++, especially not for internal code */ # pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" /* TODO how does that make sense in C23? */ # pragma clang diagnostic ignored "-Wunsafe-buffer-usage" /* clang doesn't know what it is doing */ # pragma clang diagnostic ignored "-Wvla" /* we prefer VLA over alloca (easier to support), and we are careful */ #elif defined(__GNUC__) /* We expect the user to use -Wall -Wextra mand maybe some other flags */ # pragma GCC diagnostic ignored "-Wnonnull-compare" /* why should I trust that the user is using the same compiler? */ # pragma GCC diagnostic ignored "-Winline" /* it's just a preference, up to the compiler to decide */ #endif #if defined(__GNUC__) # define PURE_FUNCTION __attribute__((__pure__)) #else # define PURE_FUNCTION #endif #define COMMA , #define MISALIGNMENT(ADDR, ALIGN) ((ADDR) & ((uintptr_t)(ALIGN) - 1U)) #define ALIGNMENT_ADJUSTMENT(ADDR, ALIGN) MISALIGNMENT((ALIGN) - MISALIGNMENT((ADDR), (ALIGN)), (ALIGN)) #define ALIGN_BUF(BUF, ALIGN) (&(BUF)[(size_t)ALIGNMENT_ADJUSTMENT((uintptr_t)(char *)(BUF), (ALIGN))]) #define ELEMSOF(ARR) (sizeof(ARR) / sizeof *(ARR)) #define MAX(A, B) ((A) > (B) ? (A) : (B)) #define LOWEST_BIT(X) ((X) & ~((X) - 1)) #define POST_HIGHEST_OF_CONSECUTIVELY_BITS(X) ((X) + LOWEST_BIT((X))) #define IS_NOT_2POW(X) ((X) & ((X) - 1)) #define SET_MASK_TRAIL(X) ((X) | ((X) - 1U)) #define USAT_MINUS(A, B) ((A) < (B) ? 0 : (A) - (B)) struct libsyscalls_symbol_printer_data { enum libsyscalls_arch arch; int nr; char buf[]; }; enum endian { Big, Little }; /* [------ size ------] [align] */ #define LIST_ARCH_SPECS(X, D) /* byte intptr size_t intmax endian sign */\ X(LIBSYSCALLS_ARCH_ALPHA_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_ALPHA_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_AMD64, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_AMD64_X32, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ /* X(LIBSYSCALLS_ARCH_ARM_OABI_LE, 8, TODO, TODO, 32, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_ARM_OABI_BE, 8, TODO, TODO, 32, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_ARM_EABI_LE, 8, TODO, TODO, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_ARM_EABI_BE, 8, TODO, TODO, 64, Big, TWOS_COMPLEMENT) D\ */\ X(LIBSYSCALLS_ARCH_IA64_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_IA64_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_IA64_P32_LE, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_IA64_P32_BE, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_M68K, 8, 32, 32, 16, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MICROBLAZE_32_LE, 8, 32, 32, 32, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MICROBLAZE_32_BE, 8, 32, 32, 32, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MICROBLAZE_64_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MICROBLAZE_64_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_O32_LE, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_O32_BE, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_N32_LE, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_N32_BE, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_N64_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_MIPS_N64_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_PARISC_32, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_PARISC_64, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_32_LE, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_32_BE, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_64_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_64_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_NOSPU_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_NOSPU_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_SPU_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_POWERPC_SPU_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_S390_32, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_S390_64, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_SH_LE, 8, 32, 32, 32, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_SH_BE, 8, 32, 32, 32, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_SPARC_32, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_SPARC_64_LE, 8, 64, 64, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_SPARC_64_BE, 8, 64, 64, 64, Big, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_I386, 8, 32, 32, 32, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_XTENSA_LE, 8, 32, 32, 64, Little, TWOS_COMPLEMENT) D\ X(LIBSYSCALLS_ARCH_XTENSA_BE, 8, 32, 32, 64, Big, TWOS_COMPLEMENT) /* Don't forget to update SUPPORTED_ARCHES in Makefile */ #include "generated/oses.h" #include "generated/arches.h" #include "generated/lowercase.h" #include "generated/macros.h" #if defined(__clang__) # pragma clang diagnostic push # pragma clang diagnostic ignored "-Wunsafe-buffer-usage" #endif extern const struct libsyscalls_syscall *const *const *const libsyscalls_syscalls_tables_[]; #define X(UPPERCASE, LOWERCASE)\ extern const struct libsyscalls_syscall *const *const libsyscalls_##LOWERCASE##_syscalls_table_[]; LIST_OSES(X,) #undef X #if defined(__clang__) # pragma clang diagnostic pop #endif #define COUNT_LIST_(...) 1 #define COUNT_LIST(LIST_MACRO) (LIST_MACRO(COUNT_LIST_,, +,)) #define COUNT_ARGS(...) (0 __VA_OPT__(+ COUNT_ARGS_1(__VA_ARGS__))) #define COUNT_ARG_PAIRS(...) (0 __VA_OPT__(+ COUNT_ARG_PAIRS_1(__VA_ARGS__))) /* mk/generate.mk reads these three lines, do not format them as multiline macros! */ #define COUNT_ARGS_1(x, ...) 1 __VA_OPT__(+ COUNT_ARGS_2(__VA_ARGS__)) #define COUNT_ARG_PAIRS_1(x1, x2, ...) 1 __VA_OPT__(+ COUNT_ARG_PAIRS_2(__VA_ARGS__)) #define PARAMS_BUILD_TYPES_1(x, A, ...) LIBSYSCALLS_TYPE_##A __VA_OPT__(, PARAMS_BUILD_TYPES_2(__VA_ARGS__)) #define PARAMS(...)\ .max_argument_count = COUNT_ARG_PAIRS(__VA_ARGS__),\ .in_pointer_mask = PARAMS_BUILD_MASK(IN, __VA_ARGS__),\ .out_pointer_mask = PARAMS_BUILD_MASK(OUT, __VA_ARGS__), \ .symbolic_mask = PARAMS_BUILD_MASK(SYM, __VA_ARGS__)\ __VA_OPT__(, .parameters_types = {PARAMS_BUILD_TYPES_1(__VA_ARGS__)}) #define ZERO(TYPE) TYPE, .expect_zero = 1 #define LIBSYSCALLS_TYPE_ZERO(TYPE) ZERO(LIBSYSCALLS_TYPE_##TYPE) #define SYMB(TYPE) TYPE, .symbolic_return = 1 #define LIBSYSCALLS_TYPE_SYMB(TYPE) SYMB(LIBSYSCALLS_TYPE_##TYPE) #define SYSCALL_ABI(OS, NAME, CATEGORY, SUBCATEGORY, MIN_ARGS, RETURN_TYPE, ...)\ static struct libsyscalls_syscall_abi OS##_syscall_##NAME = {\ .category = LIBSYSCALLS_CAT_##CATEGORY,\ .subcategory.LOWERCASE_##CATEGORY = LIBSYSCALLS_##CATEGORY##_SUBCAT_##SUBCATEGORY,\ .min_argument_count = MIN_ARGS,\ .return_type = LIBSYSCALLS_TYPE_##RETURN_TYPE,\ __VA_ARGS__\ }