From: Thomas Weißschuh Date: Sun, 5 Apr 2026 15:31:05 +0000 (+0200) Subject: tools/nolibc: add byteorder conversions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ce834c9cb984a9b85160a2c3a3821e179fa502fa;p=thirdparty%2Fkernel%2Flinux.git tools/nolibc: add byteorder conversions Add some standard functions to convert between different byte orders. Conveniently the UAPI headers provide all the necessary functionality. Signed-off-by: Thomas Weißschuh Acked-by: Willy Tarreau Link: https://patch.msgid.link/20260405-nolibc-bswap-v1-1-f7699ca9cee0@weissschuh.net --- diff --git a/tools/include/nolibc/Makefile b/tools/include/nolibc/Makefile index db6db4e6d99e6..7455097cff693 100644 --- a/tools/include/nolibc/Makefile +++ b/tools/include/nolibc/Makefile @@ -20,11 +20,13 @@ OUTPUT ?= $(CURDIR)/ architectures := arm arm64 loongarch m68k mips powerpc riscv s390 sh sparc x86 arch_files := arch.h $(addsuffix .h, $(addprefix arch-, $(architectures))) all_files := \ + byteswap.h \ compiler.h \ crt.h \ ctype.h \ dirent.h \ elf.h \ + endian.h \ err.h \ errno.h \ fcntl.h \ diff --git a/tools/include/nolibc/byteswap.h b/tools/include/nolibc/byteswap.h new file mode 100644 index 0000000000000..45bbf9609d7af --- /dev/null +++ b/tools/include/nolibc/byteswap.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Byte swapping for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_BYTESWAP_H +#define _NOLIBC_BYTESWAP_H + +#include "stdint.h" + +#include + +#define bswap_16(_x) __swab16(_x) +#define bswap_32(_x) __swab32(_x) +#define bswap_64(_x) __swab64(_x) + +#endif /* _NOLIBC_BYTESWAP_H */ diff --git a/tools/include/nolibc/endian.h b/tools/include/nolibc/endian.h new file mode 100644 index 0000000000000..ccc016ecd5ec2 --- /dev/null +++ b/tools/include/nolibc/endian.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: LGPL-2.1 OR MIT */ +/* + * Byte order conversion for NOLIBC + * Copyright (C) 2026 Thomas Weißschuh + */ + +/* make sure to include all global symbols */ +#include "nolibc.h" + +#ifndef _NOLIBC_ENDIAN_H +#define _NOLIBC_ENDIAN_H + +#include "stdint.h" + +#include + +#define htobe16(_x) __cpu_to_be16(_x) +#define htole16(_x) __cpu_to_le16(_x) +#define be16toh(_x) __be16_to_cpu(_x) +#define le16toh(_x) __le16_to_cpu(_x) + +#define htobe32(_x) __cpu_to_be32(_x) +#define htole32(_x) __cpu_to_le32(_x) +#define be32toh(_x) __be32_to_cpu(_x) +#define le32toh(_x) __le32_to_cpu(_x) + +#define htobe64(_x) __cpu_to_be64(_x) +#define htole64(_x) __cpu_to_le64(_x) +#define be64toh(_x) __be64_to_cpu(_x) +#define le64toh(_x) __le64_to_cpu(_x) + +#endif /* _NOLIBC_ENDIAN_H */ diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h index 294bac1b9039a..f4120f65fe794 100644 --- a/tools/include/nolibc/nolibc.h +++ b/tools/include/nolibc/nolibc.h @@ -131,6 +131,8 @@ #include "poll.h" #include "math.h" #include "err.h" +#include "byteswap.h" +#include "endian.h" /* Used by programs to avoid std includes */ #define NOLIBC diff --git a/tools/testing/selftests/nolibc/nolibc-test.c b/tools/testing/selftests/nolibc/nolibc-test.c index 4bcf468676036..bb13f9f9aa7c2 100644 --- a/tools/testing/selftests/nolibc/nolibc-test.c +++ b/tools/testing/selftests/nolibc/nolibc-test.c @@ -43,6 +43,8 @@ #include #include #include +#include +#include #pragma GCC diagnostic ignored "-Wmissing-prototypes" @@ -67,6 +69,8 @@ static const char *argv0; /* will be used by constructor tests */ static int constructor_test_value; +static const int is_le = __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__; + static const int is_nolibc = #ifdef NOLIBC 1 @@ -1746,6 +1750,15 @@ int run_stdlib(int min, int max) CASE_TEST(major_big); EXPECT_EQ(1, major(0x1122355667734488), 0x11223344); break; CASE_TEST(minor_big); EXPECT_EQ(1, minor(0x1122355667734488), 0x55667788); break; CASE_TEST(malloc); EXPECT_ZR(1, test_malloc()); break; + CASE_TEST(bswap_16); EXPECT_EQ(1, bswap_16(0x0123), 0x2301); break; + CASE_TEST(bswap_32); EXPECT_EQ(1, bswap_32(0x01234567), 0x67452301); break; + CASE_TEST(bswap_64); EXPECT_EQ(1, bswap_64(0x0123456789abcdef), 0xefcdab8967452301); break; + CASE_TEST(htobe16); EXPECT_EQ(1, htobe16(is_le ? 0x0123 : 0x2301), 0x2301); break; + CASE_TEST(htole16); EXPECT_EQ(1, htole16(is_le ? 0x0123 : 0x2301), 0x0123); break; + CASE_TEST(htobe32); EXPECT_EQ(1, htobe32(is_le ? 0x01234567 : 0x67452301), 0x67452301); break; + CASE_TEST(htole32); EXPECT_EQ(1, htole32(is_le ? 0x01234567 : 0x67452301), 0x01234567); break; + CASE_TEST(htobe64); EXPECT_EQ(1, htobe64(is_le ? 0x0123456789000000 : 0x8967452301), 0x8967452301); break; + CASE_TEST(htole64); EXPECT_EQ(1, htole64(is_le ? 0x0123456789 : 0x8967452301000000), 0x0123456789); break; case __LINE__: return ret; /* must be last */