From 326c676c3487d8807db6e814485b65d60ee268aa Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Thu, 21 Sep 2023 06:43:57 +0100 Subject: [PATCH] macros.h: Introduce side_ptr macros The side_ptr macros allow defining a pointer type which is suitable for use by 32-bit and 64-bit kernels without compatibility code, while preserving information about the pointer type. Those pointers are stored as 64-bit integers, and the type of the actual pointer is kept alongside with the 64-bit pointer value in a 0-len array within a union. uintptr_t will fit within a uint64_t except on architectures with 128-bit pointers. This provides fixed-size pointers on architectures with pointer size of 64-bit or less. Architectures with larger pointer size will have to handle the ABI offset specifics explicitly. Signed-off-by: Mathieu Desnoyers --- include/side/macros.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/include/side/macros.h b/include/side/macros.h index 7c5c9c2..6a0a72d 100644 --- a/include/side/macros.h +++ b/include/side/macros.h @@ -81,4 +81,44 @@ #define SIDE_PACKED __attribute__((packed)) +/* + * The side_ptr macros allow defining a pointer type which is suitable + * for use by 32-bit and 64-bit kernels without compatibility code, + * while preserving information about the pointer type. + * + * Those pointers are stored as 64-bit integers, and the type of the + * actual pointer is kept alongside with the 64-bit pointer value in a + * 0-len array within a union. + * + * uintptr_t will fit within a uint64_t except on architectures with + * 128-bit pointers. This provides fixed-size pointers on architectures + * with pointer size of 64-bit or less. Architectures with larger + * pointer size will have to handle the ABI offset specifics explicitly. + */ +#if (__SIZEOF_POINTER__ <= 8) +# define side_ptr_t(_type) \ + union { \ + uint64_t v; \ + _type *t[0]; \ + } +# define side_ptr_get(_field) \ + ((__typeof__((_field).t[0]))(uintptr_t)(_field).v) +# define side_ptr_set(_field, _ptr) \ + do { \ + (_field).v = (uint64_t)(uintptr_t)(_ptr); \ + } while (0) +#else +# define side_ptr_t(_type) \ + union { \ + uintptr_t v; \ + _type *t[0]; \ + } +# define side_ptr_get(_field) \ + ((__typeof__((_field).t[0]))(_field).v) +# define side_ptr_set(_field, _ptr) \ + do { \ + (_field).v = (uintptr_t)(_ptr); \ + } while (0) +#endif + #endif /* _SIDE_MACROS_H */ -- 2.34.1