diff options
| author | Konstantin Belousov <kib@FreeBSD.org> | 2026-01-12 04:45:36 +0000 |
|---|---|---|
| committer | Konstantin Belousov <kib@FreeBSD.org> | 2026-01-20 14:42:35 +0000 |
| commit | 96acaa960023c20e852e04e7cc5c6a5faca36c67 (patch) | |
| tree | 87001a1131485f31fe9d848cf805bc7229e26382 | |
| parent | 1876de606eb876b7a97beccfe6fcc89e60a72a25 (diff) | |
compat32: provide a type and a macro for (u)int64_t handling on non-x86 arches
uint64_t is 4-byte aligned on i386, but is 8-bytes aligned on all other
32bit arches FreeBSD supports. Provide the freebsd32_uint64_t type and
the FU64_CP() macro, which are intended to be used where 32bit ABI uses
(u)int64_t type, and do proper layout and copying for the aggregate type.
Reviewed by: des, emaste
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D54663
| -rw-r--r-- | sys/compat/freebsd32/freebsd32.h | 11 | ||||
| -rw-r--r-- | sys/sys/abi_compat.h | 8 |
2 files changed, 18 insertions, 1 deletions
diff --git a/sys/compat/freebsd32/freebsd32.h b/sys/compat/freebsd32/freebsd32.h index 9d724c93fee7..7324f9adf70c 100644 --- a/sys/compat/freebsd32/freebsd32.h +++ b/sys/compat/freebsd32/freebsd32.h @@ -36,8 +36,17 @@ #include <sys/_ffcounter.h> /* - * i386 is the only arch with a 32-bit time_t + * i386 is the only arch with a 32-bit time_t. + * Also it is the only arch with (u)int64_t having 4-bytes alignment. */ +typedef struct { +#ifdef __amd64__ + uint32_t val[2]; +#else + uint64_t val; +#endif +} freebsd32_uint64_t; + #ifdef __amd64__ typedef int32_t time32_t; #else diff --git a/sys/sys/abi_compat.h b/sys/sys/abi_compat.h index c2233f2eac2c..0a7110191430 100644 --- a/sys/sys/abi_compat.h +++ b/sys/sys/abi_compat.h @@ -67,6 +67,14 @@ TS_CP((src), (dst), it_value); \ } while (0) +#define FU64_CP(src, dst, fld) do { \ + _Static_assert(sizeof((src).fld) == sizeof(uint64_t), \ + "FU64_CP src: " #src "." #fld "is not 8 bytes"); \ + _Static_assert(sizeof((dst).fld) == sizeof(uint64_t), \ + "FU64_CP dst: " #dst "." #fld "is not 8 bytes"); \ + memcpy(&(dst).fld, &(src).fld, sizeof(uint64_t)); \ +} while (0) + #define BT_CP(src, dst, fld) do { \ CP((src).fld, (dst).fld, sec); \ *(uint64_t *)&(dst).fld.frac[0] = (src).fld.frac; \ |
