blob: 96a2b2ff1212e75fa99b86821cbeb23d24c2c5c7 [file] [log] [blame]
Wang Nan1b76c132015-07-01 02:13:51 +00001/*
2 * Common eBPF ELF object loading operations.
3 *
4 * Copyright (C) 2013-2015 Alexei Starovoitov <ast@kernel.org>
5 * Copyright (C) 2015 Wang Nan <wangnan0@huawei.com>
6 * Copyright (C) 2015 Huawei Inc.
Wang Nan203d1ca2016-07-04 11:02:42 +00007 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation;
11 * version 2.1 of the License (not later!)
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program; if not, see <http://www.gnu.org/licenses>
Wang Nan1b76c132015-07-01 02:13:51 +000020 */
21
22#include <stdlib.h>
Wang Nanb3f59d62015-07-01 02:13:52 +000023#include <stdio.h>
24#include <stdarg.h>
Wang Nan34090912015-07-01 02:14:02 +000025#include <inttypes.h>
Wang Nanb3f59d62015-07-01 02:13:52 +000026#include <string.h>
Wang Nan1b76c132015-07-01 02:13:51 +000027#include <unistd.h>
Wang Nan1a5e3fb2015-07-01 02:13:53 +000028#include <fcntl.h>
29#include <errno.h>
Wang Nan1b76c132015-07-01 02:13:51 +000030#include <asm/unistd.h>
Wang Nancb1e5e92015-07-01 02:13:57 +000031#include <linux/kernel.h>
Wang Nan1b76c132015-07-01 02:13:51 +000032#include <linux/bpf.h>
Wang Nan9a208ef2015-07-01 02:14:10 +000033#include <linux/list.h>
Wang Nan1a5e3fb2015-07-01 02:13:53 +000034#include <libelf.h>
35#include <gelf.h>
Wang Nan1b76c132015-07-01 02:13:51 +000036
37#include "libbpf.h"
Wang Nan52d33522015-07-01 02:14:04 +000038#include "bpf.h"
Wang Nanb3f59d62015-07-01 02:13:52 +000039
Wang Nan9b161372016-07-18 06:01:08 +000040#ifndef EM_BPF
41#define EM_BPF 247
42#endif
43
Wang Nanb3f59d62015-07-01 02:13:52 +000044#define __printf(a, b) __attribute__((format(printf, a, b)))
45
46__printf(1, 2)
47static int __base_pr(const char *format, ...)
48{
49 va_list args;
50 int err;
51
52 va_start(args, format);
53 err = vfprintf(stderr, format, args);
54 va_end(args);
55 return err;
56}
57
58static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr;
59static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
60static __printf(1, 2) libbpf_print_fn_t __pr_debug;
61
62#define __pr(func, fmt, ...) \
63do { \
64 if ((func)) \
65 (func)("libbpf: " fmt, ##__VA_ARGS__); \
66} while (0)
67
68#define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__)
69#define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__)
70#define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__)
71
72void libbpf_set_print(libbpf_print_fn_t warn,
73 libbpf_print_fn_t info,
74 libbpf_print_fn_t debug)
75{
76 __pr_warning = warn;
77 __pr_info = info;
78 __pr_debug = debug;
79}
Wang Nan1a5e3fb2015-07-01 02:13:53 +000080
Wang Nan6371ca3b2015-11-06 13:49:37 +000081#define STRERR_BUFSIZE 128
82
83#define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
84#define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
85#define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
86
87static const char *libbpf_strerror_table[NR_ERRNO] = {
88 [ERRCODE_OFFSET(LIBELF)] = "Something wrong in libelf",
89 [ERRCODE_OFFSET(FORMAT)] = "BPF object format invalid",
90 [ERRCODE_OFFSET(KVERSION)] = "'version' section incorrect or lost",
Colin Ian Kingde8a63b2016-06-28 13:23:37 +010091 [ERRCODE_OFFSET(ENDIAN)] = "Endian mismatch",
Wang Nan6371ca3b2015-11-06 13:49:37 +000092 [ERRCODE_OFFSET(INTERNAL)] = "Internal error in libbpf",
93 [ERRCODE_OFFSET(RELOC)] = "Relocation failed",
94 [ERRCODE_OFFSET(VERIFY)] = "Kernel verifier blocks program loading",
95 [ERRCODE_OFFSET(PROG2BIG)] = "Program too big",
96 [ERRCODE_OFFSET(KVER)] = "Incorrect kernel version",
Wang Nan705fa212016-07-13 10:44:02 +000097 [ERRCODE_OFFSET(PROGTYPE)] = "Kernel doesn't support this program type",
Wang Nan6371ca3b2015-11-06 13:49:37 +000098};
99
100int libbpf_strerror(int err, char *buf, size_t size)
101{
102 if (!buf || !size)
103 return -1;
104
105 err = err > 0 ? err : -err;
106
107 if (err < __LIBBPF_ERRNO__START) {
108 int ret;
109
110 ret = strerror_r(err, buf, size);
111 buf[size - 1] = '\0';
112 return ret;
113 }
114
115 if (err < __LIBBPF_ERRNO__END) {
116 const char *msg;
117
118 msg = libbpf_strerror_table[ERRNO_OFFSET(err)];
119 snprintf(buf, size, "%s", msg);
120 buf[size - 1] = '\0';
121 return 0;
122 }
123
124 snprintf(buf, size, "Unknown libbpf error %d", err);
125 buf[size - 1] = '\0';
126 return -1;
127}
128
129#define CHECK_ERR(action, err, out) do { \
130 err = action; \
131 if (err) \
132 goto out; \
133} while(0)
134
135
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000136/* Copied from tools/perf/util/util.h */
137#ifndef zfree
138# define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
139#endif
140
141#ifndef zclose
142# define zclose(fd) ({ \
143 int ___err = 0; \
144 if ((fd) >= 0) \
145 ___err = close((fd)); \
146 fd = -1; \
147 ___err; })
148#endif
149
150#ifdef HAVE_LIBELF_MMAP_SUPPORT
151# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ_MMAP
152#else
153# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
154#endif
155
Wang Nana5b8bd42015-07-01 02:14:00 +0000156/*
157 * bpf_prog should be a better name but it has been used in
158 * linux/filter.h.
159 */
160struct bpf_program {
161 /* Index in elf obj file, for relocation use. */
162 int idx;
163 char *section_name;
164 struct bpf_insn *insns;
165 size_t insns_cnt;
Wang Nan5f44e4c82016-07-13 10:44:01 +0000166 enum bpf_prog_type type;
Wang Nan34090912015-07-01 02:14:02 +0000167
168 struct {
169 int insn_idx;
170 int map_idx;
171 } *reloc_desc;
172 int nr_reloc;
Wang Nan55cffde2015-07-01 02:14:07 +0000173
Wang Nanb5805632015-11-16 12:10:09 +0000174 struct {
175 int nr;
176 int *fds;
177 } instances;
178 bpf_program_prep_t preprocessor;
Wang Nanaa9b1ac2015-07-01 02:14:08 +0000179
180 struct bpf_object *obj;
181 void *priv;
182 bpf_program_clear_priv_t clear_priv;
Wang Nana5b8bd42015-07-01 02:14:00 +0000183};
184
Wang Nan9d759a92015-11-27 08:47:35 +0000185struct bpf_map {
186 int fd;
Wang Nan561bbcc2015-11-27 08:47:36 +0000187 char *name;
Eric Leblond4708bbd2016-11-15 04:05:47 +0000188 size_t offset;
Wang Nan9d759a92015-11-27 08:47:35 +0000189 struct bpf_map_def def;
190 void *priv;
191 bpf_map_clear_priv_t clear_priv;
192};
193
Wang Nan9a208ef2015-07-01 02:14:10 +0000194static LIST_HEAD(bpf_objects_list);
195
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000196struct bpf_object {
Wang Nancb1e5e92015-07-01 02:13:57 +0000197 char license[64];
198 u32 kern_version;
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000199
Wang Nana5b8bd42015-07-01 02:14:00 +0000200 struct bpf_program *programs;
201 size_t nr_programs;
Wang Nan9d759a92015-11-27 08:47:35 +0000202 struct bpf_map *maps;
203 size_t nr_maps;
204
Wang Nan52d33522015-07-01 02:14:04 +0000205 bool loaded;
Wang Nana5b8bd42015-07-01 02:14:00 +0000206
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000207 /*
208 * Information when doing elf related work. Only valid if fd
209 * is valid.
210 */
211 struct {
212 int fd;
Wang Nan6c956392015-07-01 02:13:54 +0000213 void *obj_buf;
214 size_t obj_buf_sz;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000215 Elf *elf;
216 GElf_Ehdr ehdr;
Wang Nanbec7d682015-07-01 02:13:59 +0000217 Elf_Data *symbols;
Wang Nan77ba9a52015-12-08 02:25:30 +0000218 size_t strtabidx;
Wang Nanb62f06e2015-07-01 02:14:01 +0000219 struct {
220 GElf_Shdr shdr;
221 Elf_Data *data;
222 } *reloc;
223 int nr_reloc;
Wang Nan666810e2016-01-25 09:55:49 +0000224 int maps_shndx;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000225 } efile;
Wang Nan9a208ef2015-07-01 02:14:10 +0000226 /*
227 * All loaded bpf_object is linked in a list, which is
228 * hidden to caller. bpf_objects__<func> handlers deal with
229 * all objects.
230 */
231 struct list_head list;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000232 char path[];
233};
234#define obj_elf_valid(o) ((o)->efile.elf)
235
Wang Nan55cffde2015-07-01 02:14:07 +0000236static void bpf_program__unload(struct bpf_program *prog)
237{
Wang Nanb5805632015-11-16 12:10:09 +0000238 int i;
239
Wang Nan55cffde2015-07-01 02:14:07 +0000240 if (!prog)
241 return;
242
Wang Nanb5805632015-11-16 12:10:09 +0000243 /*
244 * If the object is opened but the program was never loaded,
245 * it is possible that prog->instances.nr == -1.
246 */
247 if (prog->instances.nr > 0) {
248 for (i = 0; i < prog->instances.nr; i++)
249 zclose(prog->instances.fds[i]);
250 } else if (prog->instances.nr != -1) {
251 pr_warning("Internal error: instances.nr is %d\n",
252 prog->instances.nr);
253 }
254
255 prog->instances.nr = -1;
256 zfree(&prog->instances.fds);
Wang Nan55cffde2015-07-01 02:14:07 +0000257}
258
Wang Nana5b8bd42015-07-01 02:14:00 +0000259static void bpf_program__exit(struct bpf_program *prog)
260{
261 if (!prog)
262 return;
263
Wang Nanaa9b1ac2015-07-01 02:14:08 +0000264 if (prog->clear_priv)
265 prog->clear_priv(prog, prog->priv);
266
267 prog->priv = NULL;
268 prog->clear_priv = NULL;
269
Wang Nan55cffde2015-07-01 02:14:07 +0000270 bpf_program__unload(prog);
Wang Nana5b8bd42015-07-01 02:14:00 +0000271 zfree(&prog->section_name);
272 zfree(&prog->insns);
Wang Nan34090912015-07-01 02:14:02 +0000273 zfree(&prog->reloc_desc);
274
275 prog->nr_reloc = 0;
Wang Nana5b8bd42015-07-01 02:14:00 +0000276 prog->insns_cnt = 0;
277 prog->idx = -1;
278}
279
280static int
281bpf_program__init(void *data, size_t size, char *name, int idx,
282 struct bpf_program *prog)
283{
284 if (size < sizeof(struct bpf_insn)) {
285 pr_warning("corrupted section '%s'\n", name);
286 return -EINVAL;
287 }
288
289 bzero(prog, sizeof(*prog));
290
291 prog->section_name = strdup(name);
292 if (!prog->section_name) {
293 pr_warning("failed to alloc name for prog %s\n",
294 name);
295 goto errout;
296 }
297
298 prog->insns = malloc(size);
299 if (!prog->insns) {
300 pr_warning("failed to alloc insns for %s\n", name);
301 goto errout;
302 }
303 prog->insns_cnt = size / sizeof(struct bpf_insn);
304 memcpy(prog->insns, data,
305 prog->insns_cnt * sizeof(struct bpf_insn));
306 prog->idx = idx;
Wang Nanb5805632015-11-16 12:10:09 +0000307 prog->instances.fds = NULL;
308 prog->instances.nr = -1;
Wang Nan5f44e4c82016-07-13 10:44:01 +0000309 prog->type = BPF_PROG_TYPE_KPROBE;
Wang Nana5b8bd42015-07-01 02:14:00 +0000310
311 return 0;
312errout:
313 bpf_program__exit(prog);
314 return -ENOMEM;
315}
316
317static int
318bpf_object__add_program(struct bpf_object *obj, void *data, size_t size,
319 char *name, int idx)
320{
321 struct bpf_program prog, *progs;
322 int nr_progs, err;
323
324 err = bpf_program__init(data, size, name, idx, &prog);
325 if (err)
326 return err;
327
328 progs = obj->programs;
329 nr_progs = obj->nr_programs;
330
331 progs = realloc(progs, sizeof(progs[0]) * (nr_progs + 1));
332 if (!progs) {
333 /*
334 * In this case the original obj->programs
335 * is still valid, so don't need special treat for
336 * bpf_close_object().
337 */
338 pr_warning("failed to alloc a new program '%s'\n",
339 name);
340 bpf_program__exit(&prog);
341 return -ENOMEM;
342 }
343
344 pr_debug("found program %s\n", prog.section_name);
345 obj->programs = progs;
346 obj->nr_programs = nr_progs + 1;
Wang Nanaa9b1ac2015-07-01 02:14:08 +0000347 prog.obj = obj;
Wang Nana5b8bd42015-07-01 02:14:00 +0000348 progs[nr_progs] = prog;
349 return 0;
350}
351
Wang Nan6c956392015-07-01 02:13:54 +0000352static struct bpf_object *bpf_object__new(const char *path,
353 void *obj_buf,
354 size_t obj_buf_sz)
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000355{
356 struct bpf_object *obj;
357
358 obj = calloc(1, sizeof(struct bpf_object) + strlen(path) + 1);
359 if (!obj) {
360 pr_warning("alloc memory failed for %s\n", path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000361 return ERR_PTR(-ENOMEM);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000362 }
363
364 strcpy(obj->path, path);
365 obj->efile.fd = -1;
Wang Nan6c956392015-07-01 02:13:54 +0000366
367 /*
368 * Caller of this function should also calls
369 * bpf_object__elf_finish() after data collection to return
370 * obj_buf to user. If not, we should duplicate the buffer to
371 * avoid user freeing them before elf finish.
372 */
373 obj->efile.obj_buf = obj_buf;
374 obj->efile.obj_buf_sz = obj_buf_sz;
Wang Nan666810e2016-01-25 09:55:49 +0000375 obj->efile.maps_shndx = -1;
Wang Nan6c956392015-07-01 02:13:54 +0000376
Wang Nan52d33522015-07-01 02:14:04 +0000377 obj->loaded = false;
Wang Nan9a208ef2015-07-01 02:14:10 +0000378
379 INIT_LIST_HEAD(&obj->list);
380 list_add(&obj->list, &bpf_objects_list);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000381 return obj;
382}
383
384static void bpf_object__elf_finish(struct bpf_object *obj)
385{
386 if (!obj_elf_valid(obj))
387 return;
388
389 if (obj->efile.elf) {
390 elf_end(obj->efile.elf);
391 obj->efile.elf = NULL;
392 }
Wang Nanbec7d682015-07-01 02:13:59 +0000393 obj->efile.symbols = NULL;
Wang Nanb62f06e2015-07-01 02:14:01 +0000394
395 zfree(&obj->efile.reloc);
396 obj->efile.nr_reloc = 0;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000397 zclose(obj->efile.fd);
Wang Nan6c956392015-07-01 02:13:54 +0000398 obj->efile.obj_buf = NULL;
399 obj->efile.obj_buf_sz = 0;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000400}
401
402static int bpf_object__elf_init(struct bpf_object *obj)
403{
404 int err = 0;
405 GElf_Ehdr *ep;
406
407 if (obj_elf_valid(obj)) {
408 pr_warning("elf init: internal error\n");
Wang Nan6371ca3b2015-11-06 13:49:37 +0000409 return -LIBBPF_ERRNO__LIBELF;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000410 }
411
Wang Nan6c956392015-07-01 02:13:54 +0000412 if (obj->efile.obj_buf_sz > 0) {
413 /*
414 * obj_buf should have been validated by
415 * bpf_object__open_buffer().
416 */
417 obj->efile.elf = elf_memory(obj->efile.obj_buf,
418 obj->efile.obj_buf_sz);
419 } else {
420 obj->efile.fd = open(obj->path, O_RDONLY);
421 if (obj->efile.fd < 0) {
422 pr_warning("failed to open %s: %s\n", obj->path,
423 strerror(errno));
424 return -errno;
425 }
426
427 obj->efile.elf = elf_begin(obj->efile.fd,
428 LIBBPF_ELF_C_READ_MMAP,
429 NULL);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000430 }
431
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000432 if (!obj->efile.elf) {
433 pr_warning("failed to open %s as ELF file\n",
434 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000435 err = -LIBBPF_ERRNO__LIBELF;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000436 goto errout;
437 }
438
439 if (!gelf_getehdr(obj->efile.elf, &obj->efile.ehdr)) {
440 pr_warning("failed to get EHDR from %s\n",
441 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000442 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000443 goto errout;
444 }
445 ep = &obj->efile.ehdr;
446
Wang Nan9b161372016-07-18 06:01:08 +0000447 /* Old LLVM set e_machine to EM_NONE */
448 if ((ep->e_type != ET_REL) || (ep->e_machine && (ep->e_machine != EM_BPF))) {
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000449 pr_warning("%s is not an eBPF object file\n",
450 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000451 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000452 goto errout;
453 }
454
455 return 0;
456errout:
457 bpf_object__elf_finish(obj);
458 return err;
459}
460
Wang Nancc4228d2015-07-01 02:13:55 +0000461static int
462bpf_object__check_endianness(struct bpf_object *obj)
463{
464 static unsigned int const endian = 1;
465
466 switch (obj->efile.ehdr.e_ident[EI_DATA]) {
467 case ELFDATA2LSB:
468 /* We are big endian, BPF obj is little endian. */
469 if (*(unsigned char const *)&endian != 1)
470 goto mismatch;
471 break;
472
473 case ELFDATA2MSB:
474 /* We are little endian, BPF obj is big endian. */
475 if (*(unsigned char const *)&endian != 0)
476 goto mismatch;
477 break;
478 default:
Wang Nan6371ca3b2015-11-06 13:49:37 +0000479 return -LIBBPF_ERRNO__ENDIAN;
Wang Nancc4228d2015-07-01 02:13:55 +0000480 }
481
482 return 0;
483
484mismatch:
485 pr_warning("Error: endianness mismatch.\n");
Wang Nan6371ca3b2015-11-06 13:49:37 +0000486 return -LIBBPF_ERRNO__ENDIAN;
Wang Nancc4228d2015-07-01 02:13:55 +0000487}
488
Wang Nancb1e5e92015-07-01 02:13:57 +0000489static int
490bpf_object__init_license(struct bpf_object *obj,
491 void *data, size_t size)
492{
493 memcpy(obj->license, data,
494 min(size, sizeof(obj->license) - 1));
495 pr_debug("license of %s is %s\n", obj->path, obj->license);
496 return 0;
497}
498
499static int
500bpf_object__init_kversion(struct bpf_object *obj,
501 void *data, size_t size)
502{
503 u32 kver;
504
505 if (size != sizeof(kver)) {
506 pr_warning("invalid kver section in %s\n", obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000507 return -LIBBPF_ERRNO__FORMAT;
Wang Nancb1e5e92015-07-01 02:13:57 +0000508 }
509 memcpy(&kver, data, sizeof(kver));
510 obj->kern_version = kver;
511 pr_debug("kernel version of %s is %x\n", obj->path,
512 obj->kern_version);
513 return 0;
514}
515
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000516static int
Eric Leblond4708bbd2016-11-15 04:05:47 +0000517bpf_object__validate_maps(struct bpf_object *obj)
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000518{
Wang Nan9d759a92015-11-27 08:47:35 +0000519 int i;
520
Eric Leblond4708bbd2016-11-15 04:05:47 +0000521 /*
522 * If there's only 1 map, the only error case should have been
523 * catched in bpf_object__init_maps().
524 */
525 if (!obj->maps || !obj->nr_maps || (obj->nr_maps == 1))
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000526 return 0;
Eric Leblond4708bbd2016-11-15 04:05:47 +0000527
528 for (i = 1; i < obj->nr_maps; i++) {
529 const struct bpf_map *a = &obj->maps[i - 1];
530 const struct bpf_map *b = &obj->maps[i];
531
532 if (b->offset - a->offset < sizeof(struct bpf_map_def)) {
533 pr_warning("corrupted map section in %s: map \"%s\" too small\n",
534 obj->path, a->name);
535 return -EINVAL;
536 }
537 }
538 return 0;
539}
540
541static int compare_bpf_map(const void *_a, const void *_b)
542{
543 const struct bpf_map *a = _a;
544 const struct bpf_map *b = _b;
545
546 return a->offset - b->offset;
547}
548
549static int
550bpf_object__init_maps(struct bpf_object *obj)
551{
552 int i, map_idx, nr_maps = 0;
553 Elf_Scn *scn;
554 Elf_Data *data;
555 Elf_Data *symbols = obj->efile.symbols;
556
557 if (obj->efile.maps_shndx < 0)
558 return -EINVAL;
559 if (!symbols)
560 return -EINVAL;
561
562 scn = elf_getscn(obj->efile.elf, obj->efile.maps_shndx);
563 if (scn)
564 data = elf_getdata(scn, NULL);
565 if (!scn || !data) {
566 pr_warning("failed to get Elf_Data from map section %d\n",
567 obj->efile.maps_shndx);
568 return -EINVAL;
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000569 }
570
Eric Leblond4708bbd2016-11-15 04:05:47 +0000571 /*
572 * Count number of maps. Each map has a name.
573 * Array of maps is not supported: only the first element is
574 * considered.
575 *
576 * TODO: Detect array of map and report error.
577 */
578 for (i = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
579 GElf_Sym sym;
580
581 if (!gelf_getsym(symbols, i, &sym))
582 continue;
583 if (sym.st_shndx != obj->efile.maps_shndx)
584 continue;
585 nr_maps++;
586 }
587
588 /* Alloc obj->maps and fill nr_maps. */
589 pr_debug("maps in %s: %d maps in %zd bytes\n", obj->path,
590 nr_maps, data->d_size);
591
592 if (!nr_maps)
593 return 0;
Wang Nan9d759a92015-11-27 08:47:35 +0000594
595 obj->maps = calloc(nr_maps, sizeof(obj->maps[0]));
596 if (!obj->maps) {
597 pr_warning("alloc maps for object failed\n");
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000598 return -ENOMEM;
599 }
Wang Nan9d759a92015-11-27 08:47:35 +0000600 obj->nr_maps = nr_maps;
Wang Nan0b3d1ef2015-07-01 02:13:58 +0000601
Eric Leblond4708bbd2016-11-15 04:05:47 +0000602 /*
603 * fill all fd with -1 so won't close incorrect
604 * fd (fd=0 is stdin) when failure (zclose won't close
605 * negative fd)).
606 */
607 for (i = 0; i < nr_maps; i++)
Wang Nan9d759a92015-11-27 08:47:35 +0000608 obj->maps[i].fd = -1;
609
Eric Leblond4708bbd2016-11-15 04:05:47 +0000610 /*
611 * Fill obj->maps using data in "maps" section.
612 */
613 for (i = 0, map_idx = 0; i < symbols->d_size / sizeof(GElf_Sym); i++) {
Wang Nan561bbcc2015-11-27 08:47:36 +0000614 GElf_Sym sym;
Wang Nan561bbcc2015-11-27 08:47:36 +0000615 const char *map_name;
Eric Leblond4708bbd2016-11-15 04:05:47 +0000616 struct bpf_map_def *def;
Wang Nan561bbcc2015-11-27 08:47:36 +0000617
618 if (!gelf_getsym(symbols, i, &sym))
619 continue;
Wang Nan666810e2016-01-25 09:55:49 +0000620 if (sym.st_shndx != obj->efile.maps_shndx)
Wang Nan561bbcc2015-11-27 08:47:36 +0000621 continue;
622
623 map_name = elf_strptr(obj->efile.elf,
Wang Nan77ba9a52015-12-08 02:25:30 +0000624 obj->efile.strtabidx,
Wang Nan561bbcc2015-11-27 08:47:36 +0000625 sym.st_name);
Eric Leblond4708bbd2016-11-15 04:05:47 +0000626 obj->maps[map_idx].offset = sym.st_value;
627 if (sym.st_value + sizeof(struct bpf_map_def) > data->d_size) {
628 pr_warning("corrupted maps section in %s: last map \"%s\" too small\n",
629 obj->path, map_name);
630 return -EINVAL;
Wang Nan561bbcc2015-11-27 08:47:36 +0000631 }
Eric Leblond4708bbd2016-11-15 04:05:47 +0000632
Wang Nan561bbcc2015-11-27 08:47:36 +0000633 obj->maps[map_idx].name = strdup(map_name);
Wang Nan973170e2015-12-08 02:25:29 +0000634 if (!obj->maps[map_idx].name) {
635 pr_warning("failed to alloc map name\n");
636 return -ENOMEM;
637 }
Eric Leblond4708bbd2016-11-15 04:05:47 +0000638 pr_debug("map %d is \"%s\"\n", map_idx,
Wang Nan561bbcc2015-11-27 08:47:36 +0000639 obj->maps[map_idx].name);
Eric Leblond4708bbd2016-11-15 04:05:47 +0000640 def = (struct bpf_map_def *)(data->d_buf + sym.st_value);
641 obj->maps[map_idx].def = *def;
642 map_idx++;
Wang Nan561bbcc2015-11-27 08:47:36 +0000643 }
Eric Leblond4708bbd2016-11-15 04:05:47 +0000644
645 qsort(obj->maps, obj->nr_maps, sizeof(obj->maps[0]), compare_bpf_map);
646 return bpf_object__validate_maps(obj);
Wang Nan561bbcc2015-11-27 08:47:36 +0000647}
648
Wang Nan29603662015-07-01 02:13:56 +0000649static int bpf_object__elf_collect(struct bpf_object *obj)
650{
651 Elf *elf = obj->efile.elf;
652 GElf_Ehdr *ep = &obj->efile.ehdr;
653 Elf_Scn *scn = NULL;
Wang Nan666810e2016-01-25 09:55:49 +0000654 int idx = 0, err = 0;
Wang Nan29603662015-07-01 02:13:56 +0000655
656 /* Elf is corrupted/truncated, avoid calling elf_strptr. */
657 if (!elf_rawdata(elf_getscn(elf, ep->e_shstrndx), NULL)) {
658 pr_warning("failed to get e_shstrndx from %s\n",
659 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000660 return -LIBBPF_ERRNO__FORMAT;
Wang Nan29603662015-07-01 02:13:56 +0000661 }
662
663 while ((scn = elf_nextscn(elf, scn)) != NULL) {
664 char *name;
665 GElf_Shdr sh;
666 Elf_Data *data;
667
668 idx++;
669 if (gelf_getshdr(scn, &sh) != &sh) {
670 pr_warning("failed to get section header from %s\n",
671 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000672 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan29603662015-07-01 02:13:56 +0000673 goto out;
674 }
675
676 name = elf_strptr(elf, ep->e_shstrndx, sh.sh_name);
677 if (!name) {
678 pr_warning("failed to get section name from %s\n",
679 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000680 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan29603662015-07-01 02:13:56 +0000681 goto out;
682 }
683
684 data = elf_getdata(scn, 0);
685 if (!data) {
686 pr_warning("failed to get section data from %s(%s)\n",
687 name, obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000688 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan29603662015-07-01 02:13:56 +0000689 goto out;
690 }
691 pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
692 name, (unsigned long)data->d_size,
693 (int)sh.sh_link, (unsigned long)sh.sh_flags,
694 (int)sh.sh_type);
Wang Nancb1e5e92015-07-01 02:13:57 +0000695
696 if (strcmp(name, "license") == 0)
697 err = bpf_object__init_license(obj,
698 data->d_buf,
699 data->d_size);
700 else if (strcmp(name, "version") == 0)
701 err = bpf_object__init_kversion(obj,
702 data->d_buf,
703 data->d_size);
Eric Leblond4708bbd2016-11-15 04:05:47 +0000704 else if (strcmp(name, "maps") == 0)
Wang Nan666810e2016-01-25 09:55:49 +0000705 obj->efile.maps_shndx = idx;
Eric Leblond4708bbd2016-11-15 04:05:47 +0000706 else if (sh.sh_type == SHT_SYMTAB) {
Wang Nanbec7d682015-07-01 02:13:59 +0000707 if (obj->efile.symbols) {
708 pr_warning("bpf: multiple SYMTAB in %s\n",
709 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000710 err = -LIBBPF_ERRNO__FORMAT;
Wang Nan77ba9a52015-12-08 02:25:30 +0000711 } else {
Wang Nanbec7d682015-07-01 02:13:59 +0000712 obj->efile.symbols = data;
Wang Nan77ba9a52015-12-08 02:25:30 +0000713 obj->efile.strtabidx = sh.sh_link;
714 }
Wang Nana5b8bd42015-07-01 02:14:00 +0000715 } else if ((sh.sh_type == SHT_PROGBITS) &&
716 (sh.sh_flags & SHF_EXECINSTR) &&
717 (data->d_size > 0)) {
718 err = bpf_object__add_program(obj, data->d_buf,
719 data->d_size, name, idx);
720 if (err) {
Wang Nan6371ca3b2015-11-06 13:49:37 +0000721 char errmsg[STRERR_BUFSIZE];
722
Wang Nana5b8bd42015-07-01 02:14:00 +0000723 strerror_r(-err, errmsg, sizeof(errmsg));
724 pr_warning("failed to alloc program %s (%s): %s",
725 name, obj->path, errmsg);
726 }
Wang Nanb62f06e2015-07-01 02:14:01 +0000727 } else if (sh.sh_type == SHT_REL) {
728 void *reloc = obj->efile.reloc;
729 int nr_reloc = obj->efile.nr_reloc + 1;
730
731 reloc = realloc(reloc,
732 sizeof(*obj->efile.reloc) * nr_reloc);
733 if (!reloc) {
734 pr_warning("realloc failed\n");
735 err = -ENOMEM;
736 } else {
737 int n = nr_reloc - 1;
738
739 obj->efile.reloc = reloc;
740 obj->efile.nr_reloc = nr_reloc;
741
742 obj->efile.reloc[n].shdr = sh;
743 obj->efile.reloc[n].data = data;
744 }
Wang Nanbec7d682015-07-01 02:13:59 +0000745 }
Wang Nancb1e5e92015-07-01 02:13:57 +0000746 if (err)
747 goto out;
Wang Nan29603662015-07-01 02:13:56 +0000748 }
Wang Nan561bbcc2015-11-27 08:47:36 +0000749
Wang Nan77ba9a52015-12-08 02:25:30 +0000750 if (!obj->efile.strtabidx || obj->efile.strtabidx >= idx) {
751 pr_warning("Corrupted ELF file: index of strtab invalid\n");
752 return LIBBPF_ERRNO__FORMAT;
753 }
Wang Nan666810e2016-01-25 09:55:49 +0000754 if (obj->efile.maps_shndx >= 0)
Eric Leblond4708bbd2016-11-15 04:05:47 +0000755 err = bpf_object__init_maps(obj);
Wang Nan29603662015-07-01 02:13:56 +0000756out:
757 return err;
758}
759
Wang Nan34090912015-07-01 02:14:02 +0000760static struct bpf_program *
761bpf_object__find_prog_by_idx(struct bpf_object *obj, int idx)
762{
763 struct bpf_program *prog;
764 size_t i;
765
766 for (i = 0; i < obj->nr_programs; i++) {
767 prog = &obj->programs[i];
768 if (prog->idx == idx)
769 return prog;
770 }
771 return NULL;
772}
773
774static int
775bpf_program__collect_reloc(struct bpf_program *prog,
776 size_t nr_maps, GElf_Shdr *shdr,
Wang Nan666810e2016-01-25 09:55:49 +0000777 Elf_Data *data, Elf_Data *symbols,
778 int maps_shndx)
Wang Nan34090912015-07-01 02:14:02 +0000779{
780 int i, nrels;
781
782 pr_debug("collecting relocating info for: '%s'\n",
783 prog->section_name);
784 nrels = shdr->sh_size / shdr->sh_entsize;
785
786 prog->reloc_desc = malloc(sizeof(*prog->reloc_desc) * nrels);
787 if (!prog->reloc_desc) {
788 pr_warning("failed to alloc memory in relocation\n");
789 return -ENOMEM;
790 }
791 prog->nr_reloc = nrels;
792
793 for (i = 0; i < nrels; i++) {
794 GElf_Sym sym;
795 GElf_Rel rel;
796 unsigned int insn_idx;
797 struct bpf_insn *insns = prog->insns;
798 size_t map_idx;
799
800 if (!gelf_getrel(data, i, &rel)) {
801 pr_warning("relocation: failed to get %d reloc\n", i);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000802 return -LIBBPF_ERRNO__FORMAT;
Wang Nan34090912015-07-01 02:14:02 +0000803 }
804
Wang Nan34090912015-07-01 02:14:02 +0000805 if (!gelf_getsym(symbols,
806 GELF_R_SYM(rel.r_info),
807 &sym)) {
808 pr_warning("relocation: symbol %"PRIx64" not found\n",
809 GELF_R_SYM(rel.r_info));
Wang Nan6371ca3b2015-11-06 13:49:37 +0000810 return -LIBBPF_ERRNO__FORMAT;
Wang Nan34090912015-07-01 02:14:02 +0000811 }
812
Wang Nan666810e2016-01-25 09:55:49 +0000813 if (sym.st_shndx != maps_shndx) {
814 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
815 prog->section_name, sym.st_shndx);
816 return -LIBBPF_ERRNO__RELOC;
817 }
818
819 insn_idx = rel.r_offset / sizeof(struct bpf_insn);
820 pr_debug("relocation: insn_idx=%u\n", insn_idx);
821
Wang Nan34090912015-07-01 02:14:02 +0000822 if (insns[insn_idx].code != (BPF_LD | BPF_IMM | BPF_DW)) {
823 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
824 insn_idx, insns[insn_idx].code);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000825 return -LIBBPF_ERRNO__RELOC;
Wang Nan34090912015-07-01 02:14:02 +0000826 }
827
828 map_idx = sym.st_value / sizeof(struct bpf_map_def);
829 if (map_idx >= nr_maps) {
830 pr_warning("bpf relocation: map_idx %d large than %d\n",
831 (int)map_idx, (int)nr_maps - 1);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000832 return -LIBBPF_ERRNO__RELOC;
Wang Nan34090912015-07-01 02:14:02 +0000833 }
834
835 prog->reloc_desc[i].insn_idx = insn_idx;
836 prog->reloc_desc[i].map_idx = map_idx;
837 }
838 return 0;
839}
840
Wang Nan52d33522015-07-01 02:14:04 +0000841static int
842bpf_object__create_maps(struct bpf_object *obj)
843{
844 unsigned int i;
Wang Nan52d33522015-07-01 02:14:04 +0000845
Wang Nan9d759a92015-11-27 08:47:35 +0000846 for (i = 0; i < obj->nr_maps; i++) {
847 struct bpf_map_def *def = &obj->maps[i].def;
848 int *pfd = &obj->maps[i].fd;
Wang Nan52d33522015-07-01 02:14:04 +0000849
Wang Nan9d759a92015-11-27 08:47:35 +0000850 *pfd = bpf_create_map(def->type,
851 def->key_size,
852 def->value_size,
853 def->max_entries);
Wang Nan52d33522015-07-01 02:14:04 +0000854 if (*pfd < 0) {
855 size_t j;
856 int err = *pfd;
857
858 pr_warning("failed to create map: %s\n",
859 strerror(errno));
860 for (j = 0; j < i; j++)
Wang Nan9d759a92015-11-27 08:47:35 +0000861 zclose(obj->maps[j].fd);
Wang Nan52d33522015-07-01 02:14:04 +0000862 return err;
863 }
Eric Leblond4708bbd2016-11-15 04:05:47 +0000864 pr_debug("create map %s: fd=%d\n", obj->maps[i].name, *pfd);
Wang Nan52d33522015-07-01 02:14:04 +0000865 }
866
Wang Nan52d33522015-07-01 02:14:04 +0000867 return 0;
868}
869
Wang Nan8a47a6c2015-07-01 02:14:05 +0000870static int
Wang Nan9d759a92015-11-27 08:47:35 +0000871bpf_program__relocate(struct bpf_program *prog, struct bpf_object *obj)
Wang Nan8a47a6c2015-07-01 02:14:05 +0000872{
873 int i;
874
875 if (!prog || !prog->reloc_desc)
876 return 0;
877
878 for (i = 0; i < prog->nr_reloc; i++) {
879 int insn_idx, map_idx;
880 struct bpf_insn *insns = prog->insns;
881
882 insn_idx = prog->reloc_desc[i].insn_idx;
883 map_idx = prog->reloc_desc[i].map_idx;
884
885 if (insn_idx >= (int)prog->insns_cnt) {
886 pr_warning("relocation out of range: '%s'\n",
887 prog->section_name);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000888 return -LIBBPF_ERRNO__RELOC;
Wang Nan8a47a6c2015-07-01 02:14:05 +0000889 }
890 insns[insn_idx].src_reg = BPF_PSEUDO_MAP_FD;
Wang Nan9d759a92015-11-27 08:47:35 +0000891 insns[insn_idx].imm = obj->maps[map_idx].fd;
Wang Nan8a47a6c2015-07-01 02:14:05 +0000892 }
893
894 zfree(&prog->reloc_desc);
895 prog->nr_reloc = 0;
896 return 0;
897}
898
899
900static int
901bpf_object__relocate(struct bpf_object *obj)
902{
903 struct bpf_program *prog;
904 size_t i;
905 int err;
906
907 for (i = 0; i < obj->nr_programs; i++) {
908 prog = &obj->programs[i];
909
Wang Nan9d759a92015-11-27 08:47:35 +0000910 err = bpf_program__relocate(prog, obj);
Wang Nan8a47a6c2015-07-01 02:14:05 +0000911 if (err) {
912 pr_warning("failed to relocate '%s'\n",
913 prog->section_name);
914 return err;
915 }
916 }
917 return 0;
918}
919
Wang Nan34090912015-07-01 02:14:02 +0000920static int bpf_object__collect_reloc(struct bpf_object *obj)
921{
922 int i, err;
923
924 if (!obj_elf_valid(obj)) {
925 pr_warning("Internal error: elf object is closed\n");
Wang Nan6371ca3b2015-11-06 13:49:37 +0000926 return -LIBBPF_ERRNO__INTERNAL;
Wang Nan34090912015-07-01 02:14:02 +0000927 }
928
929 for (i = 0; i < obj->efile.nr_reloc; i++) {
930 GElf_Shdr *shdr = &obj->efile.reloc[i].shdr;
931 Elf_Data *data = obj->efile.reloc[i].data;
932 int idx = shdr->sh_info;
933 struct bpf_program *prog;
Wang Nan9d759a92015-11-27 08:47:35 +0000934 size_t nr_maps = obj->nr_maps;
Wang Nan34090912015-07-01 02:14:02 +0000935
936 if (shdr->sh_type != SHT_REL) {
937 pr_warning("internal error at %d\n", __LINE__);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000938 return -LIBBPF_ERRNO__INTERNAL;
Wang Nan34090912015-07-01 02:14:02 +0000939 }
940
941 prog = bpf_object__find_prog_by_idx(obj, idx);
942 if (!prog) {
943 pr_warning("relocation failed: no %d section\n",
944 idx);
Wang Nan6371ca3b2015-11-06 13:49:37 +0000945 return -LIBBPF_ERRNO__RELOC;
Wang Nan34090912015-07-01 02:14:02 +0000946 }
947
948 err = bpf_program__collect_reloc(prog, nr_maps,
949 shdr, data,
Wang Nan666810e2016-01-25 09:55:49 +0000950 obj->efile.symbols,
951 obj->efile.maps_shndx);
Wang Nan34090912015-07-01 02:14:02 +0000952 if (err)
Wang Nan6371ca3b2015-11-06 13:49:37 +0000953 return err;
Wang Nan34090912015-07-01 02:14:02 +0000954 }
955 return 0;
956}
957
Wang Nan55cffde2015-07-01 02:14:07 +0000958static int
Wang Nan5f44e4c82016-07-13 10:44:01 +0000959load_program(enum bpf_prog_type type, struct bpf_insn *insns,
960 int insns_cnt, char *license, u32 kern_version, int *pfd)
Wang Nan55cffde2015-07-01 02:14:07 +0000961{
962 int ret;
963 char *log_buf;
964
965 if (!insns || !insns_cnt)
966 return -EINVAL;
967
968 log_buf = malloc(BPF_LOG_BUF_SIZE);
969 if (!log_buf)
970 pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
971
Wang Nan5f44e4c82016-07-13 10:44:01 +0000972 ret = bpf_load_program(type, insns, insns_cnt, license,
973 kern_version, log_buf, BPF_LOG_BUF_SIZE);
Wang Nan55cffde2015-07-01 02:14:07 +0000974
975 if (ret >= 0) {
976 *pfd = ret;
977 ret = 0;
978 goto out;
979 }
980
Wang Nan6371ca3b2015-11-06 13:49:37 +0000981 ret = -LIBBPF_ERRNO__LOAD;
Wang Nan55cffde2015-07-01 02:14:07 +0000982 pr_warning("load bpf program failed: %s\n", strerror(errno));
983
Wang Nan6371ca3b2015-11-06 13:49:37 +0000984 if (log_buf && log_buf[0] != '\0') {
985 ret = -LIBBPF_ERRNO__VERIFY;
Wang Nan55cffde2015-07-01 02:14:07 +0000986 pr_warning("-- BEGIN DUMP LOG ---\n");
987 pr_warning("\n%s\n", log_buf);
988 pr_warning("-- END LOG --\n");
Wang Nan705fa212016-07-13 10:44:02 +0000989 } else if (insns_cnt >= BPF_MAXINSNS) {
990 pr_warning("Program too large (%d insns), at most %d insns\n",
991 insns_cnt, BPF_MAXINSNS);
992 ret = -LIBBPF_ERRNO__PROG2BIG;
Wang Nan6371ca3b2015-11-06 13:49:37 +0000993 } else {
Wang Nan705fa212016-07-13 10:44:02 +0000994 /* Wrong program type? */
995 if (type != BPF_PROG_TYPE_KPROBE) {
996 int fd;
997
998 fd = bpf_load_program(BPF_PROG_TYPE_KPROBE, insns,
999 insns_cnt, license, kern_version,
1000 NULL, 0);
1001 if (fd >= 0) {
1002 close(fd);
1003 ret = -LIBBPF_ERRNO__PROGTYPE;
1004 goto out;
1005 }
Wang Nan6371ca3b2015-11-06 13:49:37 +00001006 }
Wang Nan705fa212016-07-13 10:44:02 +00001007
1008 if (log_buf)
1009 ret = -LIBBPF_ERRNO__KVER;
Wang Nan55cffde2015-07-01 02:14:07 +00001010 }
1011
1012out:
1013 free(log_buf);
1014 return ret;
1015}
1016
1017static int
1018bpf_program__load(struct bpf_program *prog,
1019 char *license, u32 kern_version)
1020{
Wang Nanb5805632015-11-16 12:10:09 +00001021 int err = 0, fd, i;
Wang Nan55cffde2015-07-01 02:14:07 +00001022
Wang Nanb5805632015-11-16 12:10:09 +00001023 if (prog->instances.nr < 0 || !prog->instances.fds) {
1024 if (prog->preprocessor) {
1025 pr_warning("Internal error: can't load program '%s'\n",
1026 prog->section_name);
1027 return -LIBBPF_ERRNO__INTERNAL;
1028 }
Wang Nan55cffde2015-07-01 02:14:07 +00001029
Wang Nanb5805632015-11-16 12:10:09 +00001030 prog->instances.fds = malloc(sizeof(int));
1031 if (!prog->instances.fds) {
1032 pr_warning("Not enough memory for BPF fds\n");
1033 return -ENOMEM;
1034 }
1035 prog->instances.nr = 1;
1036 prog->instances.fds[0] = -1;
1037 }
1038
1039 if (!prog->preprocessor) {
1040 if (prog->instances.nr != 1) {
1041 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
1042 prog->section_name, prog->instances.nr);
1043 }
Wang Nan5f44e4c82016-07-13 10:44:01 +00001044 err = load_program(prog->type, prog->insns, prog->insns_cnt,
Wang Nanb5805632015-11-16 12:10:09 +00001045 license, kern_version, &fd);
1046 if (!err)
1047 prog->instances.fds[0] = fd;
1048 goto out;
1049 }
1050
1051 for (i = 0; i < prog->instances.nr; i++) {
1052 struct bpf_prog_prep_result result;
1053 bpf_program_prep_t preprocessor = prog->preprocessor;
1054
1055 bzero(&result, sizeof(result));
1056 err = preprocessor(prog, i, prog->insns,
1057 prog->insns_cnt, &result);
1058 if (err) {
1059 pr_warning("Preprocessing the %dth instance of program '%s' failed\n",
1060 i, prog->section_name);
1061 goto out;
1062 }
1063
1064 if (!result.new_insn_ptr || !result.new_insn_cnt) {
1065 pr_debug("Skip loading the %dth instance of program '%s'\n",
1066 i, prog->section_name);
1067 prog->instances.fds[i] = -1;
1068 if (result.pfd)
1069 *result.pfd = -1;
1070 continue;
1071 }
1072
Wang Nan5f44e4c82016-07-13 10:44:01 +00001073 err = load_program(prog->type, result.new_insn_ptr,
Wang Nanb5805632015-11-16 12:10:09 +00001074 result.new_insn_cnt,
1075 license, kern_version, &fd);
1076
1077 if (err) {
1078 pr_warning("Loading the %dth instance of program '%s' failed\n",
1079 i, prog->section_name);
1080 goto out;
1081 }
1082
1083 if (result.pfd)
1084 *result.pfd = fd;
1085 prog->instances.fds[i] = fd;
1086 }
1087out:
Wang Nan55cffde2015-07-01 02:14:07 +00001088 if (err)
1089 pr_warning("failed to load program '%s'\n",
1090 prog->section_name);
1091 zfree(&prog->insns);
1092 prog->insns_cnt = 0;
1093 return err;
1094}
1095
1096static int
1097bpf_object__load_progs(struct bpf_object *obj)
1098{
1099 size_t i;
1100 int err;
1101
1102 for (i = 0; i < obj->nr_programs; i++) {
1103 err = bpf_program__load(&obj->programs[i],
1104 obj->license,
1105 obj->kern_version);
1106 if (err)
1107 return err;
1108 }
1109 return 0;
1110}
1111
Wang Nancb1e5e92015-07-01 02:13:57 +00001112static int bpf_object__validate(struct bpf_object *obj)
1113{
1114 if (obj->kern_version == 0) {
1115 pr_warning("%s doesn't provide kernel version\n",
1116 obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +00001117 return -LIBBPF_ERRNO__KVERSION;
Wang Nancb1e5e92015-07-01 02:13:57 +00001118 }
1119 return 0;
1120}
1121
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001122static struct bpf_object *
Wang Nan6c956392015-07-01 02:13:54 +00001123__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001124{
1125 struct bpf_object *obj;
Wang Nan6371ca3b2015-11-06 13:49:37 +00001126 int err;
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001127
1128 if (elf_version(EV_CURRENT) == EV_NONE) {
1129 pr_warning("failed to init libelf for %s\n", path);
Wang Nan6371ca3b2015-11-06 13:49:37 +00001130 return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001131 }
1132
Wang Nan6c956392015-07-01 02:13:54 +00001133 obj = bpf_object__new(path, obj_buf, obj_buf_sz);
Wang Nan6371ca3b2015-11-06 13:49:37 +00001134 if (IS_ERR(obj))
1135 return obj;
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001136
Wang Nan6371ca3b2015-11-06 13:49:37 +00001137 CHECK_ERR(bpf_object__elf_init(obj), err, out);
1138 CHECK_ERR(bpf_object__check_endianness(obj), err, out);
1139 CHECK_ERR(bpf_object__elf_collect(obj), err, out);
1140 CHECK_ERR(bpf_object__collect_reloc(obj), err, out);
1141 CHECK_ERR(bpf_object__validate(obj), err, out);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001142
1143 bpf_object__elf_finish(obj);
1144 return obj;
1145out:
1146 bpf_object__close(obj);
Wang Nan6371ca3b2015-11-06 13:49:37 +00001147 return ERR_PTR(err);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001148}
1149
1150struct bpf_object *bpf_object__open(const char *path)
1151{
1152 /* param validation */
1153 if (!path)
1154 return NULL;
1155
1156 pr_debug("loading %s\n", path);
1157
Wang Nan6c956392015-07-01 02:13:54 +00001158 return __bpf_object__open(path, NULL, 0);
1159}
1160
1161struct bpf_object *bpf_object__open_buffer(void *obj_buf,
Wang Nanacf860a2015-08-27 02:30:55 +00001162 size_t obj_buf_sz,
1163 const char *name)
Wang Nan6c956392015-07-01 02:13:54 +00001164{
Wang Nanacf860a2015-08-27 02:30:55 +00001165 char tmp_name[64];
1166
Wang Nan6c956392015-07-01 02:13:54 +00001167 /* param validation */
1168 if (!obj_buf || obj_buf_sz <= 0)
1169 return NULL;
1170
Wang Nanacf860a2015-08-27 02:30:55 +00001171 if (!name) {
1172 snprintf(tmp_name, sizeof(tmp_name), "%lx-%lx",
1173 (unsigned long)obj_buf,
1174 (unsigned long)obj_buf_sz);
1175 tmp_name[sizeof(tmp_name) - 1] = '\0';
1176 name = tmp_name;
1177 }
1178 pr_debug("loading object '%s' from buffer\n",
1179 name);
Wang Nan6c956392015-07-01 02:13:54 +00001180
Wang Nanacf860a2015-08-27 02:30:55 +00001181 return __bpf_object__open(name, obj_buf, obj_buf_sz);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001182}
1183
Wang Nan52d33522015-07-01 02:14:04 +00001184int bpf_object__unload(struct bpf_object *obj)
1185{
1186 size_t i;
1187
1188 if (!obj)
1189 return -EINVAL;
1190
Wang Nan9d759a92015-11-27 08:47:35 +00001191 for (i = 0; i < obj->nr_maps; i++)
1192 zclose(obj->maps[i].fd);
Wang Nan52d33522015-07-01 02:14:04 +00001193
Wang Nan55cffde2015-07-01 02:14:07 +00001194 for (i = 0; i < obj->nr_programs; i++)
1195 bpf_program__unload(&obj->programs[i]);
1196
Wang Nan52d33522015-07-01 02:14:04 +00001197 return 0;
1198}
1199
1200int bpf_object__load(struct bpf_object *obj)
1201{
Wang Nan6371ca3b2015-11-06 13:49:37 +00001202 int err;
1203
Wang Nan52d33522015-07-01 02:14:04 +00001204 if (!obj)
1205 return -EINVAL;
1206
1207 if (obj->loaded) {
1208 pr_warning("object should not be loaded twice\n");
1209 return -EINVAL;
1210 }
1211
1212 obj->loaded = true;
Wang Nan6371ca3b2015-11-06 13:49:37 +00001213
1214 CHECK_ERR(bpf_object__create_maps(obj), err, out);
1215 CHECK_ERR(bpf_object__relocate(obj), err, out);
1216 CHECK_ERR(bpf_object__load_progs(obj), err, out);
Wang Nan52d33522015-07-01 02:14:04 +00001217
1218 return 0;
1219out:
1220 bpf_object__unload(obj);
1221 pr_warning("failed to load object '%s'\n", obj->path);
Wang Nan6371ca3b2015-11-06 13:49:37 +00001222 return err;
Wang Nan52d33522015-07-01 02:14:04 +00001223}
1224
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001225void bpf_object__close(struct bpf_object *obj)
1226{
Wang Nana5b8bd42015-07-01 02:14:00 +00001227 size_t i;
1228
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001229 if (!obj)
1230 return;
1231
1232 bpf_object__elf_finish(obj);
Wang Nan52d33522015-07-01 02:14:04 +00001233 bpf_object__unload(obj);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001234
Wang Nan9d759a92015-11-27 08:47:35 +00001235 for (i = 0; i < obj->nr_maps; i++) {
Wang Nan561bbcc2015-11-27 08:47:36 +00001236 zfree(&obj->maps[i].name);
Wang Nan9d759a92015-11-27 08:47:35 +00001237 if (obj->maps[i].clear_priv)
1238 obj->maps[i].clear_priv(&obj->maps[i],
1239 obj->maps[i].priv);
1240 obj->maps[i].priv = NULL;
1241 obj->maps[i].clear_priv = NULL;
1242 }
1243 zfree(&obj->maps);
1244 obj->nr_maps = 0;
Wang Nana5b8bd42015-07-01 02:14:00 +00001245
1246 if (obj->programs && obj->nr_programs) {
1247 for (i = 0; i < obj->nr_programs; i++)
1248 bpf_program__exit(&obj->programs[i]);
1249 }
1250 zfree(&obj->programs);
1251
Wang Nan9a208ef2015-07-01 02:14:10 +00001252 list_del(&obj->list);
Wang Nan1a5e3fb2015-07-01 02:13:53 +00001253 free(obj);
1254}
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001255
Wang Nan9a208ef2015-07-01 02:14:10 +00001256struct bpf_object *
1257bpf_object__next(struct bpf_object *prev)
1258{
1259 struct bpf_object *next;
1260
1261 if (!prev)
1262 next = list_first_entry(&bpf_objects_list,
1263 struct bpf_object,
1264 list);
1265 else
1266 next = list_next_entry(prev, list);
1267
1268 /* Empty list is noticed here so don't need checking on entry. */
1269 if (&next->list == &bpf_objects_list)
1270 return NULL;
1271
1272 return next;
1273}
1274
Arnaldo Carvalho de Meloa7fe0452016-06-03 12:22:51 -03001275const char *bpf_object__name(struct bpf_object *obj)
Wang Nanacf860a2015-08-27 02:30:55 +00001276{
Arnaldo Carvalho de Meloa7fe0452016-06-03 12:22:51 -03001277 return obj ? obj->path : ERR_PTR(-EINVAL);
Wang Nanacf860a2015-08-27 02:30:55 +00001278}
1279
Arnaldo Carvalho de Meloa7fe0452016-06-03 12:22:51 -03001280unsigned int bpf_object__kversion(struct bpf_object *obj)
Wang Nan45825d82015-11-06 13:49:38 +00001281{
Arnaldo Carvalho de Meloa7fe0452016-06-03 12:22:51 -03001282 return obj ? obj->kern_version : 0;
Wang Nan45825d82015-11-06 13:49:38 +00001283}
1284
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001285struct bpf_program *
1286bpf_program__next(struct bpf_program *prev, struct bpf_object *obj)
1287{
1288 size_t idx;
1289
1290 if (!obj->programs)
1291 return NULL;
1292 /* First handler */
1293 if (prev == NULL)
1294 return &obj->programs[0];
1295
1296 if (prev->obj != obj) {
1297 pr_warning("error: program handler doesn't match object\n");
1298 return NULL;
1299 }
1300
1301 idx = (prev - obj->programs) + 1;
1302 if (idx >= obj->nr_programs)
1303 return NULL;
1304 return &obj->programs[idx];
1305}
1306
Arnaldo Carvalho de Meloedb13ed2016-06-03 12:38:21 -03001307int bpf_program__set_priv(struct bpf_program *prog, void *priv,
1308 bpf_program_clear_priv_t clear_priv)
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001309{
1310 if (prog->priv && prog->clear_priv)
1311 prog->clear_priv(prog, prog->priv);
1312
1313 prog->priv = priv;
1314 prog->clear_priv = clear_priv;
1315 return 0;
1316}
1317
Arnaldo Carvalho de Melobe834ff2016-06-03 12:36:39 -03001318void *bpf_program__priv(struct bpf_program *prog)
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001319{
Arnaldo Carvalho de Melobe834ff2016-06-03 12:36:39 -03001320 return prog ? prog->priv : ERR_PTR(-EINVAL);
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001321}
1322
Namhyung Kim715f8db2015-11-03 20:21:05 +09001323const char *bpf_program__title(struct bpf_program *prog, bool needs_copy)
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001324{
1325 const char *title;
1326
1327 title = prog->section_name;
Namhyung Kim715f8db2015-11-03 20:21:05 +09001328 if (needs_copy) {
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001329 title = strdup(title);
1330 if (!title) {
1331 pr_warning("failed to strdup program title\n");
Wang Nan6371ca3b2015-11-06 13:49:37 +00001332 return ERR_PTR(-ENOMEM);
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001333 }
1334 }
1335
1336 return title;
1337}
1338
1339int bpf_program__fd(struct bpf_program *prog)
1340{
Wang Nanb5805632015-11-16 12:10:09 +00001341 return bpf_program__nth_fd(prog, 0);
1342}
1343
1344int bpf_program__set_prep(struct bpf_program *prog, int nr_instances,
1345 bpf_program_prep_t prep)
1346{
1347 int *instances_fds;
1348
1349 if (nr_instances <= 0 || !prep)
1350 return -EINVAL;
1351
1352 if (prog->instances.nr > 0 || prog->instances.fds) {
1353 pr_warning("Can't set pre-processor after loading\n");
1354 return -EINVAL;
1355 }
1356
1357 instances_fds = malloc(sizeof(int) * nr_instances);
1358 if (!instances_fds) {
1359 pr_warning("alloc memory failed for fds\n");
1360 return -ENOMEM;
1361 }
1362
1363 /* fill all fd with -1 */
1364 memset(instances_fds, -1, sizeof(int) * nr_instances);
1365
1366 prog->instances.nr = nr_instances;
1367 prog->instances.fds = instances_fds;
1368 prog->preprocessor = prep;
1369 return 0;
1370}
1371
1372int bpf_program__nth_fd(struct bpf_program *prog, int n)
1373{
1374 int fd;
1375
1376 if (n >= prog->instances.nr || n < 0) {
1377 pr_warning("Can't get the %dth fd from program %s: only %d instances\n",
1378 n, prog->section_name, prog->instances.nr);
1379 return -EINVAL;
1380 }
1381
1382 fd = prog->instances.fds[n];
1383 if (fd < 0) {
1384 pr_warning("%dth instance of program '%s' is invalid\n",
1385 n, prog->section_name);
1386 return -ENOENT;
1387 }
1388
1389 return fd;
Wang Nanaa9b1ac2015-07-01 02:14:08 +00001390}
Wang Nan9d759a92015-11-27 08:47:35 +00001391
Wang Nan5f44e4c82016-07-13 10:44:01 +00001392static void bpf_program__set_type(struct bpf_program *prog,
1393 enum bpf_prog_type type)
1394{
1395 prog->type = type;
1396}
1397
1398int bpf_program__set_tracepoint(struct bpf_program *prog)
1399{
1400 if (!prog)
1401 return -EINVAL;
1402 bpf_program__set_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1403 return 0;
1404}
1405
1406int bpf_program__set_kprobe(struct bpf_program *prog)
1407{
1408 if (!prog)
1409 return -EINVAL;
1410 bpf_program__set_type(prog, BPF_PROG_TYPE_KPROBE);
1411 return 0;
1412}
1413
1414static bool bpf_program__is_type(struct bpf_program *prog,
1415 enum bpf_prog_type type)
1416{
1417 return prog ? (prog->type == type) : false;
1418}
1419
1420bool bpf_program__is_tracepoint(struct bpf_program *prog)
1421{
1422 return bpf_program__is_type(prog, BPF_PROG_TYPE_TRACEPOINT);
1423}
1424
1425bool bpf_program__is_kprobe(struct bpf_program *prog)
1426{
1427 return bpf_program__is_type(prog, BPF_PROG_TYPE_KPROBE);
1428}
1429
Arnaldo Carvalho de Melo6e009e62016-06-03 12:15:52 -03001430int bpf_map__fd(struct bpf_map *map)
Wang Nan9d759a92015-11-27 08:47:35 +00001431{
Arnaldo Carvalho de Melo6e009e62016-06-03 12:15:52 -03001432 return map ? map->fd : -EINVAL;
Wang Nan9d759a92015-11-27 08:47:35 +00001433}
1434
Arnaldo Carvalho de Melo53897a72016-06-02 14:21:06 -03001435const struct bpf_map_def *bpf_map__def(struct bpf_map *map)
Wang Nan9d759a92015-11-27 08:47:35 +00001436{
Arnaldo Carvalho de Melo53897a72016-06-02 14:21:06 -03001437 return map ? &map->def : ERR_PTR(-EINVAL);
Wang Nan9d759a92015-11-27 08:47:35 +00001438}
1439
Arnaldo Carvalho de Melo009ad5d2016-06-02 11:02:05 -03001440const char *bpf_map__name(struct bpf_map *map)
Wang Nan561bbcc2015-11-27 08:47:36 +00001441{
Arnaldo Carvalho de Melo009ad5d2016-06-02 11:02:05 -03001442 return map ? map->name : NULL;
Wang Nan561bbcc2015-11-27 08:47:36 +00001443}
1444
Arnaldo Carvalho de Meloedb13ed2016-06-03 12:38:21 -03001445int bpf_map__set_priv(struct bpf_map *map, void *priv,
1446 bpf_map_clear_priv_t clear_priv)
Wang Nan9d759a92015-11-27 08:47:35 +00001447{
1448 if (!map)
1449 return -EINVAL;
1450
1451 if (map->priv) {
1452 if (map->clear_priv)
1453 map->clear_priv(map, map->priv);
1454 }
1455
1456 map->priv = priv;
1457 map->clear_priv = clear_priv;
1458 return 0;
1459}
1460
Arnaldo Carvalho de Melob4cbfa52016-06-02 10:51:59 -03001461void *bpf_map__priv(struct bpf_map *map)
Wang Nan9d759a92015-11-27 08:47:35 +00001462{
Arnaldo Carvalho de Melob4cbfa52016-06-02 10:51:59 -03001463 return map ? map->priv : ERR_PTR(-EINVAL);
Wang Nan9d759a92015-11-27 08:47:35 +00001464}
1465
1466struct bpf_map *
1467bpf_map__next(struct bpf_map *prev, struct bpf_object *obj)
1468{
1469 size_t idx;
1470 struct bpf_map *s, *e;
1471
1472 if (!obj || !obj->maps)
1473 return NULL;
1474
1475 s = obj->maps;
1476 e = obj->maps + obj->nr_maps;
1477
1478 if (prev == NULL)
1479 return s;
1480
1481 if ((prev < s) || (prev >= e)) {
1482 pr_warning("error in %s: map handler doesn't belong to object\n",
1483 __func__);
1484 return NULL;
1485 }
1486
1487 idx = (prev - obj->maps) + 1;
1488 if (idx >= obj->nr_maps)
1489 return NULL;
1490 return &obj->maps[idx];
1491}
Wang Nan561bbcc2015-11-27 08:47:36 +00001492
1493struct bpf_map *
Arnaldo Carvalho de Meloa7fe0452016-06-03 12:22:51 -03001494bpf_object__find_map_by_name(struct bpf_object *obj, const char *name)
Wang Nan561bbcc2015-11-27 08:47:36 +00001495{
1496 struct bpf_map *pos;
1497
1498 bpf_map__for_each(pos, obj) {
Wang Nan973170e2015-12-08 02:25:29 +00001499 if (pos->name && !strcmp(pos->name, name))
Wang Nan561bbcc2015-11-27 08:47:36 +00001500 return pos;
1501 }
1502 return NULL;
1503}