* [bpf-next V3 PATCH 1/5] bpf: Sync kernel ABI header with tooling header for bpf_common.h
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
@ 2018-02-08 11:48 ` Jesper Dangaard Brouer
2018-02-08 14:17 ` Arnaldo Carvalho de Melo
2018-02-08 11:48 ` [bpf-next V3 PATCH 2/5] tools/libbpf: improve the pr_debug statements to contain section numbers Jesper Dangaard Brouer
` (4 subsequent siblings)
5 siblings, 1 reply; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-08 11:48 UTC (permalink / raw)
To: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, Jesper Dangaard Brouer, yhs
I recently fixed up a lot of commits that forgot to keep the tooling
headers in sync. And then I forgot to do the same thing in commit
cb5f7334d479 ("bpf: add comments to BPF ld/ldx sizes"). Let correct
that before people notice ;-).
Lawrence did partly fix/sync this for bpf.h in commit d6d4f60c3a09
("bpf: add selftest for tcpbpf").
Fixes: cb5f7334d479 ("bpf: add comments to BPF ld/ldx sizes")
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/include/uapi/linux/bpf_common.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/tools/include/uapi/linux/bpf_common.h b/tools/include/uapi/linux/bpf_common.h
index 18be90725ab0..ee97668bdadb 100644
--- a/tools/include/uapi/linux/bpf_common.h
+++ b/tools/include/uapi/linux/bpf_common.h
@@ -15,9 +15,10 @@
/* ld/ldx fields */
#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
+#define BPF_W 0x00 /* 32-bit */
+#define BPF_H 0x08 /* 16-bit */
+#define BPF_B 0x10 /* 8-bit */
+/* eBPF BPF_DW 0x18 64-bit */
#define BPF_MODE(code) ((code) & 0xe0)
#define BPF_IMM 0x00
#define BPF_ABS 0x20
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [bpf-next V3 PATCH 1/5] bpf: Sync kernel ABI header with tooling header for bpf_common.h
2018-02-08 11:48 ` [bpf-next V3 PATCH 1/5] bpf: Sync kernel ABI header with tooling header for bpf_common.h Jesper Dangaard Brouer
@ 2018-02-08 14:17 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 10+ messages in thread
From: Arnaldo Carvalho de Melo @ 2018-02-08 14:17 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0,
jakub.kicinski, joe, eric, yhs, Ingo Molnar, Jiri Olsa
Em Thu, Feb 08, 2018 at 12:48:12PM +0100, Jesper Dangaard Brouer escreveu:
> I recently fixed up a lot of commits that forgot to keep the tooling
> headers in sync. And then I forgot to do the same thing in commit
> cb5f7334d479 ("bpf: add comments to BPF ld/ldx sizes"). Let correct
> that before people notice ;-).
>
> Lawrence did partly fix/sync this for bpf.h in commit d6d4f60c3a09
> ("bpf: add selftest for tcpbpf").
>
> Fixes: cb5f7334d479 ("bpf: add comments to BPF ld/ldx sizes")
We don't consider a bug to forget to update the tooling headers copy of
the files, i.e. its not a strict requirement on kernel developers to
care about tools/ :-)
I, for one, like to get the warning, its an opportunity for me to see
that something changed and that I should pay attention to see if
something needs to be done in the tooling side.
- Arnaldo
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
> ---
> tools/include/uapi/linux/bpf_common.h | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> diff --git a/tools/include/uapi/linux/bpf_common.h b/tools/include/uapi/linux/bpf_common.h
> index 18be90725ab0..ee97668bdadb 100644
> --- a/tools/include/uapi/linux/bpf_common.h
> +++ b/tools/include/uapi/linux/bpf_common.h
> @@ -15,9 +15,10 @@
>
> /* ld/ldx fields */
> #define BPF_SIZE(code) ((code) & 0x18)
> -#define BPF_W 0x00
> -#define BPF_H 0x08
> -#define BPF_B 0x10
> +#define BPF_W 0x00 /* 32-bit */
> +#define BPF_H 0x08 /* 16-bit */
> +#define BPF_B 0x10 /* 8-bit */
> +/* eBPF BPF_DW 0x18 64-bit */
> #define BPF_MODE(code) ((code) & 0xe0)
> #define BPF_IMM 0x00
> #define BPF_ABS 0x20
^ permalink raw reply [flat|nested] 10+ messages in thread
* [bpf-next V3 PATCH 2/5] tools/libbpf: improve the pr_debug statements to contain section numbers
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 1/5] bpf: Sync kernel ABI header with tooling header for bpf_common.h Jesper Dangaard Brouer
@ 2018-02-08 11:48 ` Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 3/5] selftests/bpf: add test program for loading BPF ELF files Jesper Dangaard Brouer
` (3 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-08 11:48 UTC (permalink / raw)
To: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, Jesper Dangaard Brouer, yhs
While debugging a bpf ELF loading issue, I needed to correlate the
ELF section number with the failed relocation section reference.
Thus, add section numbers/index to the pr_debug.
In debug mode, also print section that were skipped. This helped
me identify that a section (.eh_frame) was skipped, and this was
the reason the relocation section (.rel.eh_frame) could not find
that section number.
The section numbers corresponds to the readelf tools Section Headers [Nr].
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/lib/bpf/libbpf.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index 30c776375118..b4eeaa3ebff5 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -315,8 +315,8 @@ bpf_program__init(void *data, size_t size, char *section_name, int idx,
prog->section_name = strdup(section_name);
if (!prog->section_name) {
- pr_warning("failed to alloc name for prog under section %s\n",
- section_name);
+ pr_warning("failed to alloc name for prog under section(%d) %s\n",
+ idx, section_name);
goto errout;
}
@@ -759,29 +759,29 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
idx++;
if (gelf_getshdr(scn, &sh) != &sh) {
- pr_warning("failed to get section header from %s\n",
- obj->path);
+ pr_warning("failed to get section(%d) header from %s\n",
+ idx, obj->path);
err = -LIBBPF_ERRNO__FORMAT;
goto out;
}
name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
if (!name) {
- pr_warning("failed to get section name from %s\n",
- obj->path);
+ pr_warning("failed to get section(%d) name from %s\n",
+ idx, obj->path);
err = -LIBBPF_ERRNO__FORMAT;
goto out;
}
data = elf_getdata(scn, 0);
if (!data) {
- pr_warning("failed to get section data from %s(%s)\n",
- name, obj->path);
+ pr_warning("failed to get section(%d) data from %s(%s)\n",
+ idx, name, obj->path);
err = -LIBBPF_ERRNO__FORMAT;
goto out;
}
- pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
- name, (unsigned long)data->d_size,
+ pr_debug("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
+ idx, name, (unsigned long)data->d_size,
(int)sh.sh_link, (unsigned long)sh.sh_flags,
(int)sh.sh_type);
@@ -836,6 +836,8 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
obj->efile.reloc[n].shdr = sh;
obj->efile.reloc[n].data = data;
}
+ } else {
+ pr_debug("skip section(%d) %s\n", idx, name);
}
if (err)
goto out;
@@ -1115,8 +1117,7 @@ static int bpf_object__collect_reloc(struct bpf_object *obj)
prog = bpf_object__find_prog_by_idx(obj, idx);
if (!prog) {
- pr_warning("relocation failed: no %d section\n",
- idx);
+ pr_warning("relocation failed: no section(%d)\n", idx);
return -LIBBPF_ERRNO__RELOC;
}
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [bpf-next V3 PATCH 3/5] selftests/bpf: add test program for loading BPF ELF files
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 1/5] bpf: Sync kernel ABI header with tooling header for bpf_common.h Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 2/5] tools/libbpf: improve the pr_debug statements to contain section numbers Jesper Dangaard Brouer
@ 2018-02-08 11:48 ` Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 4/5] selftests/bpf: add selftest that use test_libbpf_open Jesper Dangaard Brouer
` (2 subsequent siblings)
5 siblings, 0 replies; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-08 11:48 UTC (permalink / raw)
To: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, Jesper Dangaard Brouer, yhs
V2: Moved program into selftests/bpf from tools/libbpf
This program can be used on its own for testing/debugging if a
BPF ELF-object file can be loaded with libbpf (from tools/lib/bpf).
If something is wrong with the ELF object, the program have
a --debug mode that will display the ELF sections and especially
the skipped sections. This allows for quickly identifying the
problematic ELF section number, which can be corrolated with the
readelf tool.
The program signal error via return codes, and also have
a --quiet mode, which is practical for use in scripts like
selftests/bpf.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/testing/selftests/bpf/Makefile | 2
tools/testing/selftests/bpf/test_libbpf_open.c | 150 ++++++++++++++++++++++++
2 files changed, 151 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/test_libbpf_open.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index bf05bc5e36e5..de7b85e2e532 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -20,7 +20,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \
test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
- sample_map_ret0.o test_tcpbpf_kern.o
+ sample_map_ret0.o test_tcpbpf_kern.o test_libbpf_open
TEST_PROGS := test_kmod.sh test_xdp_redirect.sh test_xdp_meta.sh \
test_offload.py
diff --git a/tools/testing/selftests/bpf/test_libbpf_open.c b/tools/testing/selftests/bpf/test_libbpf_open.c
new file mode 100644
index 000000000000..8fcd1c076add
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_libbpf_open.c
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: GPL-2.0
+ * Copyright (c) 2018 Jesper Dangaard Brouer, Red Hat Inc.
+ */
+static const char *__doc__ =
+ "Libbpf test program for loading BPF ELF object files";
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <bpf/libbpf.h>
+#include <getopt.h>
+
+static const struct option long_options[] = {
+ {"help", no_argument, NULL, 'h' },
+ {"debug", no_argument, NULL, 'D' },
+ {"quiet", no_argument, NULL, 'q' },
+ {0, 0, NULL, 0 }
+};
+
+static void usage(char *argv[])
+{
+ int i;
+
+ printf("\nDOCUMENTATION:\n%s\n\n", __doc__);
+ printf(" Usage: %s (options-see-below) BPF_FILE\n", argv[0]);
+ printf(" Listing options:\n");
+ for (i = 0; long_options[i].name != 0; i++) {
+ printf(" --%-12s", long_options[i].name);
+ printf(" short-option: -%c",
+ long_options[i].val);
+ printf("\n");
+ }
+ printf("\n");
+}
+
+#define DEFINE_PRINT_FN(name, enabled) \
+static int libbpf_##name(const char *fmt, ...) \
+{ \
+ va_list args; \
+ int ret; \
+ \
+ va_start(args, fmt); \
+ if (enabled) { \
+ fprintf(stderr, "[" #name "] "); \
+ ret = vfprintf(stderr, fmt, args); \
+ } \
+ va_end(args); \
+ return ret; \
+}
+DEFINE_PRINT_FN(warning, 1)
+DEFINE_PRINT_FN(info, 1)
+DEFINE_PRINT_FN(debug, 1)
+
+#define EXIT_FAIL_LIBBPF EXIT_FAILURE
+#define EXIT_FAIL_OPTION 2
+
+int test_walk_progs(struct bpf_object *obj, bool verbose)
+{
+ struct bpf_program *prog;
+ int cnt = 0;
+
+ bpf_object__for_each_program(prog, obj) {
+ cnt++;
+ if (verbose)
+ printf("Prog (count:%d) section_name: %s\n", cnt,
+ bpf_program__title(prog, false));
+ }
+ return 0;
+}
+
+int test_walk_maps(struct bpf_object *obj, bool verbose)
+{
+ struct bpf_map *map;
+ int cnt = 0;
+
+ bpf_map__for_each(map, obj) {
+ cnt++;
+ if (verbose)
+ printf("Map (count:%d) name: %s\n", cnt,
+ bpf_map__name(map));
+ }
+ return 0;
+}
+
+int test_open_file(char *filename, bool verbose)
+{
+ struct bpf_object *bpfobj = NULL;
+ long err;
+
+ if (verbose)
+ printf("Open BPF ELF-file with libbpf: %s\n", filename);
+
+ /* Load BPF ELF object file and check for errors */
+ bpfobj = bpf_object__open(filename);
+ err = libbpf_get_error(bpfobj);
+ if (err) {
+ char err_buf[128];
+ libbpf_strerror(err, err_buf, sizeof(err_buf));
+ if (verbose)
+ printf("Unable to load eBPF objects in file '%s': %s\n",
+ filename, err_buf);
+ return EXIT_FAIL_LIBBPF;
+ }
+ test_walk_progs(bpfobj, verbose);
+ test_walk_maps(bpfobj, verbose);
+
+ if (verbose)
+ printf("Close BPF ELF-file with libbpf: %s\n",
+ bpf_object__name(bpfobj));
+ bpf_object__close(bpfobj);
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ char filename[1024] = { 0 };
+ bool verbose = 1;
+ int longindex = 0;
+ int opt;
+
+ libbpf_set_print(libbpf_warning, libbpf_info, NULL);
+
+ /* Parse commands line args */
+ while ((opt = getopt_long(argc, argv, "hDq",
+ long_options, &longindex)) != -1) {
+ switch (opt) {
+ case 'D':
+ libbpf_set_print(libbpf_warning, libbpf_info,
+ libbpf_debug);
+ break;
+ case 'q': /* Use in scripting mode */
+ verbose = 0;
+ break;
+ case 'h':
+ default:
+ usage(argv);
+ return EXIT_FAIL_OPTION;
+ }
+ }
+ if (optind >= argc) {
+ usage(argv);
+ printf("ERROR: Expected BPF_FILE argument after options\n");
+ return EXIT_FAIL_OPTION;
+ }
+ snprintf(filename, sizeof(filename), "%s", argv[optind]);
+
+ return test_open_file(filename, verbose);
+}
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [bpf-next V3 PATCH 4/5] selftests/bpf: add selftest that use test_libbpf_open
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
` (2 preceding siblings ...)
2018-02-08 11:48 ` [bpf-next V3 PATCH 3/5] selftests/bpf: add test program for loading BPF ELF files Jesper Dangaard Brouer
@ 2018-02-08 11:48 ` Jesper Dangaard Brouer
2018-02-08 11:48 ` [bpf-next V3 PATCH 5/5] tools/libbpf: handle issues with bpf ELF objects containing .eh_frames Jesper Dangaard Brouer
2018-02-09 1:32 ` [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Daniel Borkmann
5 siblings, 0 replies; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-08 11:48 UTC (permalink / raw)
To: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, Jesper Dangaard Brouer, yhs
This script test_libbpf.sh will be part of the 'make run_tests'
invocation, but can also be invoked manually in this directory,
and a verbose mode can be enabled via setting the environment
variable $VERBOSE like:
$ VERBOSE=yes ./test_libbpf.sh
The script contains some tests that are commented out, as they
currently fail. They are reminders about what we need to improve
for the libbpf loader library.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/testing/selftests/bpf/Makefile | 14 +++++++-
tools/testing/selftests/bpf/test_libbpf.sh | 49 ++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 2 deletions(-)
create mode 100755 tools/testing/selftests/bpf/test_libbpf.sh
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index de7b85e2e532..8b5667714250 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -13,6 +13,7 @@ endif
CFLAGS += -Wall -O2 -I$(APIDIR) -I$(LIBDIR) -I$(GENDIR) $(GENFLAGS) -I../../../include
LDLIBS += -lcap -lelf -lrt -lpthread
+# Order correspond to 'make run_tests' order
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
test_align test_verifier_log test_dev_cgroup test_tcpbpf_user
@@ -20,17 +21,26 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
test_pkt_md_access.o test_xdp_redirect.o test_xdp_meta.o sockmap_parse_prog.o \
sockmap_verdict_prog.o dev_cgroup.o sample_ret0.o test_tracepoint.o \
test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
- sample_map_ret0.o test_tcpbpf_kern.o test_libbpf_open
+ sample_map_ret0.o test_tcpbpf_kern.o
-TEST_PROGS := test_kmod.sh test_xdp_redirect.sh test_xdp_meta.sh \
+# Order correspond to 'make run_tests' order
+TEST_PROGS := test_kmod.sh \
+ test_libbpf.sh \
+ test_xdp_redirect.sh \
+ test_xdp_meta.sh \
test_offload.py
+# Compile but not part of 'make run_tests'
+TEST_GEN_PROGS_EXTENDED = test_libbpf_open
+
include ../lib.mk
BPFOBJ := $(OUTPUT)/libbpf.a $(OUTPUT)/cgroup_helpers.c
$(TEST_GEN_PROGS): $(BPFOBJ)
+$(TEST_GEN_PROGS_EXTENDED): $(OUTPUT)/libbpf.a
+
.PHONY: force
# force a rebuild of BPFOBJ when its dependencies are updated
diff --git a/tools/testing/selftests/bpf/test_libbpf.sh b/tools/testing/selftests/bpf/test_libbpf.sh
new file mode 100755
index 000000000000..d97dc914cd49
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_libbpf.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+
+export TESTNAME=test_libbpf
+
+# Determine selftest success via shell exit code
+exit_handler()
+{
+ if (( $? == 0 )); then
+ echo "selftests: $TESTNAME [PASS]";
+ else
+ echo "$TESTNAME: failed at file $LAST_LOADED" 1>&2
+ echo "selftests: $TESTNAME [FAILED]";
+ fi
+}
+
+libbpf_open_file()
+{
+ LAST_LOADED=$1
+ if [ -n "$VERBOSE" ]; then
+ ./test_libbpf_open $1
+ else
+ ./test_libbpf_open --quiet $1
+ fi
+}
+
+# Exit script immediately (well catched by trap handler) if any
+# program/thing exits with a non-zero status.
+set -e
+
+# (Use 'trap -l' to list meaning of numbers)
+trap exit_handler 0 2 3 6 9
+
+libbpf_open_file test_l4lb.o
+
+# TODO: fix libbpf to load noinline functions
+# [warning] libbpf: incorrect bpf_call opcode
+#libbpf_open_file test_l4lb_noinline.o
+
+# TODO: fix test_xdp_meta.c to load with libbpf
+# [warning] libbpf: test_xdp_meta.o doesn't provide kernel version
+#libbpf_open_file test_xdp_meta.o
+
+# TODO: fix libbpf to handle .eh_frame
+# [warning] libbpf: relocation failed: no section(10)
+#libbpf_open_file ../../../../samples/bpf/tracex3_kern.o
+
+# Success
+exit 0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [bpf-next V3 PATCH 5/5] tools/libbpf: handle issues with bpf ELF objects containing .eh_frames
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
` (3 preceding siblings ...)
2018-02-08 11:48 ` [bpf-next V3 PATCH 4/5] selftests/bpf: add selftest that use test_libbpf_open Jesper Dangaard Brouer
@ 2018-02-08 11:48 ` Jesper Dangaard Brouer
2018-02-09 1:32 ` [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Daniel Borkmann
5 siblings, 0 replies; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-08 11:48 UTC (permalink / raw)
To: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, Jesper Dangaard Brouer, yhs
V3: More generic skipping of relo-section (suggested by Daniel)
If clang >= 4.0.1 is missing the option '-target bpf', it will cause
llc/llvm to create two ELF sections for "Exception Frames", with
section names '.eh_frame' and '.rel.eh_frame'.
The BPF ELF loader library libbpf fails when loading files with these
sections. The other in-kernel BPF ELF loader in samples/bpf/bpf_load.c,
handle this gracefully. And iproute2 loader also seems to work with these
"eh" sections.
The issue in libbpf is caused by bpf_object__elf_collect() skipping
some sections, and later when performing relocation it will be
pointing to a skipped section, as these sections cannot be found by
bpf_object__find_prog_by_idx() in bpf_object__collect_reloc().
This is a general issue that also occurs for other sections, like
debug sections which are also skipped and can have relo section.
As suggested by Daniel. To avoid keeping state about all skipped
sections, instead perform a direct qlookup in the ELF object. Lookup
the section that the relo-section points to and check if it contains
executable machine instructions (denoted by the sh_flags
SHF_EXECINSTR). Use this check to also skip irrelevant relo-sections.
Note, for samples/bpf/ the '-target bpf' parameter to clang cannot be used
due to incompatibility with asm embedded headers, that some of the samples
include. This is explained in more details by Yonghong Song in bpf_devel_QA.
Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
tools/lib/bpf/libbpf.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c
index b4eeaa3ebff5..661147773dcb 100644
--- a/tools/lib/bpf/libbpf.c
+++ b/tools/lib/bpf/libbpf.c
@@ -738,6 +738,24 @@ bpf_object__init_maps(struct bpf_object *obj)
return 0;
}
+static bool section_have_execinstr(struct bpf_object *obj, int idx)
+{
+ Elf_Scn *scn;
+ GElf_Shdr sh;
+
+ scn = elf_getscn(obj->efile.elf, idx);
+ if (!scn)
+ return false;
+
+ if (gelf_getshdr(scn, &sh) != &sh)
+ return false;
+
+ if (sh.sh_flags & SHF_EXECINSTR)
+ return true;
+
+ return false;
+}
+
static int bpf_object__elf_collect(struct bpf_object *obj)
{
Elf *elf = obj->efile.elf;
@@ -821,6 +839,14 @@ static int bpf_object__elf_collect(struct bpf_object *obj)
} else if (sh.sh_type == SHT_REL) {
void *reloc = obj->efile.reloc;
int nr_reloc = obj->efile.nr_reloc + 1;
+ int sec = sh.sh_info; /* points to other section */
+
+ /* Only do relo for section with exec instructions */
+ if (!section_have_execinstr(obj, sec)) {
+ pr_debug("skip relo %s(%d) for section(%d)\n",
+ name, idx, sec);
+ continue;
+ }
reloc = realloc(reloc,
sizeof(*obj->efile.reloc) * nr_reloc);
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests
2018-02-08 11:48 [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Jesper Dangaard Brouer
` (4 preceding siblings ...)
2018-02-08 11:48 ` [bpf-next V3 PATCH 5/5] tools/libbpf: handle issues with bpf ELF objects containing .eh_frames Jesper Dangaard Brouer
@ 2018-02-09 1:32 ` Daniel Borkmann
2018-02-09 8:18 ` Jesper Dangaard Brouer
5 siblings, 1 reply; 10+ messages in thread
From: Daniel Borkmann @ 2018-02-09 1:32 UTC (permalink / raw)
To: Jesper Dangaard Brouer, netdev, Daniel Borkmann,
Alexei Starovoitov, wangnan0
Cc: jakub.kicinski, joe, acme, eric, yhs
On 02/08/2018 12:48 PM, Jesper Dangaard Brouer wrote:
> While playing with using libbpf for the Suricata project, we had
> issues LLVM >= 4.0.1 generating ELF files that could not be loaded
> with libbpf (tools/lib/bpf/).
>
> During the troubleshooting phase, I wrote a test program and improved
> the debugging output in libbpf. I turned this into a selftests
> program, and it also serves as a code example for libbpf in itself.
>
> I discovered that there are at least three ELF load issues with
> libbpf. I left them as TODO comments in (tools/testing/selftests/bpf)
> test_libbpf.sh. I've only fixed the load issue with eh_frames, and
> other types of relo-section that does not have exec flags. We can
> work on the other issues later.
Applied it to bpf tree, thanks Jesper!
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests
2018-02-09 1:32 ` [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests Daniel Borkmann
@ 2018-02-09 8:18 ` Jesper Dangaard Brouer
2018-02-09 11:50 ` Daniel Borkmann
0 siblings, 1 reply; 10+ messages in thread
From: Jesper Dangaard Brouer @ 2018-02-09 8:18 UTC (permalink / raw)
To: Daniel Borkmann
Cc: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0,
jakub.kicinski, joe, acme, eric, yhs, brouer
On Fri, 9 Feb 2018 02:32:27 +0100
Daniel Borkmann <daniel@iogearbox.net> wrote:
> On 02/08/2018 12:48 PM, Jesper Dangaard Brouer wrote:
> > While playing with using libbpf for the Suricata project, we had
> > issues LLVM >= 4.0.1 generating ELF files that could not be loaded
> > with libbpf (tools/lib/bpf/).
> >
> > During the troubleshooting phase, I wrote a test program and improved
> > the debugging output in libbpf. I turned this into a selftests
> > program, and it also serves as a code example for libbpf in itself.
> >
> > I discovered that there are at least three ELF load issues with
> > libbpf. I left them as TODO comments in (tools/testing/selftests/bpf)
> > test_libbpf.sh. I've only fixed the load issue with eh_frames, and
> > other types of relo-section that does not have exec flags. We can
> > work on the other issues later.
>
> Applied it to bpf tree, thanks Jesper!
Thank you for applying this the 'bpf' tree! -- appreciate it!
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [bpf-next V3 PATCH 0/5] tools/libbpf improvements and selftests
2018-02-09 8:18 ` Jesper Dangaard Brouer
@ 2018-02-09 11:50 ` Daniel Borkmann
0 siblings, 0 replies; 10+ messages in thread
From: Daniel Borkmann @ 2018-02-09 11:50 UTC (permalink / raw)
To: Jesper Dangaard Brouer
Cc: netdev, Daniel Borkmann, Alexei Starovoitov, wangnan0,
jakub.kicinski, joe, acme, eric, yhs
On 02/09/2018 09:18 AM, Jesper Dangaard Brouer wrote:
> On Fri, 9 Feb 2018 02:32:27 +0100
> Daniel Borkmann <daniel@iogearbox.net> wrote:
>
>> On 02/08/2018 12:48 PM, Jesper Dangaard Brouer wrote:
>>> While playing with using libbpf for the Suricata project, we had
>>> issues LLVM >= 4.0.1 generating ELF files that could not be loaded
>>> with libbpf (tools/lib/bpf/).
>>>
>>> During the troubleshooting phase, I wrote a test program and improved
>>> the debugging output in libbpf. I turned this into a selftests
>>> program, and it also serves as a code example for libbpf in itself.
>>>
>>> I discovered that there are at least three ELF load issues with
>>> libbpf. I left them as TODO comments in (tools/testing/selftests/bpf)
>>> test_libbpf.sh. I've only fixed the load issue with eh_frames, and
>>> other types of relo-section that does not have exec flags. We can
>>> work on the other issues later.
>>
>> Applied it to bpf tree, thanks Jesper!
>
> Thank you for applying this the 'bpf' tree! -- appreciate it!
Btw, if you have a chance to send a small doc update for the
Documentation/bpf/bpf_devel_QA.txt and describe somewhere in
the LLVM section of the doc the discussed issue around
gnu/stubs-32.h with possible workarounds, that would be great.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 10+ messages in thread