2 * Common eBPF ELF object loading operations.
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.
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!)
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.
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>
30 #include <asm/unistd.h>
31 #include <linux/kernel.h>
32 #include <linux/bpf.h>
33 #include <linux/list.h>
40 #define __printf(a, b) __attribute__((format(printf, a, b)))
43 static int __base_pr(const char *format
, ...)
48 va_start(args
, format
);
49 err
= vfprintf(stderr
, format
, args
);
54 static __printf(1, 2) libbpf_print_fn_t __pr_warning
= __base_pr
;
55 static __printf(1, 2) libbpf_print_fn_t __pr_info
= __base_pr
;
56 static __printf(1, 2) libbpf_print_fn_t __pr_debug
;
58 #define __pr(func, fmt, ...) \
61 (func)("libbpf: " fmt, ##__VA_ARGS__); \
64 #define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__)
65 #define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__)
66 #define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__)
68 void libbpf_set_print(libbpf_print_fn_t warn
,
69 libbpf_print_fn_t info
,
70 libbpf_print_fn_t debug
)
77 #define STRERR_BUFSIZE 128
79 #define ERRNO_OFFSET(e) ((e) - __LIBBPF_ERRNO__START)
80 #define ERRCODE_OFFSET(c) ERRNO_OFFSET(LIBBPF_ERRNO__##c)
81 #define NR_ERRNO (__LIBBPF_ERRNO__END - __LIBBPF_ERRNO__START)
83 static const char *libbpf_strerror_table
[NR_ERRNO
] = {
84 [ERRCODE_OFFSET(LIBELF
)] = "Something wrong in libelf",
85 [ERRCODE_OFFSET(FORMAT
)] = "BPF object format invalid",
86 [ERRCODE_OFFSET(KVERSION
)] = "'version' section incorrect or lost",
87 [ERRCODE_OFFSET(ENDIAN
)] = "Endian mismatch",
88 [ERRCODE_OFFSET(INTERNAL
)] = "Internal error in libbpf",
89 [ERRCODE_OFFSET(RELOC
)] = "Relocation failed",
90 [ERRCODE_OFFSET(VERIFY
)] = "Kernel verifier blocks program loading",
91 [ERRCODE_OFFSET(PROG2BIG
)] = "Program too big",
92 [ERRCODE_OFFSET(KVER
)] = "Incorrect kernel version",
95 int libbpf_strerror(int err
, char *buf
, size_t size
)
100 err
= err
> 0 ? err
: -err
;
102 if (err
< __LIBBPF_ERRNO__START
) {
105 ret
= strerror_r(err
, buf
, size
);
106 buf
[size
- 1] = '\0';
110 if (err
< __LIBBPF_ERRNO__END
) {
113 msg
= libbpf_strerror_table
[ERRNO_OFFSET(err
)];
114 snprintf(buf
, size
, "%s", msg
);
115 buf
[size
- 1] = '\0';
119 snprintf(buf
, size
, "Unknown libbpf error %d", err
);
120 buf
[size
- 1] = '\0';
124 #define CHECK_ERR(action, err, out) do { \
131 /* Copied from tools/perf/util/util.h */
133 # define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
137 # define zclose(fd) ({ \
140 ___err = close((fd)); \
145 #ifdef HAVE_LIBELF_MMAP_SUPPORT
146 # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ_MMAP
148 # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
152 * bpf_prog should be a better name but it has been used in
156 /* Index in elf obj file, for relocation use. */
159 struct bpf_insn
*insns
;
172 bpf_program_prep_t preprocessor
;
174 struct bpf_object
*obj
;
176 bpf_program_clear_priv_t clear_priv
;
182 struct bpf_map_def def
;
184 bpf_map_clear_priv_t clear_priv
;
187 static LIST_HEAD(bpf_objects_list
);
193 struct bpf_program
*programs
;
195 struct bpf_map
*maps
;
201 * Information when doing elf related work. Only valid if fd
220 * All loaded bpf_object is linked in a list, which is
221 * hidden to caller. bpf_objects__<func> handlers deal with
224 struct list_head list
;
227 #define obj_elf_valid(o) ((o)->efile.elf)
229 static void bpf_program__unload(struct bpf_program
*prog
)
237 * If the object is opened but the program was never loaded,
238 * it is possible that prog->instances.nr == -1.
240 if (prog
->instances
.nr
> 0) {
241 for (i
= 0; i
< prog
->instances
.nr
; i
++)
242 zclose(prog
->instances
.fds
[i
]);
243 } else if (prog
->instances
.nr
!= -1) {
244 pr_warning("Internal error: instances.nr is %d\n",
248 prog
->instances
.nr
= -1;
249 zfree(&prog
->instances
.fds
);
252 static void bpf_program__exit(struct bpf_program
*prog
)
257 if (prog
->clear_priv
)
258 prog
->clear_priv(prog
, prog
->priv
);
261 prog
->clear_priv
= NULL
;
263 bpf_program__unload(prog
);
264 zfree(&prog
->section_name
);
266 zfree(&prog
->reloc_desc
);
274 bpf_program__init(void *data
, size_t size
, char *name
, int idx
,
275 struct bpf_program
*prog
)
277 if (size
< sizeof(struct bpf_insn
)) {
278 pr_warning("corrupted section '%s'\n", name
);
282 bzero(prog
, sizeof(*prog
));
284 prog
->section_name
= strdup(name
);
285 if (!prog
->section_name
) {
286 pr_warning("failed to alloc name for prog %s\n",
291 prog
->insns
= malloc(size
);
293 pr_warning("failed to alloc insns for %s\n", name
);
296 prog
->insns_cnt
= size
/ sizeof(struct bpf_insn
);
297 memcpy(prog
->insns
, data
,
298 prog
->insns_cnt
* sizeof(struct bpf_insn
));
300 prog
->instances
.fds
= NULL
;
301 prog
->instances
.nr
= -1;
305 bpf_program__exit(prog
);
310 bpf_object__add_program(struct bpf_object
*obj
, void *data
, size_t size
,
313 struct bpf_program prog
, *progs
;
316 err
= bpf_program__init(data
, size
, name
, idx
, &prog
);
320 progs
= obj
->programs
;
321 nr_progs
= obj
->nr_programs
;
323 progs
= realloc(progs
, sizeof(progs
[0]) * (nr_progs
+ 1));
326 * In this case the original obj->programs
327 * is still valid, so don't need special treat for
328 * bpf_close_object().
330 pr_warning("failed to alloc a new program '%s'\n",
332 bpf_program__exit(&prog
);
336 pr_debug("found program %s\n", prog
.section_name
);
337 obj
->programs
= progs
;
338 obj
->nr_programs
= nr_progs
+ 1;
340 progs
[nr_progs
] = prog
;
344 static struct bpf_object
*bpf_object__new(const char *path
,
348 struct bpf_object
*obj
;
350 obj
= calloc(1, sizeof(struct bpf_object
) + strlen(path
) + 1);
352 pr_warning("alloc memory failed for %s\n", path
);
353 return ERR_PTR(-ENOMEM
);
356 strcpy(obj
->path
, path
);
360 * Caller of this function should also calls
361 * bpf_object__elf_finish() after data collection to return
362 * obj_buf to user. If not, we should duplicate the buffer to
363 * avoid user freeing them before elf finish.
365 obj
->efile
.obj_buf
= obj_buf
;
366 obj
->efile
.obj_buf_sz
= obj_buf_sz
;
367 obj
->efile
.maps_shndx
= -1;
371 INIT_LIST_HEAD(&obj
->list
);
372 list_add(&obj
->list
, &bpf_objects_list
);
376 static void bpf_object__elf_finish(struct bpf_object
*obj
)
378 if (!obj_elf_valid(obj
))
381 if (obj
->efile
.elf
) {
382 elf_end(obj
->efile
.elf
);
383 obj
->efile
.elf
= NULL
;
385 obj
->efile
.symbols
= NULL
;
387 zfree(&obj
->efile
.reloc
);
388 obj
->efile
.nr_reloc
= 0;
389 zclose(obj
->efile
.fd
);
390 obj
->efile
.obj_buf
= NULL
;
391 obj
->efile
.obj_buf_sz
= 0;
394 static int bpf_object__elf_init(struct bpf_object
*obj
)
399 if (obj_elf_valid(obj
)) {
400 pr_warning("elf init: internal error\n");
401 return -LIBBPF_ERRNO__LIBELF
;
404 if (obj
->efile
.obj_buf_sz
> 0) {
406 * obj_buf should have been validated by
407 * bpf_object__open_buffer().
409 obj
->efile
.elf
= elf_memory(obj
->efile
.obj_buf
,
410 obj
->efile
.obj_buf_sz
);
412 obj
->efile
.fd
= open(obj
->path
, O_RDONLY
);
413 if (obj
->efile
.fd
< 0) {
414 pr_warning("failed to open %s: %s\n", obj
->path
,
419 obj
->efile
.elf
= elf_begin(obj
->efile
.fd
,
420 LIBBPF_ELF_C_READ_MMAP
,
424 if (!obj
->efile
.elf
) {
425 pr_warning("failed to open %s as ELF file\n",
427 err
= -LIBBPF_ERRNO__LIBELF
;
431 if (!gelf_getehdr(obj
->efile
.elf
, &obj
->efile
.ehdr
)) {
432 pr_warning("failed to get EHDR from %s\n",
434 err
= -LIBBPF_ERRNO__FORMAT
;
437 ep
= &obj
->efile
.ehdr
;
439 if ((ep
->e_type
!= ET_REL
) || (ep
->e_machine
!= 0)) {
440 pr_warning("%s is not an eBPF object file\n",
442 err
= -LIBBPF_ERRNO__FORMAT
;
448 bpf_object__elf_finish(obj
);
453 bpf_object__check_endianness(struct bpf_object
*obj
)
455 static unsigned int const endian
= 1;
457 switch (obj
->efile
.ehdr
.e_ident
[EI_DATA
]) {
459 /* We are big endian, BPF obj is little endian. */
460 if (*(unsigned char const *)&endian
!= 1)
465 /* We are little endian, BPF obj is big endian. */
466 if (*(unsigned char const *)&endian
!= 0)
470 return -LIBBPF_ERRNO__ENDIAN
;
476 pr_warning("Error: endianness mismatch.\n");
477 return -LIBBPF_ERRNO__ENDIAN
;
481 bpf_object__init_license(struct bpf_object
*obj
,
482 void *data
, size_t size
)
484 memcpy(obj
->license
, data
,
485 min(size
, sizeof(obj
->license
) - 1));
486 pr_debug("license of %s is %s\n", obj
->path
, obj
->license
);
491 bpf_object__init_kversion(struct bpf_object
*obj
,
492 void *data
, size_t size
)
496 if (size
!= sizeof(kver
)) {
497 pr_warning("invalid kver section in %s\n", obj
->path
);
498 return -LIBBPF_ERRNO__FORMAT
;
500 memcpy(&kver
, data
, sizeof(kver
));
501 obj
->kern_version
= kver
;
502 pr_debug("kernel version of %s is %x\n", obj
->path
,
508 bpf_object__init_maps(struct bpf_object
*obj
, void *data
,
514 nr_maps
= size
/ sizeof(struct bpf_map_def
);
515 if (!data
|| !nr_maps
) {
516 pr_debug("%s doesn't need map definition\n",
521 pr_debug("maps in %s: %zd bytes\n", obj
->path
, size
);
523 obj
->maps
= calloc(nr_maps
, sizeof(obj
->maps
[0]));
525 pr_warning("alloc maps for object failed\n");
528 obj
->nr_maps
= nr_maps
;
530 for (i
= 0; i
< nr_maps
; i
++) {
531 struct bpf_map_def
*def
= &obj
->maps
[i
].def
;
534 * fill all fd with -1 so won't close incorrect
535 * fd (fd=0 is stdin) when failure (zclose won't close
538 obj
->maps
[i
].fd
= -1;
540 /* Save map definition into obj->maps */
541 *def
= ((struct bpf_map_def
*)data
)[i
];
547 bpf_object__init_maps_name(struct bpf_object
*obj
)
550 Elf_Data
*symbols
= obj
->efile
.symbols
;
552 if (!symbols
|| obj
->efile
.maps_shndx
< 0)
555 for (i
= 0; i
< symbols
->d_size
/ sizeof(GElf_Sym
); i
++) {
558 const char *map_name
;
560 if (!gelf_getsym(symbols
, i
, &sym
))
562 if (sym
.st_shndx
!= obj
->efile
.maps_shndx
)
565 map_name
= elf_strptr(obj
->efile
.elf
,
566 obj
->efile
.strtabidx
,
568 map_idx
= sym
.st_value
/ sizeof(struct bpf_map_def
);
569 if (map_idx
>= obj
->nr_maps
) {
570 pr_warning("index of map \"%s\" is buggy: %zu > %zu\n",
571 map_name
, map_idx
, obj
->nr_maps
);
574 obj
->maps
[map_idx
].name
= strdup(map_name
);
575 if (!obj
->maps
[map_idx
].name
) {
576 pr_warning("failed to alloc map name\n");
579 pr_debug("map %zu is \"%s\"\n", map_idx
,
580 obj
->maps
[map_idx
].name
);
585 static int bpf_object__elf_collect(struct bpf_object
*obj
)
587 Elf
*elf
= obj
->efile
.elf
;
588 GElf_Ehdr
*ep
= &obj
->efile
.ehdr
;
590 int idx
= 0, err
= 0;
592 /* Elf is corrupted/truncated, avoid calling elf_strptr. */
593 if (!elf_rawdata(elf_getscn(elf
, ep
->e_shstrndx
), NULL
)) {
594 pr_warning("failed to get e_shstrndx from %s\n",
596 return -LIBBPF_ERRNO__FORMAT
;
599 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
605 if (gelf_getshdr(scn
, &sh
) != &sh
) {
606 pr_warning("failed to get section header from %s\n",
608 err
= -LIBBPF_ERRNO__FORMAT
;
612 name
= elf_strptr(elf
, ep
->e_shstrndx
, sh
.sh_name
);
614 pr_warning("failed to get section name from %s\n",
616 err
= -LIBBPF_ERRNO__FORMAT
;
620 data
= elf_getdata(scn
, 0);
622 pr_warning("failed to get section data from %s(%s)\n",
624 err
= -LIBBPF_ERRNO__FORMAT
;
627 pr_debug("section %s, size %ld, link %d, flags %lx, type=%d\n",
628 name
, (unsigned long)data
->d_size
,
629 (int)sh
.sh_link
, (unsigned long)sh
.sh_flags
,
632 if (strcmp(name
, "license") == 0)
633 err
= bpf_object__init_license(obj
,
636 else if (strcmp(name
, "version") == 0)
637 err
= bpf_object__init_kversion(obj
,
640 else if (strcmp(name
, "maps") == 0) {
641 err
= bpf_object__init_maps(obj
, data
->d_buf
,
643 obj
->efile
.maps_shndx
= idx
;
644 } else if (sh
.sh_type
== SHT_SYMTAB
) {
645 if (obj
->efile
.symbols
) {
646 pr_warning("bpf: multiple SYMTAB in %s\n",
648 err
= -LIBBPF_ERRNO__FORMAT
;
650 obj
->efile
.symbols
= data
;
651 obj
->efile
.strtabidx
= sh
.sh_link
;
653 } else if ((sh
.sh_type
== SHT_PROGBITS
) &&
654 (sh
.sh_flags
& SHF_EXECINSTR
) &&
655 (data
->d_size
> 0)) {
656 err
= bpf_object__add_program(obj
, data
->d_buf
,
657 data
->d_size
, name
, idx
);
659 char errmsg
[STRERR_BUFSIZE
];
661 strerror_r(-err
, errmsg
, sizeof(errmsg
));
662 pr_warning("failed to alloc program %s (%s): %s",
663 name
, obj
->path
, errmsg
);
665 } else if (sh
.sh_type
== SHT_REL
) {
666 void *reloc
= obj
->efile
.reloc
;
667 int nr_reloc
= obj
->efile
.nr_reloc
+ 1;
669 reloc
= realloc(reloc
,
670 sizeof(*obj
->efile
.reloc
) * nr_reloc
);
672 pr_warning("realloc failed\n");
675 int n
= nr_reloc
- 1;
677 obj
->efile
.reloc
= reloc
;
678 obj
->efile
.nr_reloc
= nr_reloc
;
680 obj
->efile
.reloc
[n
].shdr
= sh
;
681 obj
->efile
.reloc
[n
].data
= data
;
688 if (!obj
->efile
.strtabidx
|| obj
->efile
.strtabidx
>= idx
) {
689 pr_warning("Corrupted ELF file: index of strtab invalid\n");
690 return LIBBPF_ERRNO__FORMAT
;
692 if (obj
->efile
.maps_shndx
>= 0)
693 err
= bpf_object__init_maps_name(obj
);
698 static struct bpf_program
*
699 bpf_object__find_prog_by_idx(struct bpf_object
*obj
, int idx
)
701 struct bpf_program
*prog
;
704 for (i
= 0; i
< obj
->nr_programs
; i
++) {
705 prog
= &obj
->programs
[i
];
706 if (prog
->idx
== idx
)
713 bpf_program__collect_reloc(struct bpf_program
*prog
,
714 size_t nr_maps
, GElf_Shdr
*shdr
,
715 Elf_Data
*data
, Elf_Data
*symbols
,
720 pr_debug("collecting relocating info for: '%s'\n",
722 nrels
= shdr
->sh_size
/ shdr
->sh_entsize
;
724 prog
->reloc_desc
= malloc(sizeof(*prog
->reloc_desc
) * nrels
);
725 if (!prog
->reloc_desc
) {
726 pr_warning("failed to alloc memory in relocation\n");
729 prog
->nr_reloc
= nrels
;
731 for (i
= 0; i
< nrels
; i
++) {
734 unsigned int insn_idx
;
735 struct bpf_insn
*insns
= prog
->insns
;
738 if (!gelf_getrel(data
, i
, &rel
)) {
739 pr_warning("relocation: failed to get %d reloc\n", i
);
740 return -LIBBPF_ERRNO__FORMAT
;
743 if (!gelf_getsym(symbols
,
744 GELF_R_SYM(rel
.r_info
),
746 pr_warning("relocation: symbol %"PRIx64
" not found\n",
747 GELF_R_SYM(rel
.r_info
));
748 return -LIBBPF_ERRNO__FORMAT
;
751 if (sym
.st_shndx
!= maps_shndx
) {
752 pr_warning("Program '%s' contains non-map related relo data pointing to section %u\n",
753 prog
->section_name
, sym
.st_shndx
);
754 return -LIBBPF_ERRNO__RELOC
;
757 insn_idx
= rel
.r_offset
/ sizeof(struct bpf_insn
);
758 pr_debug("relocation: insn_idx=%u\n", insn_idx
);
760 if (insns
[insn_idx
].code
!= (BPF_LD
| BPF_IMM
| BPF_DW
)) {
761 pr_warning("bpf: relocation: invalid relo for insns[%d].code 0x%x\n",
762 insn_idx
, insns
[insn_idx
].code
);
763 return -LIBBPF_ERRNO__RELOC
;
766 map_idx
= sym
.st_value
/ sizeof(struct bpf_map_def
);
767 if (map_idx
>= nr_maps
) {
768 pr_warning("bpf relocation: map_idx %d large than %d\n",
769 (int)map_idx
, (int)nr_maps
- 1);
770 return -LIBBPF_ERRNO__RELOC
;
773 prog
->reloc_desc
[i
].insn_idx
= insn_idx
;
774 prog
->reloc_desc
[i
].map_idx
= map_idx
;
780 bpf_object__create_maps(struct bpf_object
*obj
)
784 for (i
= 0; i
< obj
->nr_maps
; i
++) {
785 struct bpf_map_def
*def
= &obj
->maps
[i
].def
;
786 int *pfd
= &obj
->maps
[i
].fd
;
788 *pfd
= bpf_create_map(def
->type
,
796 pr_warning("failed to create map: %s\n",
798 for (j
= 0; j
< i
; j
++)
799 zclose(obj
->maps
[j
].fd
);
802 pr_debug("create map: fd=%d\n", *pfd
);
809 bpf_program__relocate(struct bpf_program
*prog
, struct bpf_object
*obj
)
813 if (!prog
|| !prog
->reloc_desc
)
816 for (i
= 0; i
< prog
->nr_reloc
; i
++) {
817 int insn_idx
, map_idx
;
818 struct bpf_insn
*insns
= prog
->insns
;
820 insn_idx
= prog
->reloc_desc
[i
].insn_idx
;
821 map_idx
= prog
->reloc_desc
[i
].map_idx
;
823 if (insn_idx
>= (int)prog
->insns_cnt
) {
824 pr_warning("relocation out of range: '%s'\n",
826 return -LIBBPF_ERRNO__RELOC
;
828 insns
[insn_idx
].src_reg
= BPF_PSEUDO_MAP_FD
;
829 insns
[insn_idx
].imm
= obj
->maps
[map_idx
].fd
;
832 zfree(&prog
->reloc_desc
);
839 bpf_object__relocate(struct bpf_object
*obj
)
841 struct bpf_program
*prog
;
845 for (i
= 0; i
< obj
->nr_programs
; i
++) {
846 prog
= &obj
->programs
[i
];
848 err
= bpf_program__relocate(prog
, obj
);
850 pr_warning("failed to relocate '%s'\n",
858 static int bpf_object__collect_reloc(struct bpf_object
*obj
)
862 if (!obj_elf_valid(obj
)) {
863 pr_warning("Internal error: elf object is closed\n");
864 return -LIBBPF_ERRNO__INTERNAL
;
867 for (i
= 0; i
< obj
->efile
.nr_reloc
; i
++) {
868 GElf_Shdr
*shdr
= &obj
->efile
.reloc
[i
].shdr
;
869 Elf_Data
*data
= obj
->efile
.reloc
[i
].data
;
870 int idx
= shdr
->sh_info
;
871 struct bpf_program
*prog
;
872 size_t nr_maps
= obj
->nr_maps
;
874 if (shdr
->sh_type
!= SHT_REL
) {
875 pr_warning("internal error at %d\n", __LINE__
);
876 return -LIBBPF_ERRNO__INTERNAL
;
879 prog
= bpf_object__find_prog_by_idx(obj
, idx
);
881 pr_warning("relocation failed: no %d section\n",
883 return -LIBBPF_ERRNO__RELOC
;
886 err
= bpf_program__collect_reloc(prog
, nr_maps
,
889 obj
->efile
.maps_shndx
);
897 load_program(struct bpf_insn
*insns
, int insns_cnt
,
898 char *license
, u32 kern_version
, int *pfd
)
903 if (!insns
|| !insns_cnt
)
906 log_buf
= malloc(BPF_LOG_BUF_SIZE
);
908 pr_warning("Alloc log buffer for bpf loader error, continue without log\n");
910 ret
= bpf_load_program(BPF_PROG_TYPE_KPROBE
, insns
,
911 insns_cnt
, license
, kern_version
,
912 log_buf
, BPF_LOG_BUF_SIZE
);
920 ret
= -LIBBPF_ERRNO__LOAD
;
921 pr_warning("load bpf program failed: %s\n", strerror(errno
));
923 if (log_buf
&& log_buf
[0] != '\0') {
924 ret
= -LIBBPF_ERRNO__VERIFY
;
925 pr_warning("-- BEGIN DUMP LOG ---\n");
926 pr_warning("\n%s\n", log_buf
);
927 pr_warning("-- END LOG --\n");
929 if (insns_cnt
>= BPF_MAXINSNS
) {
930 pr_warning("Program too large (%d insns), at most %d insns\n",
931 insns_cnt
, BPF_MAXINSNS
);
932 ret
= -LIBBPF_ERRNO__PROG2BIG
;
933 } else if (log_buf
) {
934 pr_warning("log buffer is empty\n");
935 ret
= -LIBBPF_ERRNO__KVER
;
945 bpf_program__load(struct bpf_program
*prog
,
946 char *license
, u32 kern_version
)
950 if (prog
->instances
.nr
< 0 || !prog
->instances
.fds
) {
951 if (prog
->preprocessor
) {
952 pr_warning("Internal error: can't load program '%s'\n",
954 return -LIBBPF_ERRNO__INTERNAL
;
957 prog
->instances
.fds
= malloc(sizeof(int));
958 if (!prog
->instances
.fds
) {
959 pr_warning("Not enough memory for BPF fds\n");
962 prog
->instances
.nr
= 1;
963 prog
->instances
.fds
[0] = -1;
966 if (!prog
->preprocessor
) {
967 if (prog
->instances
.nr
!= 1) {
968 pr_warning("Program '%s' is inconsistent: nr(%d) != 1\n",
969 prog
->section_name
, prog
->instances
.nr
);
971 err
= load_program(prog
->insns
, prog
->insns_cnt
,
972 license
, kern_version
, &fd
);
974 prog
->instances
.fds
[0] = fd
;
978 for (i
= 0; i
< prog
->instances
.nr
; i
++) {
979 struct bpf_prog_prep_result result
;
980 bpf_program_prep_t preprocessor
= prog
->preprocessor
;
982 bzero(&result
, sizeof(result
));
983 err
= preprocessor(prog
, i
, prog
->insns
,
984 prog
->insns_cnt
, &result
);
986 pr_warning("Preprocessing the %dth instance of program '%s' failed\n",
987 i
, prog
->section_name
);
991 if (!result
.new_insn_ptr
|| !result
.new_insn_cnt
) {
992 pr_debug("Skip loading the %dth instance of program '%s'\n",
993 i
, prog
->section_name
);
994 prog
->instances
.fds
[i
] = -1;
1000 err
= load_program(result
.new_insn_ptr
,
1001 result
.new_insn_cnt
,
1002 license
, kern_version
, &fd
);
1005 pr_warning("Loading the %dth instance of program '%s' failed\n",
1006 i
, prog
->section_name
);
1012 prog
->instances
.fds
[i
] = fd
;
1016 pr_warning("failed to load program '%s'\n",
1017 prog
->section_name
);
1018 zfree(&prog
->insns
);
1019 prog
->insns_cnt
= 0;
1024 bpf_object__load_progs(struct bpf_object
*obj
)
1029 for (i
= 0; i
< obj
->nr_programs
; i
++) {
1030 err
= bpf_program__load(&obj
->programs
[i
],
1039 static int bpf_object__validate(struct bpf_object
*obj
)
1041 if (obj
->kern_version
== 0) {
1042 pr_warning("%s doesn't provide kernel version\n",
1044 return -LIBBPF_ERRNO__KVERSION
;
1049 static struct bpf_object
*
1050 __bpf_object__open(const char *path
, void *obj_buf
, size_t obj_buf_sz
)
1052 struct bpf_object
*obj
;
1055 if (elf_version(EV_CURRENT
) == EV_NONE
) {
1056 pr_warning("failed to init libelf for %s\n", path
);
1057 return ERR_PTR(-LIBBPF_ERRNO__LIBELF
);
1060 obj
= bpf_object__new(path
, obj_buf
, obj_buf_sz
);
1064 CHECK_ERR(bpf_object__elf_init(obj
), err
, out
);
1065 CHECK_ERR(bpf_object__check_endianness(obj
), err
, out
);
1066 CHECK_ERR(bpf_object__elf_collect(obj
), err
, out
);
1067 CHECK_ERR(bpf_object__collect_reloc(obj
), err
, out
);
1068 CHECK_ERR(bpf_object__validate(obj
), err
, out
);
1070 bpf_object__elf_finish(obj
);
1073 bpf_object__close(obj
);
1074 return ERR_PTR(err
);
1077 struct bpf_object
*bpf_object__open(const char *path
)
1079 /* param validation */
1083 pr_debug("loading %s\n", path
);
1085 return __bpf_object__open(path
, NULL
, 0);
1088 struct bpf_object
*bpf_object__open_buffer(void *obj_buf
,
1094 /* param validation */
1095 if (!obj_buf
|| obj_buf_sz
<= 0)
1099 snprintf(tmp_name
, sizeof(tmp_name
), "%lx-%lx",
1100 (unsigned long)obj_buf
,
1101 (unsigned long)obj_buf_sz
);
1102 tmp_name
[sizeof(tmp_name
) - 1] = '\0';
1105 pr_debug("loading object '%s' from buffer\n",
1108 return __bpf_object__open(name
, obj_buf
, obj_buf_sz
);
1111 int bpf_object__unload(struct bpf_object
*obj
)
1118 for (i
= 0; i
< obj
->nr_maps
; i
++)
1119 zclose(obj
->maps
[i
].fd
);
1121 for (i
= 0; i
< obj
->nr_programs
; i
++)
1122 bpf_program__unload(&obj
->programs
[i
]);
1127 int bpf_object__load(struct bpf_object
*obj
)
1135 pr_warning("object should not be loaded twice\n");
1141 CHECK_ERR(bpf_object__create_maps(obj
), err
, out
);
1142 CHECK_ERR(bpf_object__relocate(obj
), err
, out
);
1143 CHECK_ERR(bpf_object__load_progs(obj
), err
, out
);
1147 bpf_object__unload(obj
);
1148 pr_warning("failed to load object '%s'\n", obj
->path
);
1152 void bpf_object__close(struct bpf_object
*obj
)
1159 bpf_object__elf_finish(obj
);
1160 bpf_object__unload(obj
);
1162 for (i
= 0; i
< obj
->nr_maps
; i
++) {
1163 zfree(&obj
->maps
[i
].name
);
1164 if (obj
->maps
[i
].clear_priv
)
1165 obj
->maps
[i
].clear_priv(&obj
->maps
[i
],
1167 obj
->maps
[i
].priv
= NULL
;
1168 obj
->maps
[i
].clear_priv
= NULL
;
1173 if (obj
->programs
&& obj
->nr_programs
) {
1174 for (i
= 0; i
< obj
->nr_programs
; i
++)
1175 bpf_program__exit(&obj
->programs
[i
]);
1177 zfree(&obj
->programs
);
1179 list_del(&obj
->list
);
1184 bpf_object__next(struct bpf_object
*prev
)
1186 struct bpf_object
*next
;
1189 next
= list_first_entry(&bpf_objects_list
,
1193 next
= list_next_entry(prev
, list
);
1195 /* Empty list is noticed here so don't need checking on entry. */
1196 if (&next
->list
== &bpf_objects_list
)
1202 const char *bpf_object__name(struct bpf_object
*obj
)
1204 return obj
? obj
->path
: ERR_PTR(-EINVAL
);
1207 unsigned int bpf_object__kversion(struct bpf_object
*obj
)
1209 return obj
? obj
->kern_version
: 0;
1212 struct bpf_program
*
1213 bpf_program__next(struct bpf_program
*prev
, struct bpf_object
*obj
)
1221 return &obj
->programs
[0];
1223 if (prev
->obj
!= obj
) {
1224 pr_warning("error: program handler doesn't match object\n");
1228 idx
= (prev
- obj
->programs
) + 1;
1229 if (idx
>= obj
->nr_programs
)
1231 return &obj
->programs
[idx
];
1234 int bpf_program__set_priv(struct bpf_program
*prog
, void *priv
,
1235 bpf_program_clear_priv_t clear_priv
)
1237 if (prog
->priv
&& prog
->clear_priv
)
1238 prog
->clear_priv(prog
, prog
->priv
);
1241 prog
->clear_priv
= clear_priv
;
1245 void *bpf_program__priv(struct bpf_program
*prog
)
1247 return prog
? prog
->priv
: ERR_PTR(-EINVAL
);
1250 const char *bpf_program__title(struct bpf_program
*prog
, bool needs_copy
)
1254 title
= prog
->section_name
;
1256 title
= strdup(title
);
1258 pr_warning("failed to strdup program title\n");
1259 return ERR_PTR(-ENOMEM
);
1266 int bpf_program__fd(struct bpf_program
*prog
)
1268 return bpf_program__nth_fd(prog
, 0);
1271 int bpf_program__set_prep(struct bpf_program
*prog
, int nr_instances
,
1272 bpf_program_prep_t prep
)
1276 if (nr_instances
<= 0 || !prep
)
1279 if (prog
->instances
.nr
> 0 || prog
->instances
.fds
) {
1280 pr_warning("Can't set pre-processor after loading\n");
1284 instances_fds
= malloc(sizeof(int) * nr_instances
);
1285 if (!instances_fds
) {
1286 pr_warning("alloc memory failed for fds\n");
1290 /* fill all fd with -1 */
1291 memset(instances_fds
, -1, sizeof(int) * nr_instances
);
1293 prog
->instances
.nr
= nr_instances
;
1294 prog
->instances
.fds
= instances_fds
;
1295 prog
->preprocessor
= prep
;
1299 int bpf_program__nth_fd(struct bpf_program
*prog
, int n
)
1303 if (n
>= prog
->instances
.nr
|| n
< 0) {
1304 pr_warning("Can't get the %dth fd from program %s: only %d instances\n",
1305 n
, prog
->section_name
, prog
->instances
.nr
);
1309 fd
= prog
->instances
.fds
[n
];
1311 pr_warning("%dth instance of program '%s' is invalid\n",
1312 n
, prog
->section_name
);
1319 int bpf_map__fd(struct bpf_map
*map
)
1321 return map
? map
->fd
: -EINVAL
;
1324 const struct bpf_map_def
*bpf_map__def(struct bpf_map
*map
)
1326 return map
? &map
->def
: ERR_PTR(-EINVAL
);
1329 const char *bpf_map__name(struct bpf_map
*map
)
1331 return map
? map
->name
: NULL
;
1334 int bpf_map__set_priv(struct bpf_map
*map
, void *priv
,
1335 bpf_map_clear_priv_t clear_priv
)
1341 if (map
->clear_priv
)
1342 map
->clear_priv(map
, map
->priv
);
1346 map
->clear_priv
= clear_priv
;
1350 void *bpf_map__priv(struct bpf_map
*map
)
1352 return map
? map
->priv
: ERR_PTR(-EINVAL
);
1356 bpf_map__next(struct bpf_map
*prev
, struct bpf_object
*obj
)
1359 struct bpf_map
*s
, *e
;
1361 if (!obj
|| !obj
->maps
)
1365 e
= obj
->maps
+ obj
->nr_maps
;
1370 if ((prev
< s
) || (prev
>= e
)) {
1371 pr_warning("error in %s: map handler doesn't belong to object\n",
1376 idx
= (prev
- obj
->maps
) + 1;
1377 if (idx
>= obj
->nr_maps
)
1379 return &obj
->maps
[idx
];
1383 bpf_object__find_map_by_name(struct bpf_object
*obj
, const char *name
)
1385 struct bpf_map
*pos
;
1387 bpf_map__for_each(pos
, obj
) {
1388 if (pos
->name
&& !strcmp(pos
->name
, name
))