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