- 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 headertags/v0.15.1
@@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then | |||
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")]) | |||
fi | |||
dnl Require little endian | |||
AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")]) | |||
dnl Check for endianness | |||
AC_C_BIGENDIAN | |||
dnl Check for pthread compile/link requirements | |||
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"]) | |||
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([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([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 | |||
#include <endian.h> | |||
#endif]) | |||
AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,, | |||
[#if HAVE_BYTESWAP_H | |||
#include <byteswap.h> | |||
#endif]) | |||
dnl Check for MSG_NOSIGNAL | |||
AC_MSG_CHECKING(for MSG_NOSIGNAL) | |||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]], |
@@ -141,6 +141,8 @@ BITCOIN_CORE_H = \ | |||
walletdb.h \ | |||
wallet.h \ | |||
wallet_ismine.h \ | |||
compat/byteswap.h \ | |||
compat/endian.h \ | |||
compat/sanity.h | |||
JSON_H = \ |
@@ -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 |
@@ -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> | |||
#if defined(HAVE_ENDIAN_H) | |||
#include <endian.h> | |||
#endif | |||
#include "compat/endian.h" | |||
uint16_t static inline ReadLE16(const unsigned char* ptr) | |||
{ | |||
return le16toh(*((uint16_t*)ptr)); | |||
} | |||
uint32_t static inline ReadLE32(const unsigned char* ptr) | |||
{ | |||
#if HAVE_DECL_LE32TOH == 1 | |||
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) | |||
{ | |||
#if HAVE_DECL_LE64TOH == 1 | |||
return le64toh(*((uint64_t*)ptr)); | |||
#elif !defined(WORDS_BIGENDIAN) | |||
return *((uint64_t*)ptr); | |||
#else | |||
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]); | |||
#endif | |||
} | |||
void static inline WriteLE16(unsigned char* ptr, uint16_t x) | |||
{ | |||
*((uint16_t*)ptr) = htole16(x); | |||
} | |||
void static inline WriteLE32(unsigned char* ptr, uint32_t x) | |||
{ | |||
#if HAVE_DECL_HTOLE32 == 1 | |||
*((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) | |||
{ | |||
#if HAVE_DECL_HTOLE64 == 1 | |||
*((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) | |||
{ | |||
#if HAVE_DECL_BE32TOH == 1 | |||
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) | |||
{ | |||
#if HAVE_DECL_BE64TOH == 1 | |||
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) | |||
{ | |||
#if HAVE_DECL_HTOBE32 == 1 | |||
*((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) | |||
{ | |||
#if HAVE_DECL_HTOBE64 == 1 | |||
*((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 |