18a16b7a1SPedro F. Giffuni /*- 2bac2eea1Srilysh * SPDX-License-Identifier: BSD-2-Clause 3bac2eea1Srilysh * Copyright (c) 2024 rilysh <nightquick@proton.me> 458f0484fSRodney W. Grimes */ 558f0484fSRodney W. Grimes 62f5cde3cSTom Rhodes #include <unistd.h> 7*02ebbc78SWarner Losh #include <sys/endian.h> 858f0484fSRodney W. Grimes 958f0484fSRodney W. Grimes void swab(const void * __restrict from,void * __restrict to,ssize_t len)102f5cde3cSTom Rhodesswab(const void * __restrict from, void * __restrict to, ssize_t len) 1158f0484fSRodney W. Grimes { 12*02ebbc78SWarner Losh const uint16_t *f __aligned(1) = from; 13*02ebbc78SWarner Losh uint16_t *t __aligned(1) = to; 1458f0484fSRodney W. Grimes 15*02ebbc78SWarner Losh /* 16*02ebbc78SWarner Losh * POSIX says overlapping copy behavior is undefined, however many 17*02ebbc78SWarner Losh * applications assume the old FreeBSD and current GNU libc behavior 18*02ebbc78SWarner Losh * that will swap the bytes correctly when from == to. Reading both bytes 19*02ebbc78SWarner Losh * and swapping them before writing them back accomplishes this. 20*02ebbc78SWarner Losh */ 21bac2eea1Srilysh while (len > 1) { 22*02ebbc78SWarner Losh *t++ = bswap16(*f++); 23bac2eea1Srilysh len -= 2; 2458f0484fSRodney W. Grimes } 2558f0484fSRodney W. Grimes } 26