X-Git-Url: https://git.efficios.com/?a=blobdiff_plain;f=include%2Fside%2Fmacros.h;h=20fa97e804f07d76aae19d2afe1fe765620e6812;hb=053076a034894718038e3478904f373da9a242f9;hp=aea7b9ca5e71c12de16afb752213572515cffff3;hpb=d0ee69ff824fa3a480c520896d0a69385306a204;p=libside.git diff --git a/include/side/macros.h b/include/side/macros.h index aea7b9c..20fa97e 100644 --- a/include/side/macros.h +++ b/include/side/macros.h @@ -72,13 +72,55 @@ sizeof(((_struct * )NULL)->_field) #if defined(__SIZEOF_LONG__) -#define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) +# define SIDE_BITS_PER_LONG (__SIZEOF_LONG__ * 8) #elif defined(_LP64) -#define SIDE_BITS_PER_LONG 64 +# define SIDE_BITS_PER_LONG 64 #else -#define SIDE_BITS_PER_LONG 32 +# define SIDE_BITS_PER_LONG 32 #endif #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 + +#define SIDE_PTR_INIT(...) { .v = (uintptr_t) (__VA_ARGS__) } + #endif /* _SIDE_MACROS_H */