build: Endian compatibility
- Detect endian instead of stopping configure on big-endian - Add `byteswap.h` and `endian.h` header for compatibility with Windows and other operating systems that don't come with them - Update `crypto/common.h` functions to use compat endian header
This commit is contained in:
parent
51377c2dbe
commit
4414f5ffe1
5 changed files with 263 additions and 69 deletions
13
configure.ac
13
configure.ac
|
@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
|
||||||
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
dnl Require little endian
|
dnl Check for endianness
|
||||||
AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
|
AC_C_BIGENDIAN
|
||||||
|
|
||||||
dnl Check for pthread compile/link requirements
|
dnl Check for pthread compile/link requirements
|
||||||
AX_PTHREAD
|
AX_PTHREAD
|
||||||
|
@ -438,17 +438,22 @@ if test x$TARGET_OS = xdarwin; then
|
||||||
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
|
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
|
||||||
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
|
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
|
||||||
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
|
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
|
||||||
|
|
||||||
AC_CHECK_DECLS([strnlen])
|
AC_CHECK_DECLS([strnlen])
|
||||||
|
|
||||||
AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
|
AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
|
||||||
[#if HAVE_ENDIAN_H
|
[#if HAVE_ENDIAN_H
|
||||||
#include <endian.h>
|
#include <endian.h>
|
||||||
#endif])
|
#endif])
|
||||||
|
|
||||||
|
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
|
||||||
|
[#if HAVE_BYTESWAP_H
|
||||||
|
#include <byteswap.h>
|
||||||
|
#endif])
|
||||||
|
|
||||||
dnl Check for MSG_NOSIGNAL
|
dnl Check for MSG_NOSIGNAL
|
||||||
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
AC_MSG_CHECKING(for MSG_NOSIGNAL)
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
|
||||||
|
|
|
@ -141,6 +141,8 @@ BITCOIN_CORE_H = \
|
||||||
walletdb.h \
|
walletdb.h \
|
||||||
wallet.h \
|
wallet.h \
|
||||||
wallet_ismine.h \
|
wallet_ismine.h \
|
||||||
|
compat/byteswap.h \
|
||||||
|
compat/endian.h \
|
||||||
compat/sanity.h
|
compat/sanity.h
|
||||||
|
|
||||||
JSON_H = \
|
JSON_H = \
|
||||||
|
|
47
src/compat/byteswap.h
Normal file
47
src/compat/byteswap.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_COMPAT_BYTESWAP_H
|
||||||
|
#define BITCOIN_COMPAT_BYTESWAP_H
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config/bitcoin-config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#if defined(HAVE_BYTESWAP_H)
|
||||||
|
#include <byteswap.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_16 == 0
|
||||||
|
inline uint16_t bswap_16(uint16_t x)
|
||||||
|
{
|
||||||
|
return (x >> 8) | ((x & 0x00ff) << 8);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_32 == 0
|
||||||
|
inline uint32_t bswap_32(uint32_t x)
|
||||||
|
{
|
||||||
|
return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
|
||||||
|
((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BSWAP_64 == 0
|
||||||
|
inline uint64_t bswap_64(uint64_t x)
|
||||||
|
{
|
||||||
|
return (((x & 0xff00000000000000ull) >> 56)
|
||||||
|
| ((x & 0x00ff000000000000ull) >> 40)
|
||||||
|
| ((x & 0x0000ff0000000000ull) >> 24)
|
||||||
|
| ((x & 0x000000ff00000000ull) >> 8)
|
||||||
|
| ((x & 0x00000000ff000000ull) << 8)
|
||||||
|
| ((x & 0x0000000000ff0000ull) << 24)
|
||||||
|
| ((x & 0x000000000000ff00ull) << 40)
|
||||||
|
| ((x & 0x00000000000000ffull) << 56));
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BSWAP64
|
||||||
|
|
||||||
|
#endif // BITCOIN_COMPAT_BYTESWAP_H
|
194
src/compat/endian.h
Normal file
194
src/compat/endian.h
Normal file
|
@ -0,0 +1,194 @@
|
||||||
|
// Copyright (c) 2014 The Bitcoin developers
|
||||||
|
// Distributed under the MIT software license, see the accompanying
|
||||||
|
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||||
|
|
||||||
|
#ifndef BITCOIN_COMPAT_ENDIAN_H
|
||||||
|
#define BITCOIN_COMPAT_ENDIAN_H
|
||||||
|
|
||||||
|
#if defined(HAVE_CONFIG_H)
|
||||||
|
#include "config/bitcoin-config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "compat/byteswap.h"
|
||||||
|
|
||||||
|
#if defined(HAVE_ENDIAN_H)
|
||||||
|
#include <endian.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(WORDS_BIGENDIAN)
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE16 == 0
|
||||||
|
inline uint16_t htobe16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return host_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE16 == 0
|
||||||
|
inline uint16_t htole16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(host_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE16TOH == 0
|
||||||
|
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||||
|
{
|
||||||
|
return big_endian_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE16TOH == 0
|
||||||
|
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(little_endian_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE32 == 0
|
||||||
|
inline uint32_t htobe32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return host_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE32 == 0
|
||||||
|
inline uint32_t htole32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(host_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE32TOH == 0
|
||||||
|
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||||
|
{
|
||||||
|
return big_endian_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE32TOH == 0
|
||||||
|
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(little_endian_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE64 == 0
|
||||||
|
inline uint64_t htobe64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return host_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE64 == 0
|
||||||
|
inline uint64_t htole64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(host_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE64TOH == 0
|
||||||
|
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||||
|
{
|
||||||
|
return big_endian_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE64TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE64TOH == 0
|
||||||
|
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(little_endian_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE64TOH
|
||||||
|
|
||||||
|
#else // WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE16 == 0
|
||||||
|
inline uint16_t htobe16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(host_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE16 == 0
|
||||||
|
inline uint16_t htole16(uint16_t host_16bits)
|
||||||
|
{
|
||||||
|
return host_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE16
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE16TOH == 0
|
||||||
|
inline uint16_t be16toh(uint16_t big_endian_16bits)
|
||||||
|
{
|
||||||
|
return bswap_16(big_endian_16bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE16TOH == 0
|
||||||
|
inline uint16_t le16toh(uint16_t little_endian_16bits)
|
||||||
|
{
|
||||||
|
return little_endian_16bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE16TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE32 == 0
|
||||||
|
inline uint32_t htobe32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(host_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE32 == 0
|
||||||
|
inline uint32_t htole32(uint32_t host_32bits)
|
||||||
|
{
|
||||||
|
return host_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE32
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE32TOH == 0
|
||||||
|
inline uint32_t be32toh(uint32_t big_endian_32bits)
|
||||||
|
{
|
||||||
|
return bswap_32(big_endian_32bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE32TOH == 0
|
||||||
|
inline uint32_t le32toh(uint32_t little_endian_32bits)
|
||||||
|
{
|
||||||
|
return little_endian_32bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE32TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOBE64 == 0
|
||||||
|
inline uint64_t htobe64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(host_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOBE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_HTOLE64 == 0
|
||||||
|
inline uint64_t htole64(uint64_t host_64bits)
|
||||||
|
{
|
||||||
|
return host_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_HTOLE64
|
||||||
|
|
||||||
|
#if HAVE_DECL_BE64TOH == 0
|
||||||
|
inline uint64_t be64toh(uint64_t big_endian_64bits)
|
||||||
|
{
|
||||||
|
return bswap_64(big_endian_64bits);
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_BE64TOH
|
||||||
|
|
||||||
|
#if HAVE_DECL_LE64TOH == 0
|
||||||
|
inline uint64_t le64toh(uint64_t little_endian_64bits)
|
||||||
|
{
|
||||||
|
return little_endian_64bits;
|
||||||
|
}
|
||||||
|
#endif // HAVE_DECL_LE64TOH
|
||||||
|
|
||||||
|
#endif // WORDS_BIGENDIAN
|
||||||
|
|
||||||
|
#endif // BITCOIN_COMPAT_ENDIAN_H
|
|
@ -11,110 +11,56 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#if defined(HAVE_ENDIAN_H)
|
#include "compat/endian.h"
|
||||||
#include <endian.h>
|
|
||||||
#endif
|
uint16_t static inline ReadLE16(const unsigned char* ptr)
|
||||||
|
{
|
||||||
|
return le16toh(*((uint16_t*)ptr));
|
||||||
|
}
|
||||||
|
|
||||||
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
uint32_t static inline ReadLE32(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_LE32TOH == 1
|
|
||||||
return le32toh(*((uint32_t*)ptr));
|
return le32toh(*((uint32_t*)ptr));
|
||||||
#elif !defined(WORDS_BIGENDIAN)
|
|
||||||
return *((uint32_t*)ptr);
|
|
||||||
#else
|
|
||||||
return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
uint64_t static inline ReadLE64(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_LE64TOH == 1
|
|
||||||
return le64toh(*((uint64_t*)ptr));
|
return le64toh(*((uint64_t*)ptr));
|
||||||
#elif !defined(WORDS_BIGENDIAN)
|
}
|
||||||
return *((uint64_t*)ptr);
|
|
||||||
#else
|
void static inline WriteLE16(unsigned char* ptr, uint16_t x)
|
||||||
return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
|
{
|
||||||
(uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
|
*((uint16_t*)ptr) = htole16(x);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOLE32 == 1
|
|
||||||
*((uint32_t*)ptr) = htole32(x);
|
*((uint32_t*)ptr) = htole32(x);
|
||||||
#elif !defined(WORDS_BIGENDIAN)
|
|
||||||
*((uint32_t*)ptr) = x;
|
|
||||||
#else
|
|
||||||
ptr[3] = x >> 24;
|
|
||||||
ptr[2] = x >> 16;
|
|
||||||
ptr[1] = x >> 8;
|
|
||||||
ptr[0] = x;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOLE64 == 1
|
|
||||||
*((uint64_t*)ptr) = htole64(x);
|
*((uint64_t*)ptr) = htole64(x);
|
||||||
#elif !defined(WORDS_BIGENDIAN)
|
|
||||||
*((uint64_t*)ptr) = x;
|
|
||||||
#else
|
|
||||||
ptr[7] = x >> 56;
|
|
||||||
ptr[6] = x >> 48;
|
|
||||||
ptr[5] = x >> 40;
|
|
||||||
ptr[4] = x >> 32;
|
|
||||||
ptr[3] = x >> 24;
|
|
||||||
ptr[2] = x >> 16;
|
|
||||||
ptr[1] = x >> 8;
|
|
||||||
ptr[0] = x;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
uint32_t static inline ReadBE32(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_BE32TOH == 1
|
|
||||||
return be32toh(*((uint32_t*)ptr));
|
return be32toh(*((uint32_t*)ptr));
|
||||||
#else
|
|
||||||
return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
uint64_t static inline ReadBE64(const unsigned char* ptr)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_BE64TOH == 1
|
|
||||||
return be64toh(*((uint64_t*)ptr));
|
return be64toh(*((uint64_t*)ptr));
|
||||||
#else
|
|
||||||
return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
|
|
||||||
(uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOBE32 == 1
|
|
||||||
*((uint32_t*)ptr) = htobe32(x);
|
*((uint32_t*)ptr) = htobe32(x);
|
||||||
#else
|
|
||||||
ptr[0] = x >> 24;
|
|
||||||
ptr[1] = x >> 16;
|
|
||||||
ptr[2] = x >> 8;
|
|
||||||
ptr[3] = x;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
|
||||||
{
|
{
|
||||||
#if HAVE_DECL_HTOBE64 == 1
|
|
||||||
*((uint64_t*)ptr) = htobe64(x);
|
*((uint64_t*)ptr) = htobe64(x);
|
||||||
#else
|
|
||||||
ptr[0] = x >> 56;
|
|
||||||
ptr[1] = x >> 48;
|
|
||||||
ptr[2] = x >> 40;
|
|
||||||
ptr[3] = x >> 32;
|
|
||||||
ptr[4] = x >> 24;
|
|
||||||
ptr[5] = x >> 16;
|
|
||||||
ptr[6] = x >> 8;
|
|
||||||
ptr[7] = x;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BITCOIN_CRYPTO_COMMON_H
|
#endif // BITCOIN_CRYPTO_COMMON_H
|
||||||
|
|
Loading…
Reference in a new issue