From f9ef9246b7eec79e68b9c223bf6421da12263263 Mon Sep 17 00:00:00 2001 From: Olivier Dion Date: Tue, 6 Aug 2024 17:09:48 -0400 Subject: [PATCH] Add C native types macro helpers The SIDE ABI specifies fixed sizes integers and floating points. However, as a convenience for C/C++, the SIDE C API supports C native types (e.g. char) which are translated to their equivalent. Note that the translation of C native types is toolchain dependent and therefore could produce different results. The main use case is for auto-generating SIDE events for public API of shared libraries. Change-Id: I845f0dd42ba2dc2de1f540f751e9cd65aa4a8c98 Signed-off-by: Olivier Dion Signed-off-by: Mathieu Desnoyers --- include/side/instrumentation-c-api.h | 167 +++++++++++++++++++++++++++ tests/unit/c-native-types.h | 23 ++++ tests/unit/test.c | 28 +++++ 3 files changed, 218 insertions(+) create mode 100644 tests/unit/c-native-types.h diff --git a/include/side/instrumentation-c-api.h b/include/side/instrumentation-c-api.h index 1a9bf84..f57a44a 100644 --- a/include/side/instrumentation-c-api.h +++ b/include/side/instrumentation-c-api.h @@ -285,6 +285,173 @@ #define side_field_string32(_name, _attr...) _side_field(_name, side_type_string32(SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list()))) #define side_field_dynamic(_name) _side_field(_name, side_type_dynamic()) +/* C native types. */ + +/* + * The SIDE ABI specifies fixed sizes integers and floating points. However, as + * a convenience for C/C++, the SIDE C API supports C native types (e.g. char) + * which are translated to their equivalent. + * + * Note that the translation of C * native types is toolchain dependent and + * therefore could produce different * results. + * + * The main use case is for auto-generating SIDE events for public API of shared + * libraries. + */ + +#ifdef __CHAR_UNSIGNED__ +# define side_field_char(_name, _attr...) side_field_uchar(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_char(_args...) side_arg_uchar(_args) +#else +# define side_field_char(_name, _attr...) side_field_schar(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_char(_args...) side_arg_schar(_args) +#endif + +#define side_field_schar(_name, _attr...) side_field_s8(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +#define side_arg_schar(_args...) side_arg_s8(_args) + +#define side_field_uchar(_name, _attr...) side_field_u8(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +#define side_arg_uchar(_args...) side_arg_u8(_args) + +#if __SIZEOF_SHORT__ <= 2 +# define side_field_short(_name, _attr...) side_field_s16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_short(_args...) side_arg_s16(_args) +# define side_field_ushort(_name, _attr...) side_field_u16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ushort(_args...) side_arg_u16(_args) +#elif __SIZEOF_SHORT__ <= 4 +# define side_field_short(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_short(_args...) side_arg_s32(_args) +# define side_field_ushort(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ushort(_args...) side_arg_u32(_args) +#elif __SIZEOF_SHORT__ <= 8 +# define side_field_short(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_short(_args...) side_arg_s64(_args) +# define side_field_ushort(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ushort(_args...) side_arg_u64(_args) +#else +# define side_field_short(...) \ + side_static_assert(0, "Type `signed short int' is not supported", type__signed_short_int__is_not_supported) +# define side_arg_short(...) \ + side_static_assert(0, "Type `signed short int' is not supported", type__signed_short_int__is_not_supported) +# define side_field_ushort(...) \ + side_static_assert(0, "Type `unsigned short int' is not supported", type__unsigned_short_int__is_not_supported) +# define side_arg_ushort(...) \ + side_static_assert(0, "Type `unsigned short int' is not supported", type__unsigned_short_int__is_not_supported) +#endif + +#if __SIZEOF_INT__ <= 2 +# define side_field_int(_name, _attr...) side_field_s16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_int(_args...) side_arg_s16(_args) +# define side_field_uint(_name, _attr...) side_field_u16(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_uint(_args...) side_arg_u16(_args) +#elif __SIZEOF_INT__ <= 4 +# define side_field_int(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_int(_args...) side_arg_s32(_args) +# define side_field_uint(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_uint(_args...) side_arg_u32(_args) +#elif __SIZEOF_INT__ <= 8 +# define side_field_int(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_int(_args...) side_arg_s64(_args) +# define side_field_uint(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_uint(_args...) side_arg_u64(_args) +#else +# define side_field_int(...) \ + side_static_assert(0, "Type `signed int' is not supported", type__signed_int__is_not_supported) +# define side_arg_int(...) \ + side_static_assert(0, "Type `signed int' is not supported", type__signed_int__is_not_supported) +# define side_field_uint(...) \ + side_static_assert(0, "Type `unsigned int' is not supported", type__unsigned_int__is_not_supported) +# define side_arg_uint(...) \ + side_static_assert(0, "Type `unsigned int' is not supported", type__unsigned_int__is_not_supported) +#endif + +#if __SIZEOF_LONG__ <= 4 +# define side_field_long(_name, _attr...) side_field_s32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long(_args...) side_arg_s32(_args) +# define side_field_ulong(_name, _attr...) side_field_u32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ulong(_args...) side_arg_u32(_args) +#elif __SIZEOF_LONG__ <= 8 +# define side_field_long(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long(_args...) side_arg_s64(_args) +# define side_field_ulong(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ulong(_args...) side_arg_u64(_args) +#else +# define side_field_long(...) \ + side_static_assert(0, "Type `signed long int' is not supported", type__signed_long_int__is_not_supported) +# define side_arg_long(...) \ + side_static_assert(0, "Type `signed long int' is not supported", type__signed_long_int__is_not_supported) +# define side_field_ulong(...) \ + side_static_assert(0, "Type `unsigned long int' is not supported", type__unsigned_long_int__is_not_supported) +# define side_arg_ulong(...) \ + side_static_assert(0, "Type `unsigned long int' is not supported", type__unsigned_long_int__is_not_supported) +#endif + +#if __SIZEOF_LONG_LONG__ <= 8 +# define side_field_long_long(_name, _attr...) side_field_s64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long_long(_args...) side_arg_s64(_args) +# define side_field_ulong_long(_name, _attr...) side_field_u64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_ulong_long(_args...) side_arg_u64(_args) +#else +# define side_field_long_long(...) \ + side_static_assert(0, "Type `signed long long int' is not supported", type__signed_long_long_int__is_not_supported) +# define side_arg_long_long(...) \ + side_static_assert(0, "Type `signed long long int' is not supported", type__signed_long_long_int__is_not_supported) +# define side_field_long_long(...) \ + side_static_assert(0, "Type `unsigned long long int' is not supported", type__unsigned_long_long_int__is_not_supported) +# define side_arg_long_long(...) \ + side_static_assert(0, "Type `unsigned long long int' is not supported", type__unsigned_long_long_int__is_not_supported) +#endif + +#if __SIZEOF_FLOAT__ <= 4 && __HAVE_FLOAT32 +# define side_field_float(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_float(_args...) side_arg_float_binary32(_args) +#elif __SIZEOF_FLOAT__ <= 8 && __HAVE_FLOAT64 +# define side_field_float(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_float(_args...) side_arg_float_binary64(_args) +#elif __SIZEOF_FLOAT__ <= 16 && __HAVE_FLOAT128 +# define side_field_float(_name, _attr...) side_field_float_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_float(_args...) side_arg_float_binary128(_args) +#else +# define side_field_float(...) \ + side_static_assert(0, "Type `float' is not supported", type__float__is_not_supported) +# define side_arg_float(...) \ + side_static_assert(0, "Type `float' is not supported", type__float__is_not_supported) +#endif + +#if __SIZEOF_DOUBLE__ <= 4 && __HAVE_FLOAT32 +# define side_field_double(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_double(_args...) side_arg_float_binary32(_args) +#elif __SIZEOF_DOUBLE__ <= 8 && __HAVE_FLOAT64 +# define side_field_double(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_double(_args...) side_arg_float_binary64(_args) +#elif __SIZEOF_DOUBLE__ <= 16 && __HAVE_FLOAT128 +# define side_field_double(_name, _attr...) side_field_double_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_double(_args...) side_arg_float_binary128(_args) +#else +# define side_field_double(...) \ + side_static_assert(0, "Type `double' is not supported", type__double__is_not_supported) +# define side_arg_double(...) \ + side_static_assert(0, "Type `double' is not supported", type__double__is_not_supported) +#endif + +#ifdef __SIZEOF_LONG_DOUBLE__ +# if __SIZEOF_LONG_DOUBLE__ <= 4 && __HAVE_FLOAT32 +# define side_field_long_double(_name, _attr...) side_field_float_binary32(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long_double(_args...) side_arg_float_binary32(_args) +# elif __SIZEOF_LONG_DOUBLE__ <= 8 && __HAVE_FLOAT64 +# define side_field_long_double(_name, _attr...) side_field_float_binary64(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long_double(_args...) side_arg_float_binary64(_args) +# elif __SIZEOF_LONG_DOUBLE__ <= 16 && __HAVE_FLOAT128 +# define side_field_long_double(_name, _attr...) side_field_float_binary128(_name, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) +# define side_arg_long_double(_args...) side_arg_float_binary128(_args) +# else +# define side_field_long_double(...) \ + side_static_assert(0, "Type `long double' is not supported", type__long_double__is_not_supported) +# define side_arg_long_double(...) \ + side_static_assert(0, "Type `long double' is not supported", type__long_double__is_not_supported) +# endif +#endif /* __SIZEOF_LONG_DOUBLE__ */ + /* Little endian */ #define side_type_u16_le(_attr...) _side_type_integer(SIDE_TYPE_U16, false, SIDE_TYPE_BYTE_ORDER_LE, sizeof(uint16_t), 0, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) #define side_type_u32_le(_attr...) _side_type_integer(SIDE_TYPE_U32, false, SIDE_TYPE_BYTE_ORDER_LE, sizeof(uint32_t), 0, SIDE_PARAM_SELECT_ARG1(_, ##_attr, side_attr_list())) diff --git a/tests/unit/c-native-types.h b/tests/unit/c-native-types.h new file mode 100644 index 0000000..ad03e2c --- /dev/null +++ b/tests/unit/c-native-types.h @@ -0,0 +1,23 @@ +#include +#include + +/* + * Define X before including this file to expand to something. + */ +X(char, CHAR_MAX, char); +X(signed char, SCHAR_MIN, schar); +X(unsigned char, UCHAR_MAX, uchar); +X(short, SHRT_MIN, short); +X(unsigned short, USHRT_MAX, ushort); +X(int, INT_MIN, int); +X(unsigned int, UINT_MAX, uint); +X(long, LONG_MIN, long); +X(unsigned long, ULONG_MAX, ulong); +X(long long, LLONG_MIN, long_long); +X(unsigned long long, ULLONG_MAX, ulong_long); +X(float, FLT_MIN, float); +X(double, DBL_MIN, double); + +#ifdef __SIZEOF_LONG_DOUBLE__ +X(long double, LDBL_MIN, long_double); +#endif diff --git a/tests/unit/test.c b/tests/unit/test.c index e563d07..493d6e5 100644 --- a/tests/unit/test.c +++ b/tests/unit/test.c @@ -2262,6 +2262,33 @@ void test_integer128(void) #endif +#define X(_type, _value, _field) \ + side_static_event(c_native_types_ ## _field, "c-native-types", #_type, SIDE_LOGLEVEL_DEBUG, \ + side_field_list( \ + side_field_##_field("x"), \ + ) \ + ) +#include "c-native-types.h" +#undef X + +static +void test_c_native_types(void) +{ + +#define X(_type, _value, _field) \ + ({ \ + _type x = _value; \ + side_event(c_native_types_ ## _field, \ + side_arg_list( \ + side_arg_##_field(x), \ + ) \ + ); \ + }) +#include "c-native-types.h" +#undef X +} + + int main() { test_fields(); @@ -2315,5 +2342,6 @@ int main() test_string_utf(); test_variant(); test_integer128(); + test_c_native_types(); return 0; } -- 2.34.1