[PATCH v6 52/57] dyndbg: add DEFINE_DYNAMIC_DEBUG_TABLE, use it tacitly RFC

From: Jim Cromie
Date: Sun Sep 04 2022 - 17:46:37 EST


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