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: 02ebbc781f ("swab: Fix implementation to support overlapping copies")
Sponsored by: AFRL, DARPA
Reviewed by: markj
Differential Revision: https://reviews.freebsd.org/D54399
This commit is contained in:
+10
-3
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user