macros.h: Introduce side_ptr macros
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Sep 2023 05:43:57 +0000 (06:43 +0100)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 21 Sep 2023 05:44:15 +0000 (06:44 +0100)
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 <mathieu.desnoyers@efficios.com>
include/side/macros.h

index 7c5c9c25b2f12b660c998160b2d80bf9d62f836d..6a0a72dc2efa84e93c32522ba3232f9b483773fe 100644 (file)
 
 #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 */
This page took 0.040561 seconds and 4 git commands to generate.