Signed-off-by: Jesper Dangaard Brouer <bro...@redhat.com>
---
 0 files changed

diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile
index 83714ca1f22b..f968702f4ef6 100644
--- a/tools/lib/bpf/Makefile
+++ b/tools/lib/bpf/Makefile
@@ -147,11 +147,11 @@ LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE))
 
 CMD_TARGETS = $(LIB_FILE)
 
-TARGETS = $(CMD_TARGETS)
+TARGETS = $(CMD_TARGETS) test_libbpf_open
 
 all: fixdep all_cmd
 
-all_cmd: $(CMD_TARGETS)
+all_cmd: $(TARGETS)
 
 $(BPF_IN): force elfdep bpfdep
        @(test -f ../../include/uapi/linux/bpf.h -a -f 
../../../include/uapi/linux/bpf.h && ( \
@@ -168,6 +168,9 @@ $(OUTPUT)libbpf.so: $(BPF_IN)
 $(OUTPUT)libbpf.a: $(BPF_IN)
        $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^
 
+test_libbpf_open: test_libbpf_open.c $(OUTPUT)libbpf.a
+       $(QUIET_LINK)$(CC) -lelf -Wall $< $(OUTPUT)libbpf.a -o $(OUTPUT)$@
+
 define do_install
        if [ ! -d '$(DESTDIR_SQ)$2' ]; then             \
                $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \
diff --git a/tools/lib/bpf/test_libbpf_open.c b/tools/lib/bpf/test_libbpf_open.c
new file mode 100644
index 000000000000..8fcd1c076add
--- /dev/null
+++ b/tools/lib/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);
+}

Reply via email to