#ifndef CEPH_SAN_SER_H
#define CEPH_SAN_SER_H
+#define __suppress_cast_warning(type, value) \
+ _Pragma("GCC diagnostic push") \
+ _Pragma("GCC diagnostic ignored \"-Wint-to-pointer-cast\"") \
+ _Pragma("GCC diagnostic ignored \"-Wpointer-to-int-cast\"") \
+ ((type)(value)) \
+ _Pragma("GCC diagnostic pop")
+
#define ___ceph_san_concat(__a, __b) __a ## __b
#define ___ceph_san_apply(__fn, __n) ___ceph_san_concat(__fn, __n)
#define ___ceph_san_cnt32(__t, __args...) (___ceph_san_cnt31(__args) + sizeof(__t))
#define ceph_san_cnt(...) ___ceph_san_apply(___ceph_san_cnt, ceph_san_narg(__VA_ARGS__))(__VA_ARGS__)
-#define __ceph_san_ser_const_type(__buffer, __t) \
- (__builtin_choose_expr( \
- __builtin_types_compatible_p(typeof(__t), const char *), \
- (*(char **)(__buffer) = (char *)(__t)), \
- (*(typeof(__t) *)(__buffer) = (__t)) \
- ))
-
-#define __ceph_san_ser_type_size(__buffer, __t) \
- (__builtin_choose_expr(sizeof(__t) == 1, \
- (*(uint8_t *)(__buffer) = (uint8_t)(__t)), \
- __builtin_choose_expr(sizeof(__t) == 2, \
- (*(uint16_t *)(__buffer) = (uint16_t)(__t)), \
- __builtin_choose_expr(sizeof(__t) == 4, \
- (*(uint32_t *)(__buffer) = (uint32_t)(__t)), \
- __builtin_choose_expr(sizeof(__t) == 8, \
- (*(uint64_t *)(__buffer) = (uint64_t)(__t)), \
- (*(typeof(__t) *)(__buffer) = (__t)) \
- )))))
-
-#define __ceph_san_ser_type_memcpy(__buffer, __t) \
- (__builtin_memcpy(__buffer, &(__t), sizeof(__t)), \
- __buffer = (void *)((char *)__buffer + sizeof(__t)))
-
-#define __suppress_cast_warning(type, value) \
- _Pragma("GCC diagnostic push") \
- _Pragma("GCC diagnostic ignored \"-Wint-to-pointer-cast\"") \
- _Pragma("GCC diagnostic ignored \"-Wpointer-to-int-cast\"") \
- ((type)(value)) \
- _Pragma("GCC diagnostic pop")
+#define IS_STATIC_CHAR_ARRAY(t) \
+ (__builtin_classify_type(t) == 5 && \
+ __builtin_types_compatible_p(typeof(t), char[]) && \
+ __builtin_constant_p(t))
-#define __ceph_san_ser_type_no_arr(__buffer, __t) \
- (__builtin_choose_expr(sizeof(__t) == 1, \
- (*(uint8_t *)(__buffer) = __suppress_cast_warning(uint8_t, __t)), \
- __builtin_choose_expr(sizeof(__t) == 2, \
- (*(uint16_t *)(__buffer) = __suppress_cast_warning(uint16_t, __t)), \
- __builtin_choose_expr(sizeof(__t) == 4, \
- (*(uint32_t *)(__buffer) = __suppress_cast_warning(uint32_t, __t)), \
- __builtin_choose_expr(sizeof(__t) == 8, \
- (*(uint64_t *)(__buffer) = __suppress_cast_warning(uint64_t, __t)), \
- (*(typeof(__t) *)(__buffer) = __suppress_cast_warning(typeof(__t), __t)) \
- )))))
+#define IS_DYNAMIC_CHAR_ARRAY(t) \
+ (__builtin_classify_type(t) == 5 && \
+ __builtin_types_compatible_p(typeof(t), char[]) && \
+ !__builtin_constant_p(t))
#define __ceph_san_ser_type(__buffer, __t) \
- (__builtin_choose_expr(__builtin_classify_type(__t) == 14, \
- memcpy((__buffer), __suppress_cast_warning(void *, __t), sizeof(__t)), \
+ (__builtin_choose_expr(IS_STATIC_CHAR_ARRAY(__t), \
+ /* For static arrays (like __func__), just save pointer */ \
+ (*(void **)(__buffer) = __suppress_cast_warning(void *, __t), \
+ (__buffer) = (void *)((char *)(__buffer) + sizeof(void *))), \
+ __builtin_choose_expr(IS_DYNAMIC_CHAR_ARRAY(__t), \
+ /* For dynamic arrays, save NULL and string bytes */ \
+ (*(void **)(__buffer) = NULL, \
+ (__buffer) = (void *)((char *)(__buffer) + sizeof(void *)), \
+ memcpy((__buffer), __suppress_cast_warning(char *, __t), strlen(__suppress_cast_warning(char *, __t)) + 1), \
+ (__buffer) = (void *)((char *)(__buffer) + strlen(__suppress_cast_warning(char *, __t)) + 1)), \
__builtin_choose_expr(sizeof(__t) == 1, \
- (*(uint8_t *)(__buffer) = __suppress_cast_warning(uint8_t, __t)), \
+ (*(uint8_t *)(__buffer) = __suppress_cast_warning(uint8_t, __t), \
+ (__buffer) = (void *)((char *)(__buffer) + 1)), \
__builtin_choose_expr(sizeof(__t) == 2, \
- (*(uint16_t *)(__buffer) = __suppress_cast_warning(uint16_t, __t)), \
+ (*(uint16_t *)(__buffer) = __suppress_cast_warning(uint16_t, __t), \
+ (__buffer) = (void *)((char *)(__buffer) + 2)), \
__builtin_choose_expr(sizeof(__t) == 4, \
- (*(uint32_t *)(__buffer) = __suppress_cast_warning(uint32_t, __t)), \
+ (*(uint32_t *)(__buffer) = __suppress_cast_warning(uint32_t, __t), \
+ (__buffer) = (void *)((char *)(__buffer) + 4)), \
__builtin_choose_expr(sizeof(__t) == 8, \
- (*(uint64_t *)(__buffer) = __suppress_cast_warning(uint64_t, __t)), \
- ((void)0 ) \
- ))))))
+ (*(uint64_t *)(__buffer) = __suppress_cast_warning(uint64_t, __t), \
+ (__buffer) = (void *)((char *)(__buffer) + 8)), \
+ ((void)0) \
+ )))))))
-#define __ceph_san_ser(__buffer, __t) (__ceph_san_ser_type(__buffer, __t), __buffer = (void*)((typeof(__t)*)__buffer + 1))
#define ___ceph_san_ser0(__buffer)
-#define ___ceph_san_ser1(__buffer, __t) (__ceph_san_ser(__buffer, __t))
-#define ___ceph_san_ser2(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser1(__buffer, __args))
-#define ___ceph_san_ser3(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser2(__buffer, __args))
-#define ___ceph_san_ser4(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser3(__buffer, __args))
-#define ___ceph_san_ser5(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser4(__buffer, __args))
-#define ___ceph_san_ser6(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser5(__buffer, __args))
-#define ___ceph_san_ser7(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser6(__buffer, __args))
-#define ___ceph_san_ser8(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser7(__buffer, __args))
-#define ___ceph_san_ser9(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser8(__buffer, __args))
-#define ___ceph_san_ser10(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser9(__buffer, __args))
-#define ___ceph_san_ser11(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser10(__buffer, __args))
-#define ___ceph_san_ser12(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser11(__buffer, __args))
-#define ___ceph_san_ser13(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser12(__buffer, __args))
-#define ___ceph_san_ser14(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser13(__buffer, __args))
-#define ___ceph_san_ser15(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser14(__buffer, __args))
-#define ___ceph_san_ser16(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser15(__buffer, __args))
-#define ___ceph_san_ser17(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser16(__buffer, __args))
-#define ___ceph_san_ser18(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser17(__buffer, __args))
-#define ___ceph_san_ser19(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser18(__buffer, __args))
-#define ___ceph_san_ser20(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser19(__buffer, __args))
-#define ___ceph_san_ser21(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser20(__buffer, __args))
-#define ___ceph_san_ser22(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser21(__buffer, __args))
-#define ___ceph_san_ser23(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser22(__buffer, __args))
-#define ___ceph_san_ser24(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser23(__buffer, __args))
-#define ___ceph_san_ser25(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser24(__buffer, __args))
-#define ___ceph_san_ser26(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser25(__buffer, __args))
-#define ___ceph_san_ser27(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser26(__buffer, __args))
-#define ___ceph_san_ser28(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser27(__buffer, __args))
-#define ___ceph_san_ser29(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser28(__buffer, __args))
-#define ___ceph_san_ser30(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser29(__buffer, __args))
-#define ___ceph_san_ser31(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser30(__buffer, __args))
-#define ___ceph_san_ser32(__buffer, __t, __args...) (__ceph_san_ser(__buffer, __t), ___ceph_san_ser31(__buffer, __args))
+#define ___ceph_san_ser1(__buffer, __t) (__ceph_san_ser_type(__buffer, __t))
+#define ___ceph_san_ser2(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser1(__buffer, __args))
+#define ___ceph_san_ser3(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser2(__buffer, __args))
+#define ___ceph_san_ser4(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser3(__buffer, __args))
+#define ___ceph_san_ser5(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser4(__buffer, __args))
+#define ___ceph_san_ser6(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser5(__buffer, __args))
+#define ___ceph_san_ser7(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser6(__buffer, __args))
+#define ___ceph_san_ser8(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser7(__buffer, __args))
+#define ___ceph_san_ser9(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser8(__buffer, __args))
+#define ___ceph_san_ser10(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser9(__buffer, __args))
+#define ___ceph_san_ser11(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser10(__buffer, __args))
+#define ___ceph_san_ser12(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser11(__buffer, __args))
+#define ___ceph_san_ser13(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser12(__buffer, __args))
+#define ___ceph_san_ser14(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser13(__buffer, __args))
+#define ___ceph_san_ser15(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser14(__buffer, __args))
+#define ___ceph_san_ser16(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser15(__buffer, __args))
+#define ___ceph_san_ser17(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser16(__buffer, __args))
+#define ___ceph_san_ser18(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser17(__buffer, __args))
+#define ___ceph_san_ser19(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser18(__buffer, __args))
+#define ___ceph_san_ser20(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser19(__buffer, __args))
+#define ___ceph_san_ser21(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser20(__buffer, __args))
+#define ___ceph_san_ser22(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser21(__buffer, __args))
+#define ___ceph_san_ser23(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser22(__buffer, __args))
+#define ___ceph_san_ser24(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser23(__buffer, __args))
+#define ___ceph_san_ser25(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser24(__buffer, __args))
+#define ___ceph_san_ser26(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser25(__buffer, __args))
+#define ___ceph_san_ser27(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser26(__buffer, __args))
+#define ___ceph_san_ser28(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser27(__buffer, __args))
+#define ___ceph_san_ser29(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser28(__buffer, __args))
+#define ___ceph_san_ser30(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser29(__buffer, __args))
+#define ___ceph_san_ser31(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser30(__buffer, __args))
+#define ___ceph_san_ser32(__buffer, __t, __args...) (__ceph_san_ser_type(__buffer, __t), ___ceph_san_ser31(__buffer, __args))
#define ___ceph_san_ser(__buffer, ...) ___ceph_san_apply(___ceph_san_ser, ceph_san_narg(__VA_ARGS__))(__buffer, ##__VA_ARGS__)
#define ceph_san_ser(...) ___ceph_san_ser(__VA_ARGS__)