• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
usage(char * argv[])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 
test_walk_progs(struct bpf_object * obj,bool verbose)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 
test_walk_maps(struct bpf_object * obj,bool verbose)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 
test_open_file(char * filename,bool verbose)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 
main(int argc,char ** argv)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