1 /* SPDX-License-Identifier: GPL-2.0 2 * Copyright (c) 2018 Jesper Dangaard Brouer, Red Hat Inc. 3 */ 4 static 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 14 static 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 21 static 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) \ 38 static 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 } 51 DEFINE_PRINT_FN(warning, 1) 52 DEFINE_PRINT_FN(info, 1) 53 DEFINE_PRINT_FN(debug, 1) 54 55 #define EXIT_FAIL_LIBBPF EXIT_FAILURE 56 #define EXIT_FAIL_OPTION 2 57 58 int 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 72 int 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 86 int 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 116 int 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