tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lowstar_endianness.h (7422B)


      1 /* Copyright (c) INRIA and Microsoft Corporation. All rights reserved.
      2   Licensed under the Apache 2.0 and MIT Licenses. */
      3 
      4 #ifndef KRML_HEADER_LOWSTAR_ENDIANNESS_H
      5 #define KRML_HEADER_LOWSTAR_ENDIANNESS_H
      6 
      7 #include <string.h>
      8 #include <inttypes.h>
      9 
     10 /******************************************************************************/
     11 /* Implementing C.fst (part 2: endian-ness macros)                            */
     12 /******************************************************************************/
     13 
     14 /* ... for Linux */
     15 #if defined(__linux__) || defined(__CYGWIN__) || defined(__USE_SYSTEM_ENDIAN_H__) || defined(__GLIBC__)
     16 #include <endian.h>
     17 
     18 /* ... for OSX */
     19 #elif defined(__APPLE__)
     20 #include <libkern/OSByteOrder.h>
     21 #define htole64(x) OSSwapHostToLittleInt64(x)
     22 #define le64toh(x) OSSwapLittleToHostInt64(x)
     23 #define htobe64(x) OSSwapHostToBigInt64(x)
     24 #define be64toh(x) OSSwapBigToHostInt64(x)
     25 
     26 #define htole16(x) OSSwapHostToLittleInt16(x)
     27 #define le16toh(x) OSSwapLittleToHostInt16(x)
     28 #define htobe16(x) OSSwapHostToBigInt16(x)
     29 #define be16toh(x) OSSwapBigToHostInt16(x)
     30 
     31 #define htole32(x) OSSwapHostToLittleInt32(x)
     32 #define le32toh(x) OSSwapLittleToHostInt32(x)
     33 #define htobe32(x) OSSwapHostToBigInt32(x)
     34 #define be32toh(x) OSSwapBigToHostInt32(x)
     35 
     36 /* ... for Solaris */
     37 #elif defined(__sun__)
     38 #include <sys/byteorder.h>
     39 #define htole64(x) LE_64(x)
     40 #define le64toh(x) LE_64(x)
     41 #define htobe64(x) BE_64(x)
     42 #define be64toh(x) BE_64(x)
     43 
     44 #define htole16(x) LE_16(x)
     45 #define le16toh(x) LE_16(x)
     46 #define htobe16(x) BE_16(x)
     47 #define be16toh(x) BE_16(x)
     48 
     49 #define htole32(x) LE_32(x)
     50 #define le32toh(x) LE_32(x)
     51 #define htobe32(x) BE_32(x)
     52 #define be32toh(x) BE_32(x)
     53 
     54 /* ... for the BSDs */
     55 #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
     56 #include <sys/endian.h>
     57 #elif defined(__OpenBSD__)
     58 #include <endian.h>
     59 
     60 /* ... for Windows (MSVC)... not targeting XBOX 360! */
     61 #elif defined(_MSC_VER)
     62 
     63 #include <stdlib.h>
     64 #define htobe16(x) _byteswap_ushort(x)
     65 #define htole16(x) (x)
     66 #define be16toh(x) _byteswap_ushort(x)
     67 #define le16toh(x) (x)
     68 
     69 #define htobe32(x) _byteswap_ulong(x)
     70 #define htole32(x) (x)
     71 #define be32toh(x) _byteswap_ulong(x)
     72 #define le32toh(x) (x)
     73 
     74 #define htobe64(x) _byteswap_uint64(x)
     75 #define htole64(x) (x)
     76 #define be64toh(x) _byteswap_uint64(x)
     77 #define le64toh(x) (x)
     78 
     79 /* ... for Windows (GCC-like, e.g. mingw or clang) */
     80 #elif (defined(_WIN32) || defined(_WIN64) || defined(__EMSCRIPTEN__)) && \
     81    (defined(__GNUC__) || defined(__clang__))
     82 
     83 #define htobe16(x) __builtin_bswap16(x)
     84 #define htole16(x) (x)
     85 #define be16toh(x) __builtin_bswap16(x)
     86 #define le16toh(x) (x)
     87 
     88 #define htobe32(x) __builtin_bswap32(x)
     89 #define htole32(x) (x)
     90 #define be32toh(x) __builtin_bswap32(x)
     91 #define le32toh(x) (x)
     92 
     93 #define htobe64(x) __builtin_bswap64(x)
     94 #define htole64(x) (x)
     95 #define be64toh(x) __builtin_bswap64(x)
     96 #define le64toh(x) (x)
     97 
     98 /* ... generic big-endian fallback code */
     99 /* ... AIX doesn't have __BYTE_ORDER__ (with XLC compiler) & is always big-endian */
    100 #elif (defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || defined(_AIX)
    101 
    102 /* byte swapping code inspired by:
    103 * https://github.com/rweather/arduinolibs/blob/master/libraries/Crypto/utility/EndianUtil.h
    104 * */
    105 
    106 #define htobe32(x) (x)
    107 #define be32toh(x) (x)
    108 #define htole32(x)                                                      \
    109    (__extension__({                                                    \
    110        uint32_t _temp = (x);                                           \
    111        ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) |    \
    112            ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
    113    }))
    114 #define le32toh(x) (htole32((x)))
    115 
    116 #define htobe64(x) (x)
    117 #define be64toh(x) (x)
    118 #define htole64(x)                                           \
    119    (__extension__({                                         \
    120        uint64_t __temp = (x);                               \
    121        uint32_t __low = htobe32((uint32_t)__temp);          \
    122        uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
    123        (((uint64_t)__low) << 32) | __high;                  \
    124    }))
    125 #define le64toh(x) (htole64((x)))
    126 
    127 /* ... generic little-endian fallback code */
    128 #elif defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    129 
    130 #define htole32(x) (x)
    131 #define le32toh(x) (x)
    132 #define htobe32(x)                                                      \
    133    (__extension__({                                                    \
    134        uint32_t _temp = (x);                                           \
    135        ((_temp >> 24) & 0x000000FF) | ((_temp >> 8) & 0x0000FF00) |    \
    136            ((_temp << 8) & 0x00FF0000) | ((_temp << 24) & 0xFF000000); \
    137    }))
    138 #define be32toh(x) (htobe32((x)))
    139 
    140 #define htole64(x) (x)
    141 #define le64toh(x) (x)
    142 #define htobe64(x)                                           \
    143    (__extension__({                                         \
    144        uint64_t __temp = (x);                               \
    145        uint32_t __low = htobe32((uint32_t)__temp);          \
    146        uint32_t __high = htobe32((uint32_t)(__temp >> 32)); \
    147        (((uint64_t)__low) << 32) | __high;                  \
    148    }))
    149 #define be64toh(x) (htobe64((x)))
    150 
    151 /* ... couldn't determine endian-ness of the target platform */
    152 #else
    153 #error "Please define __BYTE_ORDER__!"
    154 
    155 #endif /* defined(__linux__) || ... */
    156 
    157 /* Loads and stores. These avoid undefined behavior due to unaligned memory
    158 * accesses, via memcpy. */
    159 
    160 inline static uint16_t
    161 load16(uint8_t *b)
    162 {
    163    uint16_t x;
    164    memcpy(&x, b, 2);
    165    return x;
    166 }
    167 
    168 inline static uint32_t
    169 load32(uint8_t *b)
    170 {
    171    uint32_t x;
    172    memcpy(&x, b, 4);
    173    return x;
    174 }
    175 
    176 inline static uint64_t
    177 load64(uint8_t *b)
    178 {
    179    uint64_t x;
    180    memcpy(&x, b, 8);
    181    return x;
    182 }
    183 
    184 inline static void
    185 store16(uint8_t *b, uint16_t i)
    186 {
    187    memcpy(b, &i, 2);
    188 }
    189 
    190 inline static void
    191 store32(uint8_t *b, uint32_t i)
    192 {
    193    memcpy(b, &i, 4);
    194 }
    195 
    196 inline static void
    197 store64(uint8_t *b, uint64_t i)
    198 {
    199    memcpy(b, &i, 8);
    200 }
    201 
    202 /* Legacy accessors so that this header can serve as an implementation of
    203 * C.Endianness */
    204 #define load16_le(b) (le16toh(load16(b)))
    205 #define store16_le(b, i) (store16(b, htole16(i)))
    206 #define load16_be(b) (be16toh(load16(b)))
    207 #define store16_be(b, i) (store16(b, htobe16(i)))
    208 
    209 #define load32_le(b) (le32toh(load32(b)))
    210 #define store32_le(b, i) (store32(b, htole32(i)))
    211 #define load32_be(b) (be32toh(load32(b)))
    212 #define store32_be(b, i) (store32(b, htobe32(i)))
    213 
    214 #define load64_le(b) (le64toh(load64(b)))
    215 #define store64_le(b, i) (store64(b, htole64(i)))
    216 #define load64_be(b) (be64toh(load64(b)))
    217 #define store64_be(b, i) (store64(b, htobe64(i)))
    218 
    219 /* Co-existence of LowStar.Endianness and FStar.Endianness generates name
    220 * conflicts, because of course both insist on having no prefixes. Until a
    221 * prefix is added, or until we truly retire FStar.Endianness, solve this issue
    222 * in an elegant way. */
    223 #define load16_le0 load16_le
    224 #define store16_le0 store16_le
    225 #define load16_be0 load16_be
    226 #define store16_be0 store16_be
    227 
    228 #define load32_le0 load32_le
    229 #define store32_le0 store32_le
    230 #define load32_be0 load32_be
    231 #define store32_be0 store32_be
    232 
    233 #define load64_le0 load64_le
    234 #define store64_le0 store64_le
    235 #define load64_be0 load64_be
    236 #define store64_be0 store64_be
    237 
    238 #define load128_le0 load128_le
    239 #define store128_le0 store128_le
    240 #define load128_be0 load128_be
    241 #define store128_be0 store128_be
    242 
    243 #endif /* KRML_HEADER_LOWSTAR_ENDIANNESS_H */