Skip to content

Commit

Permalink
bpftool: support displaying relocated-with-base split BTF
Browse files Browse the repository at this point in the history
If the -R <base_btf> option is used, we can display BTF that has been
generated with distilled base BTF in its relocated form.  For example
for bpf_testmod.ko (which is built as an out-of-tree module, so has
a distilled .BTF.base section:

bpftool btf dump file bpf_testmod.ko

Alternatively, we can display content relocated with
(a possibly changed) base BTF via

bpftool btf dump -R /sys/kernel/btf/vmlinux bpf_testmod.ko

The latter mirrors how the kernel will handle such split
BTF; it relocates its representation with the running
kernel, and if successful, renumbers BTF ids to reference
the current vmlinux BTF.

Signed-off-by: Alan Maguire <alan.maguire@oracle.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
  • Loading branch information
alan-maguire authored and Kernel Patches Daemon committed May 13, 2024
1 parent f5e22b5 commit 21b748e
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 6 deletions.
15 changes: 14 additions & 1 deletion tools/bpf/bpftool/Documentation/bpftool-btf.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ SYNOPSIS

**bpftool** [*OPTIONS*] **btf** *COMMAND*

*OPTIONS* := { |COMMON_OPTIONS| | { **-B** | **--base-btf** } }
*OPTIONS* := { |COMMON_OPTIONS| | { **-B** | **--base-btf** } { **-R** | **relocate-base-btf** } }

*COMMANDS* := { **dump** | **help** }

Expand Down Expand Up @@ -85,6 +85,19 @@ OPTIONS
BTF object is passed through other handles, this option becomes
necessary.

-R, --relocate-base-btf *FILE*
When split BTF is generated with distilled base BTF for relocation,
the latter is stored in a .BTF.base section and allows us to later
relocate split BTF and a potentially-changed base BTF by using
information in the .BTF.base section about the base types referenced
from split BTF. Relocation is carried out against the split BTF
supplied via this parameter and the split BTF will then refer to
the base types supplied in *FILE*.

If this option is not used, split BTF is shown relative to the
.BTF.base, which contains just enough information to support later
relocation.

EXAMPLES
========
**# bpftool btf dump id 1226**
Expand Down
7 changes: 4 additions & 3 deletions tools/bpf/bpftool/bash-completion/bpftool
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,7 @@ _bpftool()
# Deal with options
if [[ ${words[cword]} == -* ]]; then
local c='--version --json --pretty --bpffs --mapcompat --debug \
--use-loader --base-btf'
--use-loader --base-btf --relocate-base-btf'
COMPREPLY=( $( compgen -W "$c" -- "$cur" ) )
return 0
fi
Expand All @@ -283,7 +283,7 @@ _bpftool()
_sysfs_get_netdevs
return 0
;;
file|pinned|-B|--base-btf)
file|pinned|-B|-R|--base-btf|--relocate-base-btf)
_filedir
return 0
;;
Expand All @@ -297,7 +297,8 @@ _bpftool()
local i pprev
for (( i=1; i < ${#words[@]}; )); do
if [[ ${words[i]::1} == - ]] &&
[[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]]; then
[[ ${words[i]} != "-B" ]] && [[ ${words[i]} != "--base-btf" ]] &&
[[ ${words[i]} != "-R" ]] && [[ ${words[i]} != "--relocate-base-btf" ]]; then
words=( "${words[@]:0:i}" "${words[@]:i+1}" )
[[ $i -le $cword ]] && cword=$(( cword - 1 ))
else
Expand Down
11 changes: 10 additions & 1 deletion tools/bpf/bpftool/btf.c
Original file line number Diff line number Diff line change
Expand Up @@ -638,6 +638,14 @@ static int do_dump(int argc, char **argv)
base_btf = btf__parse_opts(*argv, &optp);
if (base_btf)
btf = btf__parse_split(*argv, base_btf);
if (btf && relocate_base_btf) {
err = btf__relocate(btf, relocate_base_btf);
if (err) {
p_err("could not relocate BTF from '%s' with base BTF '%s': %s\n",
*argv, relocate_base_btf_path, strerror(-err));
goto done;
}
}
}
if (!btf) {
err = -errno;
Expand Down Expand Up @@ -1075,7 +1083,8 @@ static int do_help(int argc, char **argv)
" " HELP_SPEC_MAP "\n"
" " HELP_SPEC_PROGRAM "\n"
" " HELP_SPEC_OPTIONS " |\n"
" {-B|--base-btf} }\n"
" {-B|--base-btf} |\n"
" {-R|--relocate-base-btf} }\n"
"",
bin_name, "btf");

Expand Down
14 changes: 13 additions & 1 deletion tools/bpf/bpftool/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ bool verifier_logs;
bool relaxed_maps;
bool use_loader;
struct btf *base_btf;
struct btf *relocate_base_btf;
const char *relocate_base_btf_path;
struct hashmap *refs_table;

static void __noreturn clean_and_exit(int i)
Expand Down Expand Up @@ -448,6 +450,7 @@ int main(int argc, char **argv)
{ "debug", no_argument, NULL, 'd' },
{ "use-loader", no_argument, NULL, 'L' },
{ "base-btf", required_argument, NULL, 'B' },
{ "relocate-base-btf", required_argument, NULL, 'R' },
{ 0 }
};
bool version_requested = false;
Expand All @@ -473,7 +476,7 @@ int main(int argc, char **argv)
bin_name = "bpftool";

opterr = 0;
while ((opt = getopt_long(argc, argv, "VhpjfLmndB:l",
while ((opt = getopt_long(argc, argv, "VhpjfLmndB:lR:",
options, NULL)) >= 0) {
switch (opt) {
case 'V':
Expand Down Expand Up @@ -519,6 +522,15 @@ int main(int argc, char **argv)
case 'L':
use_loader = true;
break;
case 'R':
relocate_base_btf_path = optarg;
relocate_base_btf = btf__parse(optarg, NULL);
if (!relocate_base_btf) {
p_err("failed to parse base BTF for relocation at '%s': %d\n",
optarg, -errno);
return -1;
}
break;
default:
p_err("unrecognized option '%s'", argv[optind - 1]);
if (json_output)
Expand Down
2 changes: 2 additions & 0 deletions tools/bpf/bpftool/main.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ extern bool verifier_logs;
extern bool relaxed_maps;
extern bool use_loader;
extern struct btf *base_btf;
extern struct btf *relocate_base_btf;
extern const char *relocate_base_btf_path;
extern struct hashmap *refs_table;

void __printf(1, 2) p_err(const char *fmt, ...);
Expand Down

0 comments on commit 21b748e

Please sign in to comment.