The branch main has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=2a5c5b8f7cddf14537707895fceb454cabc1b3bd

commit 2a5c5b8f7cddf14537707895fceb454cabc1b3bd
Author:     John Baldwin <[email protected]>
AuthorDate: 2026-01-14 17:10:33 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2026-01-14 17:10:33 +0000

    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 <[email protected]>
    Fixes:          02ebbc781f08 ("swab: Fix implementation to support 
overlapping copies")
    Sponsored by:   AFRL, DARPA
    
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D54399
---
 lib/libc/string/swab.c | 13 ++++++++++---
 1 file 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 <[email protected]>
  */
 
+#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;
        }
 }

Reply via email to