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.
16 #include <asm/unistd.h>
17 #include <linux/bpf.h>
23 #define __printf(a, b) __attribute__((format(printf, a, b)))
26 static int __base_pr(const char *format
, ...)
31 va_start(args
, format
);
32 err
= vfprintf(stderr
, format
, args
);
37 static __printf(1, 2) libbpf_print_fn_t __pr_warning
= __base_pr
;
38 static __printf(1, 2) libbpf_print_fn_t __pr_info
= __base_pr
;
39 static __printf(1, 2) libbpf_print_fn_t __pr_debug
;
41 #define __pr(func, fmt, ...) \
44 (func)("libbpf: " fmt, ##__VA_ARGS__); \
47 #define pr_warning(fmt, ...) __pr(__pr_warning, fmt, ##__VA_ARGS__)
48 #define pr_info(fmt, ...) __pr(__pr_info, fmt, ##__VA_ARGS__)
49 #define pr_debug(fmt, ...) __pr(__pr_debug, fmt, ##__VA_ARGS__)
51 void libbpf_set_print(libbpf_print_fn_t warn
,
52 libbpf_print_fn_t info
,
53 libbpf_print_fn_t debug
)
60 /* Copied from tools/perf/util/util.h */
62 # define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
66 # define zclose(fd) ({ \
69 ___err = close((fd)); \
74 #ifdef HAVE_LIBELF_MMAP_SUPPORT
75 # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ_MMAP
77 # define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
82 * Information when doing elf related work. Only valid if fd
92 #define obj_elf_valid(o) ((o)->efile.elf)
94 static struct bpf_object
*bpf_object__new(const char *path
)
96 struct bpf_object
*obj
;
98 obj
= calloc(1, sizeof(struct bpf_object
) + strlen(path
) + 1);
100 pr_warning("alloc memory failed for %s\n", path
);
104 strcpy(obj
->path
, path
);
109 static void bpf_object__elf_finish(struct bpf_object
*obj
)
111 if (!obj_elf_valid(obj
))
114 if (obj
->efile
.elf
) {
115 elf_end(obj
->efile
.elf
);
116 obj
->efile
.elf
= NULL
;
118 zclose(obj
->efile
.fd
);
121 static int bpf_object__elf_init(struct bpf_object
*obj
)
126 if (obj_elf_valid(obj
)) {
127 pr_warning("elf init: internal error\n");
131 obj
->efile
.fd
= open(obj
->path
, O_RDONLY
);
132 if (obj
->efile
.fd
< 0) {
133 pr_warning("failed to open %s: %s\n", obj
->path
,
138 obj
->efile
.elf
= elf_begin(obj
->efile
.fd
,
139 LIBBPF_ELF_C_READ_MMAP
,
141 if (!obj
->efile
.elf
) {
142 pr_warning("failed to open %s as ELF file\n",
148 if (!gelf_getehdr(obj
->efile
.elf
, &obj
->efile
.ehdr
)) {
149 pr_warning("failed to get EHDR from %s\n",
154 ep
= &obj
->efile
.ehdr
;
156 if ((ep
->e_type
!= ET_REL
) || (ep
->e_machine
!= 0)) {
157 pr_warning("%s is not an eBPF object file\n",
165 bpf_object__elf_finish(obj
);
169 static struct bpf_object
*
170 __bpf_object__open(const char *path
)
172 struct bpf_object
*obj
;
174 if (elf_version(EV_CURRENT
) == EV_NONE
) {
175 pr_warning("failed to init libelf for %s\n", path
);
179 obj
= bpf_object__new(path
);
183 if (bpf_object__elf_init(obj
))
186 bpf_object__elf_finish(obj
);
189 bpf_object__close(obj
);
193 struct bpf_object
*bpf_object__open(const char *path
)
195 /* param validation */
199 pr_debug("loading %s\n", path
);
201 return __bpf_object__open(path
);
204 void bpf_object__close(struct bpf_object
*obj
)
209 bpf_object__elf_finish(obj
);