[PATCH 3/5] pahole: Honour exclusive BTF loading

Arnaldo Carvalho de Melo
2024-11-19T13:40:57Z

From: Arnaldo Carvalho de Melo <acme@redhat.com>

When we specify 'btf' and BTF info is available in the system, in the
/sys/kernel/btf/vmlinux file, pahole will find it and use it to get the
type information asked for:

root@x1:~# perf trace -o /tmp/output -e openat pahole -F btf list_head ; tail -1 /tmp/output
struct list_head {
struct list_head * next; /* 0 8 */
struct list_head * prev; /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* last cacheline: 16 bytes */
};

1.579 ( 0.010 ms): pahole/764777 openat(dfd: CWD, filename: "/sys/kernel/btf/vmlinux", flags: RDONLY|CLOEXEC) = 3
root@x1:~#

But, if the system doesn't have BTF info, which we now can simulate by using an
environment variable it is tryng DWARF after failing for BTF, which isn't what
the user asked for having specified just btf in the -F pahole command line:

root@x1:~# export PAHOLE_VMLINUX_BTF_FILENAME=non-existent
root@x1:~# perf trace -o /tmp/output -e openat,access pahole -F btf list_head ; tail -12 /tmp/output
struct list_head {
struct list_head * next; /* 0 8 */
struct list_head * prev; /* 8 8 */

/* size: 16, cachelines: 1, members: 2 */
/* last cacheline: 16 bytes */
};

1.643 ( 0.003 ms): pahole/765220 access(filename: "list_head", mode: R) = -1 ENOENT (No such file or directory)
1.658 ( 0.002 ms): pahole/765220 access(filename: "non-existent", mode: R) = -1 ENOENT (No such file or directory)
1.697 ( 0.018 ms): pahole/765220 openat(dfd: CWD, filename: "/sys/kernel/notes") = 3
1.801 ( 0.004 ms): pahole/765220 openat(dfd: CWD, filename: "vmlinux") = -1 ENOENT (No such file or directory)
1.807 ( 0.005 ms): pahole/765220 openat(dfd: CWD, filename: "/boot/vmlinux") = -1 ENOENT (No such file or directory)
1.927 ( 0.005 ms): pahole/765220 openat(dfd: CWD, filename: "/usr/lib/debug/lib/modules/6.11.6-200.fc40.x86_64/vmlinux", flags: RDONLY|CLOEXEC) = 3
root@x1:~#

So honour the request and fails when just BTF is asked and no BTF file is
found:

# export PAHOLE_VMLINUX_BTF_FILENAME=non-existent
# pahole -F btf list_head
pahole: couldn't find any btf debug information on this system.
#

Reported-by: Matthias Schwarzott <zzam@gentoo.org>
Cc: Alan Maguire <alan.maguire@oracle.com>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Song Liu <song@kernel.org>
Cc: Yonghong Song <yonghong.song@linux.dev>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
dwarves.c | 15 +++++++++++++--
pahole.c | 9 ++++++++-
2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/dwarves.c b/dwarves.c
index 5b51b55191177e21..459311e64c8b45b2 100644
--- a/dwarves.c
+++ b/dwarves.c
@@ -2944,9 +2944,17 @@ const char *vmlinux_path__find_running_kernel(void)
static int cus__load_running_kernel(struct cus *cus, struct conf_load *conf)
{
int err = 0;
+ bool btf_only = false;

- if ((!conf || conf->format_path == NULL || strncmp(conf->format_path, "btf", 3) == 0) &&
- access(vmlinux_path__btf_filename(), R_OK) == 0) {
+ if (!conf || conf->format_path == NULL)
+ goto try_btf;
+
+ if (!strstr(conf->format_path, "btf"))
+ goto try_elf;
+
+ btf_only = strcmp(conf->format_path, "btf") == 0;
+try_btf:
+ if (access(vmlinux_path__btf_filename(), R_OK) == 0) {
int loader = debugging_formats__loader("btf");
if (loader == -1)
goto try_elf;
@@ -2958,6 +2966,9 @@ static int cus__load_running_kernel(struct cus *cus, struct conf_load *conf)
return 0;
}
try_elf:
+ if (btf_only)
+ return -1;
+
elf_version(EV_CURRENT);
vmlinux_path__init();

diff --git a/pahole.c b/pahole.c
index b94cb1a979a6923d..fa5d8c707bd4717d 100644
--- a/pahole.c
+++ b/pahole.c
@@ -3782,7 +3782,14 @@ try_sole_arg_as_class_names:
remaining = argc;
goto try_sole_arg_as_class_names;
}
- cus__fprintf_load_files_err(cus, "pahole", argv + remaining, err, stderr);
+ if (argv[remaining] != NULL) {
+ cus__fprintf_load_files_err(cus, "pahole", argv + remaining, err, stderr);
+ } else {
+ fprintf(stderr, "pahole: couldn't find any%s%s debug information on this system.\n",
+ conf_load.format_path ? " " : "",
+ conf_load.format_path ?: "");
+ }
+
goto out_cus_delete;
}

--
2.47.0