diff --git a/include/endian.h b/include/endian.h index eb25cedf0bef..87ec7866c791 100644 --- a/include/endian.h +++ b/include/endian.h @@ -1,43 +1,67 @@ /*- * Copyright (c) 2021 M. Warner Losh * * SPDX-License-Identifier: BSD-2-Clause */ /* * A mostly Linux/glibc-compatible endian.h */ #ifndef _ENDIAN_H_ #define _ENDIAN_H_ +/* + * POSIX Issue 8 requires that endian.h define uint{16,32,64}_t. Although POSIX + * allows stdint.h symbols here, be conservative and only define there required + * ones. FreeBSD's sys/_endian.h doesn't need to expose those types since it + * implements all the [bl]eXtoh hto[bl]eX interfaces as macros calling builtin + * functions. POSIX allows functions, macros or both. We opt for macros only. + */ +#include + +#ifndef _UINT16_T_DECLARED +typedef __uint16_t uint16_t; +#define _UINT16_T_DECLARED +#endif + +#ifndef _UINT32_T_DECLARED +typedef __uint32_t uint32_t; +#define _UINT32_T_DECLARED +#endif + +#ifndef _UINT64_T_DECLARED +typedef __uint64_t uint64_t; +#define _UINT64_T_DECLARED +#endif + /* * FreeBSD's sys/_endian.h is very close to the interface provided on Linux by - * glibc's endian.h. + * glibc's endian.h as well as POSIX Issue 8's endian.h. */ #include /* * glibc uses double underscore for these symbols. Define these unconditionally. * The compiler defines __BYTE_ORDER__ these days, so we don't do anything * with that since sys/endian.h defines _BYTE_ORDER based on it. */ #define __BIG_ENDIAN _BIG_ENDIAN #define __BYTE_ORDER _BYTE_ORDER #define __LITTLE_ENDIAN _LITTLE_ENDIAN #define __PDP_ENDIAN _PDP_ENDIAN /* * FreeBSD's sys/endian.h and machine/endian.h doesn't define a separate * byte order for floats. Use the host non-float byte order. */ #define __FLOAT_WORD_ORDER _BYTE_ORDER /* * We don't define BIG_ENDI, LITTLE_ENDI, HIGH_HALF and LOW_HALF macros that * glibc's endian.h defines since those appear to be internal to glibc. * We also don't try to emulate the various helper macros that glibc uses to * limit namespace visibility. */ #endif /* _ENDIAN_H_ */ diff --git a/sys/sys/_endian.h b/sys/sys/_endian.h index 8d1eb3f3f3df..d0ffd87efa11 100644 --- a/sys/sys/_endian.h +++ b/sys/sys/_endian.h @@ -1,133 +1,135 @@ /*- * SPDX-License-Identifier: BSD-3-Clause * * Copyright (c) 1987, 1991 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef _SYS__ENDIAN_H_ #define _SYS__ENDIAN_H_ #if !defined(_MACHINE_ENDIAN_H_) && !defined(_BYTESWAP_H_) && !defined(_ENDIAN_H_) #error "sys/_endian.h should not be included directly" #endif #include /* visibility macros */ /* BSD Compatibility */ #define _BYTE_ORDER __BYTE_ORDER__ /* * Definitions for byte order, according to byte significance from low * address to high. We undefine any prior definition of them because * powerpc compilers define _LITTLE_ENDIAN and _BIG_ENDIAN to mean * something else. */ #undef _LITTLE_ENDIAN #define _LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__ /* LSB first: 1234 */ #undef _BIG_ENDIAN #define _BIG_ENDIAN __ORDER_BIG_ENDIAN__ /* MSB first: 4321 */ #define _PDP_ENDIAN __ORDER_PDP_ENDIAN__ /* LSB first in word, * MSW first in long: 3412 */ /* * Define the order of 32-bit words in 64-bit words. */ #if _BYTE_ORDER == _LITTLE_ENDIAN #define _QUAD_HIGHWORD 1 #define _QUAD_LOWWORD 0 #elif _BYTE_ORDER == _BIG_ENDIAN #define _QUAD_HIGHWORD 0 #define _QUAD_LOWWORD 1 #else #error "Unsupported endian" #endif /* * POSIX Issue 8 will require these for endian.h. Define them there and in the - * traditional BSD compilation environment. Since issue 8 doesn't yet have an - * assigned date, use strictly greater than issue 7's date. + * traditional BSD compilation environment. PDP_ENDIAN isn't strictly in Issue + * 8, but is allowed as implementations can define any *_ENDIAN symbol. Since + * issue 8 doesn't yet have an assigned date, use strictly greater than issue + * 7's date. */ #if __BSD_VISIBLE || _POSIX_C_SOURCE > 200809 #define LITTLE_ENDIAN _LITTLE_ENDIAN #define BIG_ENDIAN _BIG_ENDIAN #define PDP_ENDIAN _PDP_ENDIAN #define BYTE_ORDER _BYTE_ORDER #endif /* bswap primitives, based on compiler builtins */ #define __bswap16(x) __builtin_bswap16(x) #define __bswap32(x) __builtin_bswap32(x) #define __bswap64(x) __builtin_bswap64(x) #if _BYTE_ORDER == _LITTLE_ENDIAN #define __ntohl(x) (__bswap32(x)) #define __ntohs(x) (__bswap16(x)) #define __htonl(x) (__bswap32(x)) #define __htons(x) (__bswap16(x)) #elif _BYTE_ORDER == _BIG_ENDIAN #define __htonl(x) ((__uint32_t)(x)) #define __htons(x) ((__uint16_t)(x)) #define __ntohl(x) ((__uint32_t)(x)) #define __ntohs(x) ((__uint16_t)(x)) #endif /* * Host to big endian, host to little endian, big endian to host, and little * endian to host byte order functions as detailed in byteorder(9). */ #if _BYTE_ORDER == _LITTLE_ENDIAN #define htobe16(x) __bswap16((x)) #define htobe32(x) __bswap32((x)) #define htobe64(x) __bswap64((x)) #define htole16(x) ((uint16_t)(x)) #define htole32(x) ((uint32_t)(x)) #define htole64(x) ((uint64_t)(x)) #define be16toh(x) __bswap16((x)) #define be32toh(x) __bswap32((x)) #define be64toh(x) __bswap64((x)) #define le16toh(x) ((uint16_t)(x)) #define le32toh(x) ((uint32_t)(x)) #define le64toh(x) ((uint64_t)(x)) #else /* _BYTE_ORDER != _LITTLE_ENDIAN */ #define htobe16(x) ((uint16_t)(x)) #define htobe32(x) ((uint32_t)(x)) #define htobe64(x) ((uint64_t)(x)) #define htole16(x) __bswap16((x)) #define htole32(x) __bswap32((x)) #define htole64(x) __bswap64((x)) #define be16toh(x) ((uint16_t)(x)) #define be32toh(x) ((uint32_t)(x)) #define be64toh(x) ((uint64_t)(x)) #define le16toh(x) __bswap16((x)) #define le32toh(x) __bswap32((x)) #define le64toh(x) __bswap64((x)) #endif /* _BYTE_ORDER == _LITTLE_ENDIAN */ #endif /* _SYS__ENDIAN_H_ */