[PATCH v5 03/11] libdtrace: avoid BTF probes for ranged built-in modules

Alan Maguire <[email protected]>
Newsgroups dev.linux.lists.dtrace
Message-ID <[email protected]>
When /proc/kallsyms is used with modules.builtin.ranges, libdtrace can
attribute symbols linked into vmlinux to their individual built-in objects,
such as bitrev or atomic64_test.  This creates module objects for those
names.

These objects have no per-module BTF file under /sys/kernel/btf.  Avoid
probing for one when modules.builtin.ranges has identified the module as
built in, and use the shared vmlinux BTF directly instead.

Keep the existing lookup path for loadable modules and for an explicitly
configured BTF directory.

Signed-off-by: Alan Maguire <[email protected]>
---
 libdtrace/dt_btf.c    |  8 ++++++--
 libdtrace/dt_impl.h   |  1 +
 libdtrace/dt_module.c | 20 +++++++++++++++++++-
 3 files changed, 26 insertions(+), 3 deletions(-)

diff --git a/libdtrace/dt_btf.c b/libdtrace/dt_btf.c
index e7980969..93ecf5cd 100644
--- a/libdtrace/dt_btf.c
+++ b/libdtrace/dt_btf.c
@@ -915,8 +915,12 @@ dt_btf_module_ctf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 	if (!dtp->dt_shared_ctf && dtp->dt_shared_btf && btf == dtp->dt_shared_btf)
 		dtp->dt_shared_ctf = ctf;
 
-	dt_dprintf("Generated %s CTF from BTF (%d types).\n", dmp->dm_name,
-		   btf->type_cnt);
+	if (btf == dtp->dt_shared_btf && strcmp(dmp->dm_name, "vmlinux") != 0)
+		dt_dprintf("Created %s CTF import from shared vmlinux BTF.\n",
+		    dmp->dm_name);
+	else
+		dt_dprintf("Generated %s CTF from BTF (%d types).\n", dmp->dm_name,
+		    btf->type_cnt);
 #endif
 
 	return ctf;
diff --git a/libdtrace/dt_impl.h b/libdtrace/dt_impl.h
index 7ccdc271..38c5ff0b 100644
--- a/libdtrace/dt_impl.h
+++ b/libdtrace/dt_impl.h
@@ -201,6 +201,7 @@ typedef struct dt_kern_path {
 #define DT_DM_KERNEL		0x2	/* module is associated with a kernel object */
 #define DT_DM_CTF_ARCHIVED	0x4	/* module found in a CTF archive */
 #define DT_DM_KERN_UNLOADED	0x8	/* module not loaded into the kernel */
+#define DT_DM_KERN_BUILTIN	0x10	/* module is linked into vmlinux */
 
 /*
  * Why do we need (only) 4 slots?  The maximum amount of string arguments to
diff --git a/libdtrace/dt_module.c b/libdtrace/dt_module.c
index 00978911..ea6d56c3 100644
--- a/libdtrace/dt_module.c
+++ b/libdtrace/dt_module.c
@@ -871,6 +871,19 @@ dt_kern_module_find_btf(dtrace_hdl_t *dtp, dt_module_t *dmp)
 	if (dtp->dt_shared_btf == NULL && strcmp(dmp->dm_name, "vmlinux") != 0)
 		return;
 
+	/*
+	 * modules.builtin.ranges identifies this object as linked into vmlinux.
+	 * Such objects cannot have a per-module BTF object, so use the shared
+	 * vmlinux BTF directly.  Retain the usual lookup for an explicitly
+	 * configured BTF directory and every other module.
+	 */
+	if (dtp->dt_btf_path == NULL && (dmp->dm_flags & DT_DM_KERN_BUILTIN)) {
+		dmp->dm_btf = dtp->dt_shared_btf;
+		dt_dprintf("Using shared vmlinux BTF for built-in module %s.\n",
+		    dmp->dm_name);
+		return;
+	}
+
 	dt_dprintf("Loading BTF for module %s.\n", dmp->dm_name);
 
 	/*
@@ -1405,6 +1418,7 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state)
 {
 	dt_kallsym_t	sym;
 	char		*modname;
+	int		builtin = 0;
 
 	if ((line[0] == '\n') || (line[0] == 0))
 		return 0;
@@ -1440,8 +1454,10 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state)
 			char	*s;
 
 			s = dt_kasstate_modname(state, sym.addr, sym.name);
-			if (s != NULL)
+			if (s != NULL) {
 				strncpy(sym.mod, s, PATH_MAX);
+				builtin = 1;
+			}
 		}
 	}
 
@@ -1511,6 +1527,8 @@ dt_modsym_update(dtrace_hdl_t *dtp, const char *line, dt_kasstate_t *state)
 			if (err != 0)
 				return err;
 		}
+		if (builtin)
+			dmp->dm_flags |= DT_DM_KERN_BUILTIN;
 
 		err = dt_modsym_addsym(dtp, dmp, &sym, state);
 		if (err != 0)
-- 
2.43.5
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.