Skip to content

Commit

Permalink
Merge branch 'bpftool: Add LLVM as default library for disassembling …
Browse files Browse the repository at this point in the history
…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 <[email protected]>
  • Loading branch information
Alexei Starovoitov committed Oct 25, 2022
2 parents 8f4bc15 + 08b8191 commit 152e60e
Show file tree
Hide file tree
Showing 12 changed files with 320 additions and 106 deletions.
8 changes: 4 additions & 4 deletions tools/bpf/bpftool/Documentation/common_options.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
Print bpftool's version number (similar to **bpftool version**), the
number of the libbpf version in use, and optional features that were
included when bpftool was compiled. Optional features include linking
against libbfd to provide the disassembler for JIT-ted programs
(**bpftool prog dump jited**) and usage of BPF skeletons (some
features like **bpftool prog profile** or showing pids associated to
BPF objects may rely on it).
against LLVM or libbfd to provide the disassembler for JIT-ted
programs (**bpftool prog dump jited**) and usage of BPF skeletons
(some features like **bpftool prog profile** or showing pids
associated to BPF objects may rely on it).

-j, --json
Generate JSON output. For commands that cannot produce JSON, this
Expand Down
74 changes: 49 additions & 25 deletions tools/bpf/bpftool/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,22 @@ INSTALL ?= install
RM ?= rm -f

FEATURE_USER = .bpftool
FEATURE_TESTS = libbfd libbfd-liberty libbfd-liberty-z \
disassembler-four-args disassembler-init-styled libcap \
clang-bpf-co-re
FEATURE_DISPLAY = libbfd libbfd-liberty libbfd-liberty-z \
libcap clang-bpf-co-re

FEATURE_TESTS := clang-bpf-co-re
FEATURE_TESTS += llvm
FEATURE_TESTS += libcap
FEATURE_TESTS += libbfd
FEATURE_TESTS += libbfd-liberty
FEATURE_TESTS += libbfd-liberty-z
FEATURE_TESTS += disassembler-four-args
FEATURE_TESTS += disassembler-init-styled

FEATURE_DISPLAY := clang-bpf-co-re
FEATURE_DISPLAY += llvm
FEATURE_DISPLAY += libcap
FEATURE_DISPLAY += libbfd
FEATURE_DISPLAY += libbfd-liberty
FEATURE_DISPLAY += libbfd-liberty-z

check_feat := 1
NON_CHECK_FEAT_TARGETS := clean uninstall doc doc-clean doc-install doc-uninstall
Expand All @@ -115,13 +126,6 @@ include $(FEATURES_DUMP)
endif
endif

ifeq ($(feature-disassembler-four-args), 1)
CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
endif
ifeq ($(feature-disassembler-init-styled), 1)
CFLAGS += -DDISASM_INIT_STYLED
endif

LIBS = $(LIBBPF) -lelf -lz
LIBS_BOOTSTRAP = $(LIBBPF_BOOTSTRAP) -lelf -lz
ifeq ($(feature-libcap), 1)
Expand All @@ -133,21 +137,41 @@ include $(wildcard $(OUTPUT)*.d)

all: $(OUTPUT)bpftool

BFD_SRCS = jit_disasm.c
SRCS := $(wildcard *.c)

SRCS = $(filter-out $(BFD_SRCS),$(wildcard *.c))

ifeq ($(feature-libbfd),1)
LIBS += -lbfd -ldl -lopcodes
else ifeq ($(feature-libbfd-liberty),1)
LIBS += -lbfd -ldl -lopcodes -liberty
else ifeq ($(feature-libbfd-liberty-z),1)
LIBS += -lbfd -ldl -lopcodes -liberty -lz
ifeq ($(feature-llvm),1)
# If LLVM is available, use it for JIT disassembly
CFLAGS += -DHAVE_LLVM_SUPPORT
LLVM_CONFIG_LIB_COMPONENTS := mcdisassembler all-targets
CFLAGS += $(shell $(LLVM_CONFIG) --cflags --libs $(LLVM_CONFIG_LIB_COMPONENTS))
LIBS += $(shell $(LLVM_CONFIG) --libs $(LLVM_CONFIG_LIB_COMPONENTS))
LDFLAGS += $(shell $(LLVM_CONFIG) --ldflags)
else
# Fall back on libbfd
ifeq ($(feature-libbfd),1)
LIBS += -lbfd -ldl -lopcodes
else ifeq ($(feature-libbfd-liberty),1)
LIBS += -lbfd -ldl -lopcodes -liberty
else ifeq ($(feature-libbfd-liberty-z),1)
LIBS += -lbfd -ldl -lopcodes -liberty -lz
endif

# If one of the above feature combinations is set, we support libbfd
ifneq ($(filter -lbfd,$(LIBS)),)
CFLAGS += -DHAVE_LIBBFD_SUPPORT

# Libbfd interface changed over time, figure out what we need
ifeq ($(feature-disassembler-four-args), 1)
CFLAGS += -DDISASM_FOUR_ARGS_SIGNATURE
endif
ifeq ($(feature-disassembler-init-styled), 1)
CFLAGS += -DDISASM_INIT_STYLED
endif
endif
endif

ifneq ($(filter -lbfd,$(LIBS)),)
CFLAGS += -DHAVE_LIBBFD_SUPPORT
SRCS += $(BFD_SRCS)
ifeq ($(filter -DHAVE_LLVM_SUPPORT -DHAVE_LIBBFD_SUPPORT,$(CFLAGS)),)
# No support for JIT disassembly
SRCS := $(filter-out jit_disasm.c,$(SRCS))
endif

HOST_CFLAGS = $(subst -I$(LIBBPF_INCLUDE),-I$(LIBBPF_BOOTSTRAP_INCLUDE),\
Expand Down
12 changes: 8 additions & 4 deletions tools/bpf/bpftool/common.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/* Copyright (C) 2017-2018 Netronome Systems, Inc. */

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
Expand Down Expand Up @@ -625,12 +627,11 @@ static int read_sysfs_netdev_hex_int(char *devname, const char *entry_name)
}

const char *
ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
const char **opt)
ifindex_to_arch(__u32 ifindex, __u64 ns_dev, __u64 ns_ino, const char **opt)
{
__maybe_unused int device_id;
char devname[IF_NAMESIZE];
int vendor_id;
int device_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,
Expand All @@ -645,6 +646,7 @@ ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
}

switch (vendor_id) {
#ifdef HAVE_LIBBFD_SUPPORT
case 0x19ee:
device_id = read_sysfs_netdev_hex_int(devname, "device");
if (device_id != 0x4000 &&
Expand All @@ -653,8 +655,10 @@ ifindex_to_bfd_params(__u32 ifindex, __u64 ns_dev, __u64 ns_ino,
p_info("Unknown NFP device ID, assuming it is NFP-6xxx arch");
*opt = "ctx4";
return "NFP-6xxx";
#endif /* HAVE_LIBBFD_SUPPORT */
/* No NFP support in LLVM, we have no valid triple to return. */
default:
p_err("Can't get bfd arch name for device vendor id 0x%04x",
p_err("Can't get arch name for device vendor id 0x%04x",
vendor_id);
return NULL;
}
Expand Down
2 changes: 2 additions & 0 deletions tools/bpf/bpftool/iter.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
// Copyright (C) 2020 Facebook

#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <unistd.h>
#include <linux/err.h>
#include <bpf/libbpf.h>
Expand Down
Loading

0 comments on commit 152e60e

Please sign in to comment.