linux/tools/testing/selftests/bpf/test_libbpf_open.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0
   2 * Copyright (c) 2018 Jesper Dangaard Brouer, Red Hat Inc.
   3 */
   4static const char *__doc__ =
   5        "Libbpf test program for loading BPF ELF object files";
   6
   7#include <stdlib.h>
   8#include <stdio.h>
   9#include <string.h>
  10#include <stdarg.h>
  11#include <bpf/libbpf.h>
  12#include <getopt.h>
  13
  14static const struct option long_options[] = {
  15        {"help",        no_argument,            NULL, 'h' },
  16        {"debug",       no_argument,            NULL, 'D' },
  17        {"quiet",       no_argument,            NULL, 'q' },
  18        {0, 0, NULL,  0 }
  19};
  20
  21static void usage(char *argv[])
  22{
  23        int i;
  24
  25        printf("\nDOCUMENTATION:\n%s\n\n", __doc__);
  26        printf(" Usage: %s (options-see-below) BPF_FILE\n", argv[0]);
  27        printf(" Listing options:\n");
  28        for (i = 0; long_options[i].name != 0; i++) {
  29                printf(" --%-12s", long_options[i].name);
  30                printf(" short-option: -%c",
  31                       long_options[i].val);
  32                printf("\n");
  33        }
  34        printf("\n");
  35}
  36
  37#define DEFINE_PRINT_FN(name, enabled) \
  38static int libbpf_##name(const char *fmt, ...)          \
  39{                                                       \
  40        va_list args;                                   \
  41        int ret;                                        \
  42                                                        \
  43        va_start(args, fmt);                            \
  44        if (enabled) {                                  \
  45                fprintf(stderr, "[" #name "] ");        \
  46                ret = vfprintf(stderr, fmt, args);      \
  47        }                                               \
  48        va_end(args);                                   \
  49        return ret;                                     \
  50}
  51DEFINE_PRINT_FN(warning, 1)
  52DEFINE_PRINT_FN(info, 1)
  53DEFINE_PRINT_FN(debug, 1)
  54
  55#define EXIT_FAIL_LIBBPF EXIT_FAILURE
  56#define EXIT_FAIL_OPTION 2
  57
  58int test_walk_progs(struct bpf_object *obj, bool verbose)
  59{
  60        struct bpf_program *prog;
  61        int cnt = 0;
  62
  63        bpf_object__for_each_program(prog, obj) {
  64                cnt++;
  65                if (verbose)
  66                        printf("Prog (count:%d) section_name: %s\n", cnt,
  67                               bpf_program__title(prog, false));
  68        }
  69        return 0;
  70}
  71
  72int test_walk_maps(struct bpf_object *obj, bool verbose)
  73{
  74        struct bpf_map *map;
  75        int cnt = 0;
  76
  77        bpf_map__for_each(map, obj) {
  78                cnt++;
  79                if (verbose)
  80                        printf("Map (count:%d) name: %s\n", cnt,
  81                               bpf_map__name(map));
  82        }
  83        return 0;
  84}
  85
  86int test_open_file(char *filename, bool verbose)
  87{
  88        struct bpf_object *bpfobj = NULL;
  89        long err;
  90
  91        if (verbose)
  92                printf("Open BPF ELF-file with libbpf: %s\n", filename);
  93
  94        /* Load BPF ELF object file and check for errors */
  95        bpfobj = bpf_object__open(filename);
  96        err = libbpf_get_error(bpfobj);
  97        if (err) {
  98                char err_buf[128];
  99                libbpf_strerror(err, err_buf, sizeof(err_buf));
 100                if (verbose)
 101                        printf("Unable to load eBPF objects in file '%s': %s\n",
 102                               filename, err_buf);
 103                return EXIT_FAIL_LIBBPF;
 104        }
 105        test_walk_progs(bpfobj, verbose);
 106        test_walk_maps(bpfobj, verbose);
 107
 108        if (verbose)
 109                printf("Close BPF ELF-file with libbpf: %s\n",
 110                       bpf_object__name(bpfobj));
 111        bpf_object__close(bpfobj);
 112
 113        return 0;
 114}
 115
 116int main(int argc, char **argv)
 117{
 118        char filename[1024] = { 0 };
 119        bool verbose = 1;
 120        int longindex = 0;
 121        int opt;
 122
 123        libbpf_set_print(libbpf_warning, libbpf_info, NULL);
 124
 125        /* Parse commands line args */
 126        while ((opt = getopt_long(argc, argv, "hDq",
 127                                  long_options, &longindex)) != -1) {
 128                switch (opt) {
 129                case 'D':
 130                        libbpf_set_print(libbpf_warning, libbpf_info,
 131                                         libbpf_debug);
 132                        break;
 133                case 'q': /* Use in scripting mode */
 134                        verbose = 0;
 135                        break;
 136                case 'h':
 137                default:
 138                        usage(argv);
 139                        return EXIT_FAIL_OPTION;
 140                }
 141        }
 142        if (optind >= argc) {
 143                usage(argv);
 144                printf("ERROR: Expected BPF_FILE argument after options\n");
 145                return EXIT_FAIL_OPTION;
 146        }
 147        snprintf(filename, sizeof(filename), "%s", argv[optind]);
 148
 149        return test_open_file(filename, verbose);
 150}
 151