diff --git a/src/util/common.c b/src/util/common.c index 6aa4a99..b01d216 100644 --- a/src/util/common.c +++ b/src/util/common.c @@ -15,43 +15,71 @@ #include #include +#if defined(__x86_64__) || defined(_M_AMD64) #ifdef _WIN32 #include #else #include #include #endif +#endif // This function actually works for both copying LE file data to BE system // memory, and vice versa. all we care about is if the source and target // endianness mismatch (which will only happen if the system is BE since the // file data is guaranteed to be LE), so simply flipping the bytes in this case // will work regardless of which direction we're copying. +#if defined(__x86_64__) || defined(_M_AMD64) +void copy_int_as_le(void *dst, void *src, size_t len) { + memcpy(dst, src, len); + + #ifdef _WIN32 + if (len == 2) { + *((uint16_t*) dst) = _byteswap_ushort(*((uint16_t*) dst)); + } else if (len == 3 || len == 4) { + *((uint32_t*) dst) = _byteswap_ulong(*((uint32_t*) dst)); + } else if (len == 8) { + *((uint64_t*) dst) = _byteswap_uint64(*((uint64_t*) dst)); + } + #else + if (len == 2) { + *((uint16_t*) dst) = __builtin_bswap16(*((uint16_t*) dst)); + ((uint8_t*) dst)[0] ^= ((uint8_t*) dst)[1]; + } else if (len == 3 || len == 4) { + *((uint32_t*) dst) = __builtin_bswap32(*((uint32_t*) dst)); + } else if (len == 8) { + *((uint64_t*) dst) = __builtin_bswap64(*((uint64_t*) dst)); + } + #endif +} +#else +inline static void _swap_bytes(void *bytes, uint8_t off_a, uint8_t off_b) { + unsigned char *byte_arr = (unsigned char *) bytes; + byte_arr[off_a] ^= byte_arr[off_b]; + byte_arr[off_b] ^= byte_arr[off_a]; + byte_arr[off_a] ^= byte_arr[off_b]; +} + void copy_int_as_le(void *dst, void *src, size_t len) { memcpy(dst, src, len); int x = 1; if (((unsigned char*) &x)[0] == 0) { // system is big-endian, so we need to convert to little - #ifdef _WIN32 if (len == 2) { - *((uint16_t*) dst) = _byteswap_ushort(*((uint16_t*) dst)); + _swap_bytes(&dst, 0, 1); } else if (len == 3 || len == 4) { - *((uint32_t*) dst) = _byteswap_ulong(*((uint32_t*) dst)); + _swap_bytes(&dst, 0, 3); + _swap_bytes(&dst, 1, 2); } else if (len == 8) { - *((uint64_t*) dst) = _byteswap_uint64(*((uint64_t*) dst)); + _swap_bytes(&dst, 0, 7); + _swap_bytes(&dst, 1, 6); + _swap_bytes(&dst, 2, 5); + _swap_bytes(&dst, 3, 4); } - #else - if (len == 2) { - *((uint16_t*) dst) = __builtin_bswap16(*((uint16_t*) dst)); - } else if (len == 3 || len == 4) { - *((uint32_t*) dst) = __builtin_bswap32(*((uint32_t*) dst)); - } else if (len == 8) { - *((uint64_t*) dst) = __builtin_bswap64(*((uint64_t*) dst)); - } - #endif } } +#endif int validate_path_component(const char *cmpnt, uint8_t len_s) { for (uint8_t i = 0; i < len_s; i++) {