Skip to content

Commit 152e60e

Browse files
author
Alexei Starovoitov
committed
Merge branch 'bpftool: Add LLVM as default library for disassembling JIT-ed programs'
Quentin Monnet says: ==================== To disassemble instructions for JIT-ed programs, bpftool has relied on the libbfd library. This has been problematic in the past: libbfd's interface is not meant to be stable and has changed several times, hence the detection of the two related features from the Makefile (disassembler-four-args and disassembler-init-styled). When it comes to shipping bpftool, this has also caused issues with several distribution maintainers unwilling to support the feature (for example, Debian's page for binutils-dev, libbfd's package, says: "Note that building Debian packages which depend on the shared libbfd is Not Allowed."). This patchset adds support for LLVM as the primary library for disassembling instructions for JIT-ed programs. We keep libbfd as a fallback. One reason for this is that currently it works well, we have all we need in terms of features detection in the Makefile, so it provides a fallback for disassembling JIT-ed programs if libbfd is installed but LLVM is not. The other reason is that libbfd supports nfp instruction for Netronome's SmartNICs and can be used to disassemble offloaded programs, something that LLVM cannot do (Niklas confirmed that the feature is still in use). However, if libbfd's interface breaks again in the future, we might reconsider keeping support for it. v4: - Rebase to address a conflict with commit 2c76238 ("bpftool: Add "bootstrap" feature to version output"). v3: - Extend commit description (patch 6) with notes on llvm-dev and LLVM's disassembler stability. v2: - Pass callback when creating the LLVM disassembler, so that the branch targets are printed as addresses (instead of byte offsets). - Add last commit to "support" other arch with LLVM, although we don't know any supported triple yet. - Use $(LLVM_CONFIG) instead of llvm-config in Makefile. - Pass components to llvm-config --libs to limit the number of libraries to pass on the command line, in Makefile. - Rebase split of FEATURE_TESTS and FEATURE_DISPLAY in Makefile. ==================== Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 parents 8f4bc15 + 08b8191 commit 152e60e

File tree

12 files changed

+320
-106
lines changed

12 files changed

+320
-106
lines changed

tools/bpf/bpftool/Documentation/common_options.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
Print bpftool's version number (similar to **bpftool version**), the
88
number of the libbpf version in use, and optional features that were
99
included when bpftool was compiled. Optional features include linking
10-
against libbfd to provide the disassembler for JIT-ted programs
11-
(**bpftool prog dump jited**) and usage of BPF skeletons (some
12-
features like **bpftool prog profile** or showing pids associated to
13-
BPF objects may rely on it).
10+
against LLVM or libbfd to provide the disassembler for JIT-ted
11+
programs (**bpftool prog dump jited**) and usage of BPF skeletons
12+
(some features like **bpftool prog profile** or showing pids
13+
associated to BPF objects may rely on it).
1414

1515
-j, --json
1616
Generate JSON output. For commands that cannot produce JSON, this

tools/bpf/bpftool/Makefile

Lines changed: 49 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -93,11 +93,22 @@ INSTALL ?= install
9393
RM ?= rm -f
9494

9595
FEATURE_USER = .bpftool
96-
FEATURE_TESTS = libbfd libbfd-liberty libbfd-liberty-z \
97-
disassembler-four-args disassembler-init-styled libcap \
98-
clang-bpf-co-re
99-
FEATURE_DISPLAY = libbfd libbfd-liberty libbfd-liberty-z \
100-
libcap clang-bpf-co-re
96+
97+
FEATURE_TESTS := clang-bpf-co-re
98+
FEATURE_TESTS += llvm
99+
FEATURE_TESTS += libcap
100+
FEATURE_TESTS += libbfd
101+
FEATURE_TESTS += libbfd-liberty
102+
FEATURE_TESTS += libbfd-liberty-z
103+
FEATURE_TESTS += disassembler-four-args
104+
FEATURE_TESTS += disassembler-init-styled
105+
106+
FEATURE_DISPLAY := clang-bpf-co-re
107+
FEATURE_DISPLAY += llvm
108+
FEATURE_DISPLAY += libcap
109+
FEATURE_DISPLAY += libbfd
110+
FEATURE_DISPLAY += libbfd-liberty
111+
FEATURE_DISPLAY += libbfd-liberty-z
101112

102113
check_feat := 1
103114
NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
@@ -115,13 +126,6 @@ include $(FEATURES_DUMP)
115126
endif
116127
endif
117128

118-
ifeq ($(feature-disassembler-four-args), 1)
119-
CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
120-
endif
121-
ifeq ($(feature-disassembler-init-styled), 1)
122-
CFLAGS += -DDISASM_INIT_STYLED
123-
endif
124-
125129
LIBS = $(LIBBPF) -lelf -lz
126130
LIBS_BOOTSTRAP = $(LIBBPF_BOOTSTRAP) -lelf -lz
127131
ifeq ($(feature-libcap), 1)
@@ -133,21 +137,41 @@ include $(wildcard $(OUTPUT)*.d)
133137

134138
all: $(OUTPUT)bpftool
135139

136-
BFD_SRCS = jit_disasm.c
140+
SRCS := $(wildcard *.c)
137141

138-
SRCS = $(filter-out $(BFD_SRCS),$(wildcard *.c))
139-
140-
ifeq ($(feature-libbfd),1)
141-
LIBS += -lbfd -ldl -lopcodes
142-
else ifeq ($(feature-libbfd-liberty),1)
143-
LIBS += -lbfd -ldl -lopcodes -liberty
144-
else ifeq ($(feature-libbfd-liberty-z),1)
145-
LIBS += -lbfd -ldl -lopcodes -liberty -lz
142+
ifeq ($(feature-llvm),1)
143+
# If LLVM is available, use it for JIT disassembly
144+
CFLAGS += -DHAVE_LLVM_SUPPORT
145+
LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
146+
CFLAGS += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
147+
LIBS += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
148+
LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags)
149+
else
150+
# Fall back on libbfd
151+
ifeq ($(feature-libbfd),1)
152+
LIBS += -lbfd -ldl -lopcodes
153+
else ifeq ($(feature-libbfd-liberty),1)
154+
LIBS += -lbfd -ldl -lopcodes -liberty
155+
else ifeq ($(feature-libbfd-liberty-z),1)
156+
LIBS += -lbfd -ldl -lopcodes -liberty -lz
157+
endif
158+
159+
# If one of the above feature combinations is set, we support libbfd
160+
ifneq ($(filter -lbfd,$(LIBS)),)
161+
CFLAGS += -DHAVE_LIBBFD_SUPPORT
162+
163+
# Libbfd interface changed over time, figure out what we need
164+
ifeq ($(feature-disassembler-four-args), 1)
165+
CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
166+
endif
167+
ifeq ($(feature-disassembler-init-styled), 1)
168+
CFLAGS += -DDISASM_INIT_STYLED
169+
endif
170+
endif
146171
endif
147-
148-
ifneq ($(filter -lbfd,$(LIBS)),)
149-
CFLAGS += -DHAVE_LIBBFD_SUPPORT
150-
SRCS += $(BFD_SRCS)
172+
ifeq ($(filter -DHAVE_LLVM_SUPPORT -DHAVE_LIBBFD_SUPPORT,$(CFLAGS)),)
173+
# No support for JIT disassembly
174+
SRCS := $(filter-out jit_disasm.c,$(SRCS))
151175
endif
152176

153177
HOST_CFLAGS = $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\

tools/bpf/bpftool/common.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */
33

4+
#ifndef _GNU_SOURCE
45
#define _GNU_SOURCE
6+
#endif
57
#include <ctype.h>
68
#include <errno.h>
79
#include <fcntl.h>
@@ -625,12 +627,11 @@ static int read_sysfs_netdev_hex_int(char *devname, const char *entry_name)
625627
}
626628

627629
const char *
628-
ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
629-
const char **opt)
630+
ifindex_to_arch(__u32 ifindex, __u64 ns_dev, __u64 ns_ino, const char **opt)
630631
{
632+
__maybe_unused int device_id;
631633
char devname[IF_NAMESIZE];
632634
int vendor_id;
633-
int device_id;
634635

635636
if (!ifindex_to_name_ns(ifindex, ns_dev, ns_ino, devname)) {
636637
p_err("Can't get net device name for ifindex %d: %s", ifindex,
@@ -645,6 +646,7 @@ ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
645646
}
646647

647648
switch (vendor_id) {
649+
#ifdef HAVE_LIBBFD_SUPPORT
648650
case 0x19ee:
649651
device_id = read_sysfs_netdev_hex_int(devname, "device");
650652
if (device_id != 0x4000 &&
@@ -653,8 +655,10 @@ ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
653655
p_info("Unknown NFP device ID, assuming it is NFP-6xxx arch");
654656
*opt = "ctx4";
655657
return "NFP-6xxx";
658+
#endif /* HAVE_LIBBFD_SUPPORT */
659+
/* No NFP support in LLVM, we have no valid triple to return. */
656660
default:
657-
p_err("Can't get bfd arch name for device vendor id 0x%04x",
661+
p_err("Can't get arch name for device vendor id 0x%04x",
658662
vendor_id);
659663
return NULL;
660664
}

tools/bpf/bpftool/iter.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
22
// Copyright (C) 2020 Facebook
33

4+
#ifndef _GNU_SOURCE
45
#define _GNU_SOURCE
6+
#endif
57
#include <unistd.h>
68
#include <linux/err.h>
79
#include <bpf/libbpf.h>

0 commit comments

Comments
 (0)