diff options
Diffstat (limited to 'tools/bpf/bpftool')
-rw-r--r-- | tools/bpf/bpftool/Documentation/Makefile | 6 | ||||
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool-btf.rst | 9 | ||||
-rw-r--r-- | tools/bpf/bpftool/Documentation/bpftool-prog.rst | 10 | ||||
-rw-r--r-- | tools/bpf/bpftool/Makefile | 20 | ||||
-rw-r--r-- | tools/bpf/bpftool/bash-completion/bpftool | 11 | ||||
-rw-r--r-- | tools/bpf/bpftool/btf.c | 63 | ||||
-rw-r--r-- | tools/bpf/bpftool/btf_dumper.c | 2 | ||||
-rw-r--r-- | tools/bpf/bpftool/cfg.c | 1 | ||||
-rw-r--r-- | tools/bpf/bpftool/cgroup.c | 16 | ||||
-rw-r--r-- | tools/bpf/bpftool/common.c | 7 | ||||
-rw-r--r-- | tools/bpf/bpftool/feature.c | 23 | ||||
-rw-r--r-- | tools/bpf/bpftool/gen.c | 12 | ||||
-rw-r--r-- | tools/bpf/bpftool/jit_disasm.c | 3 | ||||
-rw-r--r-- | tools/bpf/bpftool/link.c | 17 | ||||
-rw-r--r-- | tools/bpf/bpftool/main.c | 8 | ||||
-rw-r--r-- | tools/bpf/bpftool/map.c | 14 | ||||
-rw-r--r-- | tools/bpf/bpftool/map_perf_ring.c | 6 | ||||
-rw-r--r-- | tools/bpf/bpftool/net.c | 4 | ||||
-rw-r--r-- | tools/bpf/bpftool/netlink_dumper.c | 6 | ||||
-rw-r--r-- | tools/bpf/bpftool/prog.c | 25 | ||||
-rw-r--r-- | tools/bpf/bpftool/tracelog.c | 2 | ||||
-rw-r--r-- | tools/bpf/bpftool/xlated_dumper.c | 6 |
22 files changed, 189 insertions, 82 deletions
diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile index 4315652678b9..bf843f328812 100644 --- a/tools/bpf/bpftool/Documentation/Makefile +++ b/tools/bpf/bpftool/Documentation/Makefile @@ -5,12 +5,6 @@ INSTALL ?= install RM ?= rm -f RMDIR ?= rmdir --ignore-fail-on-non-empty -ifeq ($(V),1) - Q = -else - Q = @ -endif - prefix ?= /usr/local mandir ?= $(prefix)/man man8dir = $(mandir)/man8 diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst index 3f6bca03ad2e..d47dddc2b4ee 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst @@ -24,7 +24,7 @@ BTF COMMANDS ============= | **bpftool** **btf** { **show** | **list** } [**id** *BTF_ID*] -| **bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*] +| **bpftool** **btf dump** *BTF_SRC* [**format** *FORMAT*] [**root_id** *ROOT_ID*] | **bpftool** **btf help** | | *BTF_SRC* := { **id** *BTF_ID* | **prog** *PROG* | **map** *MAP* [{**key** | **value** | **kv** | **all**}] | **file** *FILE* } @@ -43,7 +43,7 @@ bpftool btf { show | list } [id *BTF_ID*] that hold open file descriptors (FDs) against BTF objects. On such kernels bpftool will automatically emit this information as well. -bpftool btf dump *BTF_SRC* +bpftool btf dump *BTF_SRC* [format *FORMAT*] [root_id *ROOT_ID*] Dump BTF entries from a given *BTF_SRC*. When **id** is specified, BTF object with that ID will be loaded and all @@ -67,6 +67,11 @@ bpftool btf dump *BTF_SRC* formatting, the output is sorted by default. Use the **unsorted** option to avoid sorting the output. + **root_id** option can be used to filter a dump to a single type and all + its dependent types. It cannot be used with any other types of filtering + (such as the "key", "value", or "kv" arguments when dumping BTF for a map). + It can be passed multiple times to dump multiple types. + bpftool btf help Print short help message. diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst index d6304e01afe0..da3152c16228 100644 --- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst +++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst @@ -31,7 +31,7 @@ PROG COMMANDS | **bpftool** **prog dump xlated** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] [**visual**] }] | **bpftool** **prog dump jited** *PROG* [{ **file** *FILE* | [**opcodes**] [**linum**] }] | **bpftool** **prog pin** *PROG* *FILE* -| **bpftool** **prog** { **load** | **loadall** } *OBJ* *PATH* [**type** *TYPE*] [**map** { **idx** *IDX* | **name** *NAME* } *MAP*] [{ **offload_dev** | **xdpmeta_dev** } *NAME*] [**pinmaps** *MAP_DIR*] [**autoattach**] +| **bpftool** **prog** { **load** | **loadall** } *OBJ* *PATH* [**type** *TYPE*] [**map** { **idx** *IDX* | **name** *NAME* } *MAP*] [{ **offload_dev** | **xdpmeta_dev** } *NAME*] [**pinmaps** *MAP_DIR*] [**autoattach**] [**kernel_btf** *BTF_FILE*] | **bpftool** **prog attach** *PROG* *ATTACH_TYPE* [*MAP*] | **bpftool** **prog detach** *PROG* *ATTACH_TYPE* [*MAP*] | **bpftool** **prog tracelog** @@ -127,7 +127,7 @@ bpftool prog pin *PROG* *FILE* Note: *FILE* must be located in *bpffs* mount. It must not contain a dot character ('.'), which is reserved for future extensions of *bpffs*. -bpftool prog { load | loadall } *OBJ* *PATH* [type *TYPE*] [map { idx *IDX* | name *NAME* } *MAP*] [{ offload_dev | xdpmeta_dev } *NAME*] [pinmaps *MAP_DIR*] [autoattach] +bpftool prog { load | loadall } *OBJ* *PATH* [type *TYPE*] [map { idx *IDX* | name *NAME* } *MAP*] [{ offload_dev | xdpmeta_dev } *NAME*] [pinmaps *MAP_DIR*] [autoattach] [kernel_btf *BTF_FILE*] Load bpf program(s) from binary *OBJ* and pin as *PATH*. **bpftool prog load** pins only the first program from the *OBJ* as *PATH*. **bpftool prog loadall** pins all programs from the *OBJ* under *PATH* directory. **type** @@ -153,6 +153,12 @@ bpftool prog { load | loadall } *OBJ* *PATH* [type *TYPE*] [map { idx *IDX* | na program does not support autoattach, bpftool falls back to regular pinning for that program instead. + The **kernel_btf** option allows specifying an external BTF file to replace + the system's own vmlinux BTF file for CO-RE relocations. Note that any + other feature relying on BTF (such as fentry/fexit programs, struct_ops) + requires the BTF file for the actual kernel running on the host, often + exposed at /sys/kernel/btf/vmlinux. + Note: *PATH* must be located in *bpffs* mount. It must not contain a dot character ('.'), which is reserved for future extensions of *bpffs*. diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile index a4263dfb5e03..9e9a5f006cd2 100644 --- a/tools/bpf/bpftool/Makefile +++ b/tools/bpf/bpftool/Makefile @@ -7,12 +7,6 @@ srctree := $(patsubst %/,%,$(dir $(srctree))) srctree := $(patsubst %/,%,$(dir $(srctree))) endif -ifeq ($(V),1) - Q = -else - Q = @ -endif - BPF_DIR = $(srctree)/tools/lib/bpf ifneq ($(OUTPUT),) @@ -71,7 +65,12 @@ prefix ?= /usr/local bash_compdir ?= /usr/share/bash-completion/completions CFLAGS += -O2 -CFLAGS += -W -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers +CFLAGS += -W +CFLAGS += -Wall +CFLAGS += -Wextra +CFLAGS += -Wformat-signedness +CFLAGS += -Wno-unused-parameter +CFLAGS += -Wno-missing-field-initializers CFLAGS += $(filter-out -Wswitch-enum -Wnested-externs,$(EXTRA_WARNINGS)) CFLAGS += -DPACKAGE='"bpftool"' -D__EXPORTED_HEADERS__ \ -I$(or $(OUTPUT),.) \ @@ -106,6 +105,7 @@ FEATURE_TESTS += libbfd-liberty FEATURE_TESTS += libbfd-liberty-z FEATURE_TESTS += disassembler-four-args FEATURE_TESTS += disassembler-init-styled +FEATURE_TESTS += libelf-zstd FEATURE_DISPLAY := clang-bpf-co-re FEATURE_DISPLAY += llvm @@ -132,6 +132,12 @@ endif LIBS = $(LIBBPF) -lelf -lz LIBS_BOOTSTRAP = $(LIBBPF_BOOTSTRAP) -lelf -lz + +ifeq ($(feature-libelf-zstd),1) +LIBS += -lzstd +LIBS_BOOTSTRAP += -lzstd +endif + ifeq ($(feature-libcap), 1) CFLAGS += -DUSE_LIBCAP LIBS += -lcap diff --git a/tools/bpf/bpftool/bash-completion/bpftool b/tools/bpf/bpftool/bash-completion/bpftool index 0c541498c301..27512feb5c70 100644 --- a/tools/bpf/bpftool/bash-completion/bpftool +++ b/tools/bpf/bpftool/bash-completion/bpftool @@ -505,13 +505,13 @@ _bpftool() _bpftool_get_map_names return 0 ;; - pinned|pinmaps) + pinned|pinmaps|kernel_btf) _filedir return 0 ;; *) COMPREPLY=( $( compgen -W "map" -- "$cur" ) ) - _bpftool_once_attr 'type pinmaps autoattach' + _bpftool_once_attr 'type pinmaps autoattach kernel_btf' _bpftool_one_of_list 'offload_dev xdpmeta_dev' return 0 ;; @@ -930,19 +930,24 @@ _bpftool() format) COMPREPLY=( $( compgen -W "c raw" -- "$cur" ) ) ;; + root_id) + return 0; + ;; c) - COMPREPLY=( $( compgen -W "unsorted" -- "$cur" ) ) + COMPREPLY=( $( compgen -W "unsorted root_id" -- "$cur" ) ) ;; *) # emit extra options case ${words[3]} in id|file) + COMPREPLY=( $( compgen -W "root_id" -- "$cur" ) ) _bpftool_once_attr 'format' ;; map|prog) if [[ ${words[3]} == "map" ]] && [[ $cword == 6 ]]; then COMPREPLY+=( $( compgen -W "key value kv all" -- "$cur" ) ) fi + COMPREPLY=( $( compgen -W "root_id" -- "$cur" ) ) _bpftool_once_attr 'format' ;; *) diff --git a/tools/bpf/bpftool/btf.c b/tools/bpf/bpftool/btf.c index d005e4fd6128..6b14cbfa58aa 100644 --- a/tools/bpf/bpftool/btf.c +++ b/tools/bpf/bpftool/btf.c @@ -27,6 +27,8 @@ #define KFUNC_DECL_TAG "bpf_kfunc" #define FASTCALL_DECL_TAG "bpf_fastcall" +#define MAX_ROOT_IDS 16 + static const char * const btf_kind_str[NR_BTF_KINDS] = { [BTF_KIND_UNKN] = "UNKNOWN", [BTF_KIND_INT] = "INT", @@ -251,7 +253,7 @@ static int dump_btf_type(const struct btf *btf, __u32 id, if (btf_kflag(t)) printf("\n\t'%s' val=%d", name, v->val); else - printf("\n\t'%s' val=%u", name, v->val); + printf("\n\t'%s' val=%u", name, (__u32)v->val); } } if (json_output) @@ -880,12 +882,14 @@ static int do_dump(int argc, char **argv) { bool dump_c = false, sort_dump_c = true; struct btf *btf = NULL, *base = NULL; - __u32 root_type_ids[2]; + __u32 root_type_ids[MAX_ROOT_IDS]; + bool have_id_filtering; int root_type_cnt = 0; __u32 btf_id = -1; const char *src; int fd = -1; int err = 0; + int i; if (!REQ_ARGS(2)) { usage(); @@ -973,6 +977,8 @@ static int do_dump(int argc, char **argv) goto done; } + have_id_filtering = !!root_type_cnt; + while (argc) { if (is_prefix(*argv, "format")) { NEXT_ARG(); @@ -992,6 +998,36 @@ static int do_dump(int argc, char **argv) goto done; } NEXT_ARG(); + } else if (is_prefix(*argv, "root_id")) { + __u32 root_id; + char *end; + + if (have_id_filtering) { + p_err("cannot use root_id with other type filtering"); + err = -EINVAL; + goto done; + } else if (root_type_cnt == MAX_ROOT_IDS) { + p_err("only %d root_id are supported", MAX_ROOT_IDS); + err = -E2BIG; + goto done; + } + + NEXT_ARG(); + root_id = strtoul(*argv, &end, 0); + if (*end) { + err = -1; + p_err("can't parse %s as root ID", *argv); + goto done; + } + for (i = 0; i < root_type_cnt; i++) { + if (root_type_ids[i] == root_id) { + err = -EINVAL; + p_err("duplicate root_id %u supplied", root_id); + goto done; + } + } + root_type_ids[root_type_cnt++] = root_id; + NEXT_ARG(); } else if (is_prefix(*argv, "unsorted")) { sort_dump_c = false; NEXT_ARG(); @@ -1017,6 +1053,17 @@ static int do_dump(int argc, char **argv) } } + /* Invalid root IDs causes half emitted boilerplate and then unclean + * exit. It's an ugly user experience, so handle common error here. + */ + for (i = 0; i < root_type_cnt; i++) { + if (root_type_ids[i] >= btf__type_cnt(btf)) { + err = -EINVAL; + p_err("invalid root ID: %u", root_type_ids[i]); + goto done; + } + } + if (dump_c) { if (json_output) { p_err("JSON output for C-syntax dump is not supported"); @@ -1085,7 +1132,7 @@ build_btf_type_table(struct hashmap *tab, enum bpf_obj_type type, break; default: err = -1; - p_err("unexpected object type: %d", type); + p_err("unexpected object type: %u", type); goto err_free; } if (err) { @@ -1108,7 +1155,7 @@ build_btf_type_table(struct hashmap *tab, enum bpf_obj_type type, break; default: err = -1; - p_err("unexpected object type: %d", type); + p_err("unexpected object type: %u", type); goto err_free; } if (fd < 0) { @@ -1141,7 +1188,7 @@ build_btf_type_table(struct hashmap *tab, enum bpf_obj_type type, break; default: err = -1; - p_err("unexpected object type: %d", type); + p_err("unexpected object type: %u", type); goto err_free; } if (!btf_id) @@ -1207,12 +1254,12 @@ show_btf_plain(struct bpf_btf_info *info, int fd, n = 0; hashmap__for_each_key_entry(btf_prog_table, entry, info->id) { - printf("%s%lu", n++ == 0 ? " prog_ids " : ",", entry->value); + printf("%s%lu", n++ == 0 ? " prog_ids " : ",", (unsigned long)entry->value); } n = 0; hashmap__for_each_key_entry(btf_map_table, entry, info->id) { - printf("%s%lu", n++ == 0 ? " map_ids " : ",", entry->value); + printf("%s%lu", n++ == 0 ? " map_ids " : ",", (unsigned long)entry->value); } emit_obj_refs_plain(refs_table, info->id, "\n\tpids "); @@ -1391,7 +1438,7 @@ static int do_help(int argc, char **argv) fprintf(stderr, "Usage: %1$s %2$s { show | list } [id BTF_ID]\n" - " %1$s %2$s dump BTF_SRC [format FORMAT]\n" + " %1$s %2$s dump BTF_SRC [format FORMAT] [root_id ROOT_ID]\n" " %1$s %2$s help\n" "\n" " BTF_SRC := { id BTF_ID | prog PROG | map MAP [{key | value | kv | all}] | file FILE }\n" diff --git a/tools/bpf/bpftool/btf_dumper.c b/tools/bpf/bpftool/btf_dumper.c index 527fe867a8fb..4e896d8a2416 100644 --- a/tools/bpf/bpftool/btf_dumper.c +++ b/tools/bpf/bpftool/btf_dumper.c @@ -653,7 +653,7 @@ static int __btf_dumper_type_only(const struct btf *btf, __u32 type_id, case BTF_KIND_ARRAY: array = (struct btf_array *)(t + 1); BTF_PRINT_TYPE(array->type); - BTF_PRINT_ARG("[%d]", array->nelems); + BTF_PRINT_ARG("[%u]", array->nelems); break; case BTF_KIND_PTR: BTF_PRINT_TYPE(t->type); diff --git a/tools/bpf/bpftool/cfg.c b/tools/bpf/bpftool/cfg.c index eec437cca2ea..e3785f9a697d 100644 --- a/tools/bpf/bpftool/cfg.c +++ b/tools/bpf/bpftool/cfg.c @@ -302,6 +302,7 @@ static bool func_add_bb_edges(struct func_node *func) insn = bb->tail; if (!is_jmp_insn(insn->code) || + BPF_OP(insn->code) == BPF_CALL || BPF_OP(insn->code) == BPF_EXIT) { e->dst = bb_next(bb); e->flags |= EDGE_FLAG_FALLTHROUGH; diff --git a/tools/bpf/bpftool/cgroup.c b/tools/bpf/bpftool/cgroup.c index 9af426d43299..944ebe21a216 100644 --- a/tools/bpf/bpftool/cgroup.c +++ b/tools/bpf/bpftool/cgroup.c @@ -191,7 +191,7 @@ static int show_bpf_prog(int id, enum bpf_attach_type attach_type, if (attach_btf_name) printf(" %-15s", attach_btf_name); else if (info.attach_btf_id) - printf(" attach_btf_obj_id=%d attach_btf_id=%d", + printf(" attach_btf_obj_id=%u attach_btf_id=%u", info.attach_btf_obj_id, info.attach_btf_id); printf("\n"); } @@ -221,7 +221,7 @@ static int cgroup_has_attached_progs(int cgroup_fd) for (i = 0; i < ARRAY_SIZE(cgroup_attach_types); i++) { int count = count_attached_bpf_progs(cgroup_fd, cgroup_attach_types[i]); - if (count < 0) + if (count < 0 && errno != EINVAL) return -1; if (count > 0) { @@ -318,11 +318,11 @@ static int show_bpf_progs(int cgroup_fd, enum bpf_attach_type type, static int do_show(int argc, char **argv) { - enum bpf_attach_type type; int has_attached_progs; const char *path; int cgroup_fd; int ret = -1; + unsigned int i; query_flags = 0; @@ -370,14 +370,14 @@ static int do_show(int argc, char **argv) "AttachFlags", "Name"); btf_vmlinux = libbpf_find_kernel_btf(); - for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) { + for (i = 0; i < ARRAY_SIZE(cgroup_attach_types); i++) { /* * Not all attach types may be supported, so it's expected, * that some requests will fail. * If we were able to get the show for at least one * attach type, let's return 0. */ - if (show_bpf_progs(cgroup_fd, type, 0) == 0) + if (show_bpf_progs(cgroup_fd, cgroup_attach_types[i], 0) == 0) ret = 0; } @@ -400,9 +400,9 @@ exit: static int do_show_tree_fn(const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftw) { - enum bpf_attach_type type; int has_attached_progs; int cgroup_fd; + unsigned int i; if (typeflag != FTW_D) return 0; @@ -434,8 +434,8 @@ static int do_show_tree_fn(const char *fpath, const struct stat *sb, } btf_vmlinux = libbpf_find_kernel_btf(); - for (type = 0; type < __MAX_BPF_ATTACH_TYPE; type++) - show_bpf_progs(cgroup_fd, type, ftw->level); + for (i = 0; i < ARRAY_SIZE(cgroup_attach_types); i++) + show_bpf_progs(cgroup_fd, cgroup_attach_types[i], ftw->level); if (errno == EINVAL) /* Last attach type does not support query. diff --git a/tools/bpf/bpftool/common.c b/tools/bpf/bpftool/common.c index 9b75639434b8..ecfa790adc13 100644 --- a/tools/bpf/bpftool/common.c +++ b/tools/bpf/bpftool/common.c @@ -461,10 +461,11 @@ int get_fd_type(int fd) p_err("can't read link type: %s", strerror(errno)); return -1; } - if (n == sizeof(path)) { + if (n == sizeof(buf)) { p_err("can't read link type: path too long!"); return -1; } + buf[n] = '\0'; if (strstr(buf, "bpf-map")) return BPF_OBJ_MAP; @@ -713,7 +714,7 @@ ifindex_to_arch(__u32 ifindex, __u64 ns_dev, __u64 ns_ino, const char **opt) int vendor_id; if (!ifindex_to_name_ns(ifindex, ns_dev, ns_ino, devname)) { - p_err("Can't get net device name for ifindex %d: %s", ifindex, + p_err("Can't get net device name for ifindex %u: %s", ifindex, strerror(errno)); return NULL; } @@ -738,7 +739,7 @@ ifindex_to_arch(__u32 ifindex, __u64 ns_dev, __u64 ns_ino, const char **opt) /* No NFP support in LLVM, we have no valid triple to return. */ default: p_err("Can't get arch name for device vendor id 0x%04x", - vendor_id); + (unsigned int)vendor_id); return NULL; } } diff --git a/tools/bpf/bpftool/feature.c b/tools/bpf/bpftool/feature.c index 4dbc4fcdf473..24fecdf8e430 100644 --- a/tools/bpf/bpftool/feature.c +++ b/tools/bpf/bpftool/feature.c @@ -885,6 +885,28 @@ probe_v3_isa_extension(const char *define_prefix, __u32 ifindex) "V3_ISA_EXTENSION"); } +/* + * Probe for the v4 instruction set extension introduced in commit 1f9a1ea821ff + * ("bpf: Support new sign-extension load insns"). + */ +static void +probe_v4_isa_extension(const char *define_prefix, __u32 ifindex) +{ + struct bpf_insn insns[5] = { + BPF_MOV64_IMM(BPF_REG_0, 0), + BPF_JMP32_IMM(BPF_JEQ, BPF_REG_0, 1, 1), + BPF_JMP32_A(1), + BPF_MOV64_IMM(BPF_REG_0, 1), + BPF_EXIT_INSN() + }; + + probe_misc_feature(insns, ARRAY_SIZE(insns), + define_prefix, ifindex, + "have_v4_isa_extension", + "ISA extension v4", + "V4_ISA_EXTENSION"); +} + static void section_system_config(enum probe_component target, const char *define_prefix) { @@ -1029,6 +1051,7 @@ static void section_misc(const char *define_prefix, __u32 ifindex) probe_bounded_loops(define_prefix, ifindex); probe_v2_isa_extension(define_prefix, ifindex); probe_v3_isa_extension(define_prefix, ifindex); + probe_v4_isa_extension(define_prefix, ifindex); print_end_section(); } diff --git a/tools/bpf/bpftool/gen.c b/tools/bpf/bpftool/gen.c index 5a4d3240689e..67a60114368f 100644 --- a/tools/bpf/bpftool/gen.c +++ b/tools/bpf/bpftool/gen.c @@ -670,7 +670,7 @@ static void codegen_destroy(struct bpf_object *obj, const char *obj_name) continue; if (bpf_map__is_internal(map) && (bpf_map__map_flags(map) & BPF_F_MMAPABLE)) - printf("\tskel_free_map_data(skel->%1$s, skel->maps.%1$s.initial_value, %2$zd);\n", + printf("\tskel_free_map_data(skel->%1$s, skel->maps.%1$s.initial_value, %2$zu);\n", ident, bpf_map_mmap_sz(map)); codegen("\ \n\ @@ -984,7 +984,7 @@ static int walk_st_ops_shadow_vars(struct btf *btf, const char *ident, offset = m->offset / 8; if (next_offset < offset) - printf("\t\t\tchar __padding_%d[%d];\n", i, offset - next_offset); + printf("\t\t\tchar __padding_%d[%u];\n", i, offset - next_offset); switch (btf_kind(member_type)) { case BTF_KIND_INT: @@ -1052,7 +1052,7 @@ static int walk_st_ops_shadow_vars(struct btf *btf, const char *ident, /* Cannot fail since it must be a struct type */ size = btf__resolve_size(btf, map_type_id); if (next_offset < (__u32)size) - printf("\t\t\tchar __padding_end[%d];\n", size - next_offset); + printf("\t\t\tchar __padding_end[%u];\n", size - next_offset); out: btf_dump__free(d); @@ -2095,7 +2095,7 @@ btfgen_mark_type(struct btfgen_info *info, unsigned int type_id, bool follow_poi break; /* tells if some other type needs to be handled */ default: - p_err("unsupported kind: %s (%d)", btf_kind_str(btf_type), type_id); + p_err("unsupported kind: %s (%u)", btf_kind_str(btf_type), type_id); return -EINVAL; } @@ -2147,7 +2147,7 @@ static int btfgen_record_field_relo(struct btfgen_info *info, struct bpf_core_sp btf_type = btf__type_by_id(btf, type_id); break; default: - p_err("unsupported kind: %s (%d)", + p_err("unsupported kind: %s (%u)", btf_kind_str(btf_type), btf_type->type); return -EINVAL; } @@ -2246,7 +2246,7 @@ static int btfgen_mark_type_match(struct btfgen_info *info, __u32 type_id, bool } /* tells if some other type needs to be handled */ default: - p_err("unsupported kind: %s (%d)", btf_kind_str(btf_type), type_id); + p_err("unsupported kind: %s (%u)", btf_kind_str(btf_type), type_id); return -EINVAL; } diff --git a/tools/bpf/bpftool/jit_disasm.c b/tools/bpf/bpftool/jit_disasm.c index c032d2c6ab6d..8895b4e1f690 100644 --- a/tools/bpf/bpftool/jit_disasm.c +++ b/tools/bpf/bpftool/jit_disasm.c @@ -343,7 +343,8 @@ int disasm_print_insn(unsigned char *image, ssize_t len, int opcodes, { const struct bpf_line_info *linfo = NULL; unsigned int nr_skip = 0; - int count, i, pc = 0; + int count, i; + unsigned int pc = 0; disasm_ctx_t ctx; if (!len) diff --git a/tools/bpf/bpftool/link.c b/tools/bpf/bpftool/link.c index 5cd503b763d7..3535afc80a49 100644 --- a/tools/bpf/bpftool/link.c +++ b/tools/bpf/bpftool/link.c @@ -107,7 +107,7 @@ static int link_parse_fd(int *argc, char ***argv) fd = bpf_link_get_fd_by_id(id); if (fd < 0) - p_err("failed to get link with ID %d: %s", id, strerror(errno)); + p_err("failed to get link with ID %u: %s", id, strerror(errno)); return fd; } else if (is_prefix(**argv, "pinned")) { char *path; @@ -380,6 +380,7 @@ show_perf_event_uprobe_json(struct bpf_link_info *info, json_writer_t *wtr) u64_to_ptr(info->perf_event.uprobe.file_name)); jsonw_uint_field(wtr, "offset", info->perf_event.uprobe.offset); jsonw_uint_field(wtr, "cookie", info->perf_event.uprobe.cookie); + jsonw_uint_field(wtr, "ref_ctr_offset", info->perf_event.uprobe.ref_ctr_offset); } static void @@ -404,7 +405,7 @@ static char *perf_config_hw_cache_str(__u64 config) if (hw_cache) snprintf(str, PERF_HW_CACHE_LEN, "%s-", hw_cache); else - snprintf(str, PERF_HW_CACHE_LEN, "%lld-", config & 0xff); + snprintf(str, PERF_HW_CACHE_LEN, "%llu-", config & 0xff); op = perf_event_name(evsel__hw_cache_op, (config >> 8) & 0xff); if (op) @@ -412,7 +413,7 @@ static char *perf_config_hw_cache_str(__u64 config) "%s-", op); else snprintf(str + strlen(str), PERF_HW_CACHE_LEN - strlen(str), - "%lld-", (config >> 8) & 0xff); + "%llu-", (config >> 8) & 0xff); result = perf_event_name(evsel__hw_cache_result, config >> 16); if (result) @@ -420,7 +421,7 @@ static char *perf_config_hw_cache_str(__u64 config) "%s", result); else snprintf(str + strlen(str), PERF_HW_CACHE_LEN - strlen(str), - "%lld", config >> 16); + "%llu", config >> 16); return str; } @@ -623,7 +624,7 @@ static void show_link_ifindex_plain(__u32 ifindex) else snprintf(devname, sizeof(devname), "(detached)"); if (ret) - snprintf(devname, sizeof(devname), "%s(%d)", + snprintf(devname, sizeof(devname), "%s(%u)", tmpname, ifindex); printf("ifindex %s ", devname); } @@ -699,7 +700,7 @@ void netfilter_dump_plain(const struct bpf_link_info *info) if (pfname) printf("\n\t%s", pfname); else - printf("\n\tpf: %d", pf); + printf("\n\tpf: %u", pf); if (hookname) printf(" %s", hookname); @@ -773,7 +774,7 @@ static void show_uprobe_multi_plain(struct bpf_link_info *info) printf("func_cnt %u ", info->uprobe_multi.count); if (info->uprobe_multi.pid) - printf("pid %d ", info->uprobe_multi.pid); + printf("pid %u ", info->uprobe_multi.pid); printf("\n\t%-16s %-16s %-16s", "offset", "ref_ctr_offset", "cookies"); for (i = 0; i < info->uprobe_multi.count; i++) { @@ -823,6 +824,8 @@ static void show_perf_event_uprobe_plain(struct bpf_link_info *info) printf("%s+%#x ", buf, info->perf_event.uprobe.offset); if (info->perf_event.uprobe.cookie) printf("cookie %llu ", info->perf_event.uprobe.cookie); + if (info->perf_event.uprobe.ref_ctr_offset) + printf("ref_ctr_offset 0x%llx ", info->perf_event.uprobe.ref_ctr_offset); } static void show_perf_event_tracepoint_plain(struct bpf_link_info *info) diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c index 08d0ac543c67..cd5963cb6058 100644 --- a/tools/bpf/bpftool/main.c +++ b/tools/bpf/bpftool/main.c @@ -152,7 +152,7 @@ static int do_version(int argc, char **argv) BPFTOOL_MINOR_VERSION, BPFTOOL_PATCH_VERSION); #endif jsonw_name(json_wtr, "libbpf_version"); - jsonw_printf(json_wtr, "\"%d.%d\"", + jsonw_printf(json_wtr, "\"%u.%u\"", libbpf_major_version(), libbpf_minor_version()); jsonw_name(json_wtr, "features"); @@ -370,7 +370,7 @@ static int do_batch(int argc, char **argv) while ((cp = strstr(buf, "\\\n")) != NULL) { if (!fgets(contline, sizeof(contline), fp) || strlen(contline) == 0) { - p_err("missing continuation line on command %d", + p_err("missing continuation line on command %u", lines); err = -1; goto err_close; @@ -381,7 +381,7 @@ static int do_batch(int argc, char **argv) *cp = '\0'; if (strlen(buf) + strlen(contline) + 1 > sizeof(buf)) { - p_err("command %d is too long", lines); + p_err("command %u is too long", lines); err = -1; goto err_close; } @@ -423,7 +423,7 @@ static int do_batch(int argc, char **argv) err = -1; } else { if (!json_output) - printf("processed %d commands\n", lines); + printf("processed %u commands\n", lines); } err_close: if (fp != stdin) diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index b89bd792c1d5..81cc668b4b05 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c @@ -285,7 +285,7 @@ static void print_entry_plain(struct bpf_map_info *info, unsigned char *key, } if (info->value_size) { for (i = 0; i < n; i++) { - printf("value (CPU %02d):%c", + printf("value (CPU %02u):%c", i, info->value_size > 16 ? '\n' : ' '); fprint_hex(stdout, value + i * step, info->value_size, " "); @@ -316,7 +316,7 @@ static char **parse_bytes(char **argv, const char *name, unsigned char *val, } if (i != n) { - p_err("%s expected %d bytes got %d", name, n, i); + p_err("%s expected %u bytes got %u", name, n, i); return NULL; } @@ -462,7 +462,7 @@ static void show_map_header_json(struct bpf_map_info *info, json_writer_t *wtr) jsonw_string_field(wtr, "name", info->name); jsonw_name(wtr, "flags"); - jsonw_printf(wtr, "%d", info->map_flags); + jsonw_printf(wtr, "%u", info->map_flags); } static int show_map_close_json(int fd, struct bpf_map_info *info) @@ -588,7 +588,7 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info) if (prog_type_str) printf("owner_prog_type %s ", prog_type_str); else - printf("owner_prog_type %d ", prog_type); + printf("owner_prog_type %u ", prog_type); } if (owner_jited) printf("owner%s jited", @@ -615,7 +615,7 @@ static int show_map_close_plain(int fd, struct bpf_map_info *info) printf("\n\t"); if (info->btf_id) - printf("btf_id %d", info->btf_id); + printf("btf_id %u", info->btf_id); if (frozen) printf("%sfrozen", info->btf_id ? " " : ""); @@ -1270,6 +1270,10 @@ static int do_create(int argc, char **argv) } else if (is_prefix(*argv, "name")) { NEXT_ARG(); map_name = GET_ARG(); + if (strlen(map_name) > BPF_OBJ_NAME_LEN - 1) { + p_info("Warning: map name is longer than %u characters, it will be truncated.", + BPF_OBJ_NAME_LEN - 1); + } } else if (is_prefix(*argv, "key")) { if (parse_u32_arg(&argc, &argv, &key_size, "key size")) diff --git a/tools/bpf/bpftool/map_perf_ring.c b/tools/bpf/bpftool/map_perf_ring.c index 21d7d447e1f3..552b4ca40c27 100644 --- a/tools/bpf/bpftool/map_perf_ring.c +++ b/tools/bpf/bpftool/map_perf_ring.c @@ -91,15 +91,15 @@ print_bpf_output(void *private_data, int cpu, struct perf_event_header *event) jsonw_end_object(json_wtr); } else { if (e->header.type == PERF_RECORD_SAMPLE) { - printf("== @%lld.%09lld CPU: %d index: %d =====\n", + printf("== @%llu.%09llu CPU: %d index: %d =====\n", e->time / 1000000000ULL, e->time % 1000000000ULL, cpu, idx); fprint_hex(stdout, e->data, e->size, " "); printf("\n"); } else if (e->header.type == PERF_RECORD_LOST) { - printf("lost %lld events\n", lost->lost); + printf("lost %llu events\n", lost->lost); } else { - printf("unknown event type=%d size=%d\n", + printf("unknown event type=%u size=%u\n", e->header.type, e->header.size); } } diff --git a/tools/bpf/bpftool/net.c b/tools/bpf/bpftool/net.c index d2242d9f8441..64f958f437b0 100644 --- a/tools/bpf/bpftool/net.c +++ b/tools/bpf/bpftool/net.c @@ -476,7 +476,7 @@ static void __show_dev_tc_bpf(const struct ip_devname_ifindex *dev, for (i = 0; i < optq.count; i++) { NET_START_OBJECT; NET_DUMP_STR("devname", "%s", dev->devname); - NET_DUMP_UINT("ifindex", "(%u)", dev->ifindex); + NET_DUMP_UINT("ifindex", "(%u)", (unsigned int)dev->ifindex); NET_DUMP_STR("kind", " %s", attach_loc_strings[loc]); ret = __show_dev_tc_bpf_name(prog_ids[i], prog_name, sizeof(prog_name)); @@ -831,7 +831,7 @@ static void show_link_netfilter(void) if (err) { if (errno == ENOENT) break; - p_err("can't get next link: %s (id %d)", strerror(errno), id); + p_err("can't get next link: %s (id %u)", strerror(errno), id); break; } diff --git a/tools/bpf/bpftool/netlink_dumper.c b/tools/bpf/bpftool/netlink_dumper.c index 5f65140b003b..0a3c7e96c797 100644 --- a/tools/bpf/bpftool/netlink_dumper.c +++ b/tools/bpf/bpftool/netlink_dumper.c @@ -45,7 +45,7 @@ static int do_xdp_dump_one(struct nlattr *attr, unsigned int ifindex, NET_START_OBJECT; if (name) NET_DUMP_STR("devname", "%s", name); - NET_DUMP_UINT("ifindex", "(%d)", ifindex); + NET_DUMP_UINT("ifindex", "(%u)", ifindex); if (mode == XDP_ATTACHED_MULTI) { if (json_output) { @@ -74,7 +74,7 @@ int do_xdp_dump(struct ifinfomsg *ifinfo, struct nlattr **tb) if (!tb[IFLA_XDP]) return 0; - return do_xdp_dump_one(tb[IFLA_XDP], ifinfo->ifi_index, + return do_xdp_dump_one(tb[IFLA_XDP], (unsigned int)ifinfo->ifi_index, libbpf_nla_getattr_str(tb[IFLA_IFNAME])); } @@ -168,7 +168,7 @@ int do_filter_dump(struct tcmsg *info, struct nlattr **tb, const char *kind, NET_START_OBJECT; if (devname[0] != '\0') NET_DUMP_STR("devname", "%s", devname); - NET_DUMP_UINT("ifindex", "(%u)", ifindex); + NET_DUMP_UINT("ifindex", "(%u)", (unsigned int)ifindex); NET_DUMP_STR("kind", " %s", kind); ret = do_bpf_filter_dump(tb[TCA_OPTIONS]); NET_END_OBJECT_FINAL; diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c index e71be67f1d86..96eea8a67225 100644 --- a/tools/bpf/bpftool/prog.c +++ b/tools/bpf/bpftool/prog.c @@ -521,10 +521,10 @@ static void print_prog_header_plain(struct bpf_prog_info *info, int fd) print_dev_plain(info->ifindex, info->netns_dev, info->netns_ino); printf("%s", info->gpl_compatible ? " gpl" : ""); if (info->run_time_ns) - printf(" run_time_ns %lld run_cnt %lld", + printf(" run_time_ns %llu run_cnt %llu", info->run_time_ns, info->run_cnt); if (info->recursion_misses) - printf(" recursion_misses %lld", info->recursion_misses); + printf(" recursion_misses %llu", info->recursion_misses); printf("\n"); } @@ -569,7 +569,7 @@ static void print_prog_plain(struct bpf_prog_info *info, int fd, bool orphaned) } if (info->btf_id) - printf("\n\tbtf_id %d", info->btf_id); + printf("\n\tbtf_id %u", info->btf_id); emit_obj_refs_plain(refs_table, info->id, "\n\tpids "); @@ -1164,7 +1164,7 @@ static int get_run_data(const char *fname, void **data_ptr, unsigned int *size) } if (nb_read > buf_size - block_size) { if (buf_size == UINT32_MAX) { - p_err("data_in/ctx_in is too long (max: %d)", + p_err("data_in/ctx_in is too long (max: %u)", UINT32_MAX); goto err_free; } @@ -1681,8 +1681,17 @@ offload_dev: } else if (is_prefix(*argv, "autoattach")) { auto_attach = true; NEXT_ARG(); + } else if (is_prefix(*argv, "kernel_btf")) { + NEXT_ARG(); + + if (!REQ_ARGS(1)) + goto err_free_reuse_maps; + + open_opts.btf_custom_path = GET_ARG(); } else { - p_err("expected no more arguments, 'type', 'map' or 'dev', got: '%s'?", + p_err("expected no more arguments, " + "'type', 'map', 'offload_dev', 'xdpmeta_dev', 'pinmaps', " + "'autoattach', or 'kernel_btf', got: '%s'?", *argv); goto err_free_reuse_maps; } @@ -1928,6 +1937,7 @@ static int do_loader(int argc, char **argv) obj = bpf_object__open_file(file, &open_opts); if (!obj) { + err = -1; p_err("failed to open object file"); goto err_close_obj; } @@ -2251,7 +2261,7 @@ static char *profile_target_name(int tgt_fd) t = btf__type_by_id(btf, func_info.type_id); if (!t) { - p_err("btf %d doesn't have type %d", + p_err("btf %u doesn't have type %u", info.btf_id, func_info.type_id); goto out; } @@ -2329,7 +2339,7 @@ static int profile_open_perf_events(struct profiler_bpf *obj) continue; for (cpu = 0; cpu < obj->rodata->num_cpu; cpu++) { if (profile_open_perf_event(m, cpu, map_fd)) { - p_err("failed to create event %s on cpu %d", + p_err("failed to create event %s on cpu %u", metrics[m].name, cpu); return -1; } @@ -2473,6 +2483,7 @@ static int do_help(int argc, char **argv) " [map { idx IDX | name NAME } MAP]\\\n" " [pinmaps MAP_DIR]\n" " [autoattach]\n" + " [kernel_btf BTF_FILE]\n" " %1$s %2$s attach PROG ATTACH_TYPE [MAP]\n" " %1$s %2$s detach PROG ATTACH_TYPE [MAP]\n" " %1$s %2$s run PROG \\\n" diff --git a/tools/bpf/bpftool/tracelog.c b/tools/bpf/bpftool/tracelog.c index bf1f02212797..31d806e3bdaa 100644 --- a/tools/bpf/bpftool/tracelog.c +++ b/tools/bpf/bpftool/tracelog.c @@ -78,7 +78,7 @@ static bool get_tracefs_pipe(char *mnt) return false; /* Allow room for NULL terminating byte and pipe file name */ - snprintf(format, sizeof(format), "%%*s %%%zds %%99s %%*s %%*d %%*d\\n", + snprintf(format, sizeof(format), "%%*s %%%zus %%99s %%*s %%*d %%*d\\n", PATH_MAX - strlen(pipe_name) - 1); while (fscanf(fp, format, mnt, type) == 2) if (strcmp(type, fstype) == 0) { diff --git a/tools/bpf/bpftool/xlated_dumper.c b/tools/bpf/bpftool/xlated_dumper.c index d0094345fb2b..5e7cb8b36fef 100644 --- a/tools/bpf/bpftool/xlated_dumper.c +++ b/tools/bpf/bpftool/xlated_dumper.c @@ -199,13 +199,13 @@ static const char *print_imm(void *private_data, if (insn->src_reg == BPF_PSEUDO_MAP_FD) snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), - "map[id:%u]", insn->imm); + "map[id:%d]", insn->imm); else if (insn->src_reg == BPF_PSEUDO_MAP_VALUE) snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), - "map[id:%u][0]+%u", insn->imm, (insn + 1)->imm); + "map[id:%d][0]+%d", insn->imm, (insn + 1)->imm); else if (insn->src_reg == BPF_PSEUDO_MAP_IDX_VALUE) snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), - "map[idx:%u]+%u", insn->imm, (insn + 1)->imm); + "map[idx:%d]+%d", insn->imm, (insn + 1)->imm); else if (insn->src_reg == BPF_PSEUDO_FUNC) snprintf(dd->scratch_buff, sizeof(dd->scratch_buff), "subprog[%+d]", insn->imm); |