aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2026-01-14 17:10:33 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2026-01-14 17:10:33 +0000
commit2a5c5b8f7cddf14537707895fceb454cabc1b3bd (patch)
treee88a292f3e6f372c17dd3973a02630c8cc01dbee
parentfef84fd8ae845e19cec0f6b9aac0e6451cca3d7a (diff)
swab: Correctly treat the data as misaligned
The __aligned attribute in the previous version applied to the location of the pointers, not the data the pointers pointed to. While this could be fixed by applying the attribute to a local typedef of uint16_t, just using memcpy() for the unaligned access is simpler and ISO C. This fixes the build on CHERI architectures which do not support misaligned pointers and were thus failing with: lib/libc/string/swab.c:12:18: error: alignment (1) of 'const uint16_t *' (aka 'const unsigned short *') is less than the required capability alignment (16) [-Werror,-Wcheri-capability-misuse] 12 | const uint16_t *f __aligned(1) = from; | Co-authored by: Jessica Clarke <jrtc27@FreeBSD.org> Fixes: 02ebbc781f08 ("swab: Fix implementation to support overlapping copies") Sponsored by: AFRL, DARPA Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D54399
-rw-r--r--lib/libc/string/swab.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/lib/libc/string/swab.c b/lib/libc/string/swab.c
index ed4436a49810..4f4fb26379c6 100644
--- a/lib/libc/string/swab.c
+++ b/lib/libc/string/swab.c
@@ -3,14 +3,16 @@
* Copyright (c) 2024 rilysh <nightquick@proton.me>
*/
+#include <string.h>
#include <unistd.h>
#include <sys/endian.h>
void
swab(const void * __restrict from, void * __restrict to, ssize_t len)
{
- const uint16_t *f __aligned(1) = from;
- uint16_t *t __aligned(1) = to;
+ const char *f = from;
+ char *t = to;
+ uint16_t tmp;
/*
* POSIX says overlapping copy behavior is undefined, however many
@@ -19,7 +21,12 @@ swab(const void * __restrict from, void * __restrict to, ssize_t len)
* and swapping them before writing them back accomplishes this.
*/
while (len > 1) {
- *t++ = bswap16(*f++);
+ memcpy(&tmp, f, 2);
+ tmp = bswap16(tmp);
+ memcpy(t, &tmp, 2);
+
+ f += 2;
+ t += 2;
len -= 2;
}
}