diff options
Diffstat (limited to 'libsyscalls_get_datatype_description.c')
-rw-r--r-- | libsyscalls_get_datatype_description.c | 69 |
1 files changed, 46 insertions, 23 deletions
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; |