This defines a new macro (tbd: tweak name) which is a special version of DEFINE_DYNAMIC_DEBUG_METADATA_CLS(). Unlike that macro, which declares callsites in pairs of desc/site recs. This macro declares a pair of header records, which the linker script then places once (.gnu.linkonce.) into the front of the respective sections. For builtins, the .linkonce gives us a single header preceding all ~3-5k callsites. It uses __unused, __weak, .gnu.linkonce to avoid trouble with multiple inclusions, and should not consume space when not linked to by a callsite in a loadable module. Atypically, this macro is also tacitly invoked in the header, which is indirectly included by printk.h. This means 2 things: it mostly insures that source files will declare it at least once, and that multiple decls resolve to the identical storage address. I did this with the expectation that I could let the linker compute the offset and initialize ._index accordingly, but that resulted in some "linker cant compute" error. Ive initialized it in __ddebug_add_module() instead. Signed-off-by: Jim Cromie <jim.cromie@xxxxxxxxx> --- include/linux/dynamic_debug.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/include/linux/dynamic_debug.h b/include/linux/dynamic_debug.h index f23608c38a79..23d3d2882882 100644 --- a/include/linux/dynamic_debug.h +++ b/include/linux/dynamic_debug.h @@ -220,6 +220,32 @@ void __dynamic_ibdev_dbg(struct _ddebug *descriptor, #define DEFINE_DYNAMIC_DEBUG_METADATA(name, fmt) \ DEFINE_DYNAMIC_DEBUG_METADATA_CLS(name, _DPRINTK_CLASS_DFLT, fmt) +/* + * DEFINE_DYNAMIC_DEBUG_TABLE(): This is a special version of + * DEFINE_DYNAMIC_DEBUG_METADATA(). It creates a single pair of + * header records, which the linker scripts place in front of their + * respective sections. + * + * To allow for a robust runtime test in dynamic_debug_init(), the + * pair of records is hardwired into a self-reference loop which can + * be validated before the field is altered to support _ddebug_map_site() + */ +#define DEFINE_DYNAMIC_DEBUG_TABLE() \ + /* forward decl, allowing loopback pointer */ \ + struct _ddebug_hdr __used __aligned(8) \ + __section(".gnu.linkonce.dyndbg") \ + _LINKONCE_dyndbg_header; \ + struct _ddebug_site_hdr __used __aligned(8) \ + __section(".gnu.linkonce.dyndbg_site") \ + _LINKONCE_dyndbg_site_header = { \ + ._uplink = (void *) &_LINKONCE_dyndbg_header \ + }; \ + struct _ddebug_hdr __used __aligned(8) \ + __section(".gnu.linkonce.dyndbg") \ + _LINKONCE_dyndbg_header = { \ + ._uplink = (void *) &_LINKONCE_dyndbg_site_header \ + } + #ifdef CONFIG_JUMP_LABEL #ifdef DEBUG @@ -390,4 +416,12 @@ static inline int param_get_dyndbg_classes(char *buffer, const struct kernel_par extern const struct kernel_param_ops param_ops_dyndbg_classes; +#if ((defined(CONFIG_DYNAMIC_DEBUG) || \ + (defined(CONFIG_DYNAMIC_DEBUG_CORE) && defined(DYNAMIC_DEBUG_MODULE))) \ + && defined(KBUILD_MODNAME) && !defined(NO_DYNAMIC_DEBUG_TABLE)) + +/* transparently invoked, except when -DNO_DYNAMIC_DEBUG_TABLE */ +DEFINE_DYNAMIC_DEBUG_TABLE(); +#endif + #endif -- 2.37.2