From: Mathieu Desnoyers Date: Fri, 24 Nov 2023 20:14:06 +0000 (-0500) Subject: Document ABI extensibility schemes X-Git-Url: http://git.efficios.com/?p=libside.git;a=commitdiff_plain;h=35e4f870db53745e7c259e0270ebc746f93d6f8a Document ABI extensibility schemes Signed-off-by: Mathieu Desnoyers --- diff --git a/include/side/abi/attribute.h b/include/side/abi/attribute.h index 7bc9e9d..e8dcce6 100644 --- a/include/side/abi/attribute.h +++ b/include/side/abi/attribute.h @@ -12,6 +12,33 @@ #include +/* + * SIDE ABI for description of event and type attributes. + * Event and type attributes are an optional array of { key, value } + * pairs which can be associated with either an event or a type. + * + * The extensibility scheme for the SIDE ABI for description of event + * and type attributes is as follows: + * + * * Existing attribute types are never changed nor extended. Attribute + * types can be added to the ABI by reserving a label within + * enum side_attr_type. + * * Each union part of the ABI has an explicit size defined by a + * side_padding() member. Each structure and union have a static + * assert validating its size. + * * Changing the semantic of the existing attribute type fields is a + * breaking ABI change. + * + * Handling of unknown attribute types by the tracers: + * + * * A tracer may choose to support only a subset of the types supported + * by libside. When encountering an unknown or unsupported attribute + * type, the tracer has the option to either disallow the entire + * event, skip over the field containing the unknown attribute, or + * skip over the unknown attribute, both at event registration and + * when receiving the side_call arguments. + */ + enum side_attr_type { SIDE_ATTR_TYPE_NULL, SIDE_ATTR_TYPE_BOOL, diff --git a/include/side/abi/event-description.h b/include/side/abi/event-description.h index c72a959..a978436 100644 --- a/include/side/abi/event-description.h +++ b/include/side/abi/event-description.h @@ -10,6 +10,21 @@ #include #include +/* + * SIDE ABI event description. + * + * The extensibility scheme for the SIDE ABI event description is as + * follows: + * + * * Changing the semantic of the existing event description fields is a + * breaking ABI change: the SIDE_EVENT_DESCRIPTION_ABI_VERSION should + * be increased to reflect this. + * + * * Event descriptions can be extended by adding fields at the end of + * the structure. The "struct side_event_description" is a structure + * with flexible size which must not be used within arrays. + */ + #define SIDE_EVENT_DESCRIPTION_ABI_VERSION 0 enum side_event_flags { diff --git a/include/side/abi/type-argument.h b/include/side/abi/type-argument.h index 9d0f0cb..06a4b0b 100644 --- a/include/side/abi/type-argument.h +++ b/include/side/abi/type-argument.h @@ -15,6 +15,30 @@ #include #include +/* + * SIDE ABI for arguments passed to instrumentation call site. + * + * The extensibility scheme for the SIDE ABI for call site arguments is + * as follows: + * + * * Existing argument types are never changed nor extended. Argument + * types can be added to the ABI by reserving a label within + * enum side_type_label. + * * Each union part of the ABI has an explicit size defined by a + * side_padding() member. Each structure and union have a static + * assert validating its size. + * * Changing the semantic of the existing argument type fields is a + * breaking ABI change. + * + * Handling of unknown argument types by the tracers: + * + * * A tracer may choose to support only a subset of the types supported + * by libside. When encountering an unknown or unsupported type, the + * tracer has the option to either disallow the entire event or skip + * over the unknown type, both at event registration and when + * receiving the side_call arguments. + */ + #if (SIDE_BYTE_ORDER == SIDE_LITTLE_ENDIAN) # define SIDE_TYPE_BYTE_ORDER_HOST SIDE_TYPE_BYTE_ORDER_LE #else diff --git a/include/side/abi/type-description.h b/include/side/abi/type-description.h index 47056ba..e76fbe2 100644 --- a/include/side/abi/type-description.h +++ b/include/side/abi/type-description.h @@ -14,6 +14,74 @@ #include #include +/* + * SIDE ABI for type description. + * + * This instrumentation ABI exposes 3 type systems: + * + * * Stack-copy type system: This is the core type system which can + * represent all supported types and into which all other type systems + * can be nested. This type system requires that every type is + * statically or dynamically declared and then registered, thus giving + * tracers a complete description of the events and their associated + * fields before the associated instrumentation is invoked. The + * application needs to copy each argument (side_arg_...()) onto the + * stack when calling the instrumentation. + * + * This is the most expressive of the 3 type systems, althrough not the + * fastest due to the extra copy of the arguments. + * + * * Data-gathering type system: This type system requires every type to + * be statically or dynamically declared and registered, but does not + * require the application to copy its arguments onto the stack. + * Instead, the type description contains all the required information + * to fetch the data from the application memory. The only argument + * required from the instrumentation is the base pointer from which + * the data should be fetched. + * + * This type system can be used as an event field, or nested within + * the stack-copy type system. Nesting of gather-vla within + * gather-array and gather-vla types is not allowed. + * + * This type system is has the least overhead of the 3 type systems. + * + * * Dynamic type system: This type system receives both type + * description and actual data onto the stack at runtime. It has more + * overhead that the 2 other type systems, but does not require a + * prior registration of event field description. This makes it useful + * for seldom used types which are not performance critical, but for + * which registering each individual events would needlessly grow the + * number of events to declare and register. + * + * Another use-case for this type system is for use by dynamically + * typed language runtimes, where the field type is only known when + * the instrumentation is called. + * + * Those dynamic types can be either used as arguments to a variadic + * field list, or as on-stack instrumentation argument for a static + * type SIDE_TYPE_DYNAMIC place holder in the stack-copy type system. + * + * The extensibility scheme for the SIDE ABI for type description is as + * follows: + * + * * Existing field types are never changed nor extended. Field types + * can be added to the ABI by reserving a label within + * enum side_type_label. + * * Each union part of the ABI has an explicit size defined by a + * side_padding() member. Each structure and union have a static + * assert validating its size. + * * Changing the semantic of the existing type fields is a breaking + * ABI change. + * + * Handling of unknown types by the tracers: + * + * * A tracer may choose to support only a subset of the types supported + * by libside. When encountering an unknown or unsupported type, the + * tracer has the option to either disallow the entire event or skip + * over the unknown type, both at event registration and when + * receiving the side_call arguments. + */ + enum side_type_label { /* Stack-copy basic types */ SIDE_TYPE_NULL, diff --git a/include/side/abi/type-value.h b/include/side/abi/type-value.h index 9d489ef..d445e26 100644 --- a/include/side/abi/type-value.h +++ b/include/side/abi/type-value.h @@ -10,6 +10,30 @@ #include #include +/* + * SIDE ABI for type values. + * + * The extensibility scheme for the SIDE ABI for type values is as + * follows: + * + * * Existing type values are never changed nor extended. Type values + * can be added to the ABI by reserving a label within enum + * side_type_label. + * * Each union part of the ABI has an explicit size defined by a + * side_padding() member. Each structure and union have a static + * assert validating its size. + * * Changing the semantic of the existing type value fields is a + * breaking ABI change. + * + * Handling of unknown type values by the tracers: + * + * * A tracer may choose to support only a subset of the type values + * supported by libside. When encountering an unknown or unsupported + * type value, the tracer has the option to either disallow the entire + * event or skip over the unknown type, both at event registration and + * when receiving the side_call arguments. + */ + enum side_type_label_byte_order { SIDE_TYPE_BYTE_ORDER_LE = 0, SIDE_TYPE_BYTE_ORDER_BE = 1, diff --git a/include/side/abi/visitor.h b/include/side/abi/visitor.h index b79dffc..10069ea 100644 --- a/include/side/abi/visitor.h +++ b/include/side/abi/visitor.h @@ -10,12 +10,24 @@ #include #include +/* + * SIDE ABI for visitor pattern. + * + * The visitor pattern is a double-dispatch visitor. Changing this ABI + * is a breaking ABI change. + * + * This ABI is a contract between the instrumented application and + * user-space tracers. Kernel tracers are not expected to interact with + * visitors directly: a proxy in libside should execute visitors to + * convert their output to other types which can be read by the kernel + * tracers. + */ + struct side_arg; struct side_arg_dynamic_field; struct side_tracer_visitor_ctx; struct side_tracer_dynamic_struct_visitor_ctx; -/* The visitor pattern is a double-dispatch visitor. */ typedef enum side_visitor_status (*side_write_elem_func)( const struct side_tracer_visitor_ctx *tracer_ctx, diff --git a/include/side/trace.h b/include/side/trace.h index 25ec2aa..70cb5e9 100644 --- a/include/side/trace.h +++ b/include/side/trace.h @@ -23,81 +23,15 @@ * instrumentation type system and facilities allowing a kernel or * user-space tracer to consume user-space instrumentation. * - * This instrumentation ABI exposes 3 type systems: + * The extensibility scheme for the SIDE ABI for event state is as + * follows: * - * * Stack-copy type system: This is the core type system which can - * represent all supported types and into which all other type systems - * can be nested. This type system requires that every type is - * statically or dynamically declared and then registered, thus giving - * tracers a complete description of the events and their associated - * fields before the associated instrumentation is invoked. The - * application needs to copy each argument (side_arg_...()) onto the - * stack when calling the instrumentation. - * - * This is the most expressive of the 3 type systems, althrough not the - * fastest due to the extra copy of the arguments. - * - * * Data-gathering type system: This type system requires every type to - * be statically or dynamically declared and registered, but does not - * require the application to copy its arguments onto the stack. - * Instead, the type description contains all the required information - * to fetch the data from the application memory. The only argument - * required from the instrumentation is the base pointer from which - * the data should be fetched. - * - * This type system can be used as an event field, or nested within - * the stack-copy type system. Nesting of gather-vla within - * gather-array and gather-vla types is not allowed. - * - * This type system is has the least overhead of the 3 type systems. - * - * * Dynamic type system: This type system receives both type - * description and actual data onto the stack at runtime. It has more - * overhead that the 2 other type systems, but does not require a - * prior registration of event field description. This makes it useful - * for seldom used types which are not performance critical, but for - * which registering each individual events would needlessly grow the - * number of events to declare and register. - * - * Another use-case for this type system is for use by dynamically - * typed language runtimes, where the field type is only known when - * the instrumentation is called. - * - * Those dynamic types can be either used as arguments to a variadic - * field list, or as on-stack instrumentation argument for a static - * type SIDE_TYPE_DYNAMIC place holder in the stack-copy type system. - * - * The extensibility scheme for the SIDE ABI is as follows: - * - * * Existing field types are never changed nor extended. Field types - * can be added to the ABI by reserving a label within - * enum side_type_label. - * * Existing attribute types are never changed nor extended. Attribute - * types can be added to the ABI by reserving a label within - * enum side_attr_type. - * * Each union part of the ABI has an explicit size defined by a - * side_padding() member. Each structure and union have a static - * assert validating its size. - * * If the semantic of the existing event description or type fields - * change, the SIDE_EVENT_DESCRIPTION_ABI_VERSION should be increased. * * If the semantic of the "struct side_event_state_N" fields change, * the SIDE_EVENT_STATE_ABI_VERSION should be increased. The * "struct side_event_state_N" is not extensible and must have its * ABI version increased whenever it is changed. Note that increasing * the version of SIDE_EVENT_DESCRIPTION_ABI_VERSION is not necessary * when changing the layout of "struct side_event_state_N". - * - * Handling of unknown types by the tracers: - * - * * A tracer may choose to support only a subset of the types supported - * by libside. When encountering an unknown or unsupported type, the - * tracer has the option to either disallow the entire event or skip - * over the unknown type, both at event registration and when - * receiving the side_call arguments. - * - * * Event descriptions can be extended by adding fields at the end of - * the structure. The "struct side_event_description" is a structure - * with flexible size which must not be used within arrays. */ #define SIDE_EVENT_STATE_ABI_VERSION 0