blob: 15b3e82b22f685a3b2124d0c02a401ff375924a2 [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.
7 */
8
9#include <stdlib.h>
Wang Nanb3f59d62015-07-01 02:13:52 +000010#include <stdio.h>
11#include <stdarg.h>
12#include <string.h>
Wang Nan1b76c132015-07-01 02:13:51 +000013#include <unistd.h>
Wang Nan1a5e3fb2015-07-01 02:13:53 +000014#include <fcntl.h>
15#include <errno.h>
Wang Nan1b76c132015-07-01 02:13:51 +000016#include <asm/unistd.h>
17#include <linux/bpf.h>
Wang Nan1a5e3fb2015-07-01 02:13:53 +000018#include <libelf.h>
19#include <gelf.h>
Wang Nan1b76c132015-07-01 02:13:51 +000020
21#include "libbpf.h"
Wang Nanb3f59d62015-07-01 02:13:52 +000022
23#define __printf(a, b) __attribute__((format(printf, a, b)))
24
25__printf(1, 2)
26static int __base_pr(const char *format, ...)
27{
28 va_list args;
29 int err;
30
31 va_start(args, format);
32 err = vfprintf(stderr, format, args);
33 va_end(args);
34 return err;
35}
36
37static __printf(1, 2) libbpf_print_fn_t __pr_warning = __base_pr;
38static __printf(1, 2) libbpf_print_fn_t __pr_info = __base_pr;
39static __printf(1, 2) libbpf_print_fn_t __pr_debug;
40
41#define __pr(func, fmt, ...) \
42do { \
43 if ((func)) \
44 (func)("libbpf: " fmt, ##__VA_ARGS__); \
45} while (0)
46
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__)
50
51void libbpf_set_print(libbpf_print_fn_t warn,
52 libbpf_print_fn_t info,
53 libbpf_print_fn_t debug)
54{
55 __pr_warning = warn;
56 __pr_info = info;
57 __pr_debug = debug;
58}
Wang Nan1a5e3fb2015-07-01 02:13:53 +000059
60/* Copied from tools/perf/util/util.h */
61#ifndef zfree
62# define zfree(ptr) ({ free(*ptr); *ptr = NULL; })
63#endif
64
65#ifndef zclose
66# define zclose(fd) ({ \
67 int ___err = 0; \
68 if ((fd) >= 0) \
69 ___err = close((fd)); \
70 fd = -1; \
71 ___err; })
72#endif
73
74#ifdef HAVE_LIBELF_MMAP_SUPPORT
75# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ_MMAP
76#else
77# define LIBBPF_ELF_C_READ_MMAP ELF_C_READ
78#endif
79
80struct bpf_object {
81 /*
82 * Information when doing elf related work. Only valid if fd
83 * is valid.
84 */
85 struct {
86 int fd;
Wang Nan6c956392015-07-01 02:13:54 +000087 void *obj_buf;
88 size_t obj_buf_sz;
Wang Nan1a5e3fb2015-07-01 02:13:53 +000089 Elf *elf;
90 GElf_Ehdr ehdr;
91 } efile;
92 char path[];
93};
94#define obj_elf_valid(o) ((o)->efile.elf)
95
Wang Nan6c956392015-07-01 02:13:54 +000096static struct bpf_object *bpf_object__new(const char *path,
97 void *obj_buf,
98 size_t obj_buf_sz)
Wang Nan1a5e3fb2015-07-01 02:13:53 +000099{
100 struct bpf_object *obj;
101
102 obj = calloc(1, sizeof(struct bpf_object) + strlen(path) + 1);
103 if (!obj) {
104 pr_warning("alloc memory failed for %s\n", path);
105 return NULL;
106 }
107
108 strcpy(obj->path, path);
109 obj->efile.fd = -1;
Wang Nan6c956392015-07-01 02:13:54 +0000110
111 /*
112 * Caller of this function should also calls
113 * bpf_object__elf_finish() after data collection to return
114 * obj_buf to user. If not, we should duplicate the buffer to
115 * avoid user freeing them before elf finish.
116 */
117 obj->efile.obj_buf = obj_buf;
118 obj->efile.obj_buf_sz = obj_buf_sz;
119
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000120 return obj;
121}
122
123static void bpf_object__elf_finish(struct bpf_object *obj)
124{
125 if (!obj_elf_valid(obj))
126 return;
127
128 if (obj->efile.elf) {
129 elf_end(obj->efile.elf);
130 obj->efile.elf = NULL;
131 }
132 zclose(obj->efile.fd);
Wang Nan6c956392015-07-01 02:13:54 +0000133 obj->efile.obj_buf = NULL;
134 obj->efile.obj_buf_sz = 0;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000135}
136
137static int bpf_object__elf_init(struct bpf_object *obj)
138{
139 int err = 0;
140 GElf_Ehdr *ep;
141
142 if (obj_elf_valid(obj)) {
143 pr_warning("elf init: internal error\n");
144 return -EEXIST;
145 }
146
Wang Nan6c956392015-07-01 02:13:54 +0000147 if (obj->efile.obj_buf_sz > 0) {
148 /*
149 * obj_buf should have been validated by
150 * bpf_object__open_buffer().
151 */
152 obj->efile.elf = elf_memory(obj->efile.obj_buf,
153 obj->efile.obj_buf_sz);
154 } else {
155 obj->efile.fd = open(obj->path, O_RDONLY);
156 if (obj->efile.fd < 0) {
157 pr_warning("failed to open %s: %s\n", obj->path,
158 strerror(errno));
159 return -errno;
160 }
161
162 obj->efile.elf = elf_begin(obj->efile.fd,
163 LIBBPF_ELF_C_READ_MMAP,
164 NULL);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000165 }
166
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000167 if (!obj->efile.elf) {
168 pr_warning("failed to open %s as ELF file\n",
169 obj->path);
170 err = -EINVAL;
171 goto errout;
172 }
173
174 if (!gelf_getehdr(obj->efile.elf, &obj->efile.ehdr)) {
175 pr_warning("failed to get EHDR from %s\n",
176 obj->path);
177 err = -EINVAL;
178 goto errout;
179 }
180 ep = &obj->efile.ehdr;
181
182 if ((ep->e_type != ET_REL) || (ep->e_machine != 0)) {
183 pr_warning("%s is not an eBPF object file\n",
184 obj->path);
185 err = -EINVAL;
186 goto errout;
187 }
188
189 return 0;
190errout:
191 bpf_object__elf_finish(obj);
192 return err;
193}
194
Wang Nancc4228d2015-07-01 02:13:55 +0000195static int
196bpf_object__check_endianness(struct bpf_object *obj)
197{
198 static unsigned int const endian = 1;
199
200 switch (obj->efile.ehdr.e_ident[EI_DATA]) {
201 case ELFDATA2LSB:
202 /* We are big endian, BPF obj is little endian. */
203 if (*(unsigned char const *)&endian != 1)
204 goto mismatch;
205 break;
206
207 case ELFDATA2MSB:
208 /* We are little endian, BPF obj is big endian. */
209 if (*(unsigned char const *)&endian != 0)
210 goto mismatch;
211 break;
212 default:
213 return -EINVAL;
214 }
215
216 return 0;
217
218mismatch:
219 pr_warning("Error: endianness mismatch.\n");
220 return -EINVAL;
221}
222
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000223static struct bpf_object *
Wang Nan6c956392015-07-01 02:13:54 +0000224__bpf_object__open(const char *path, void *obj_buf, size_t obj_buf_sz)
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000225{
226 struct bpf_object *obj;
227
228 if (elf_version(EV_CURRENT) == EV_NONE) {
229 pr_warning("failed to init libelf for %s\n", path);
230 return NULL;
231 }
232
Wang Nan6c956392015-07-01 02:13:54 +0000233 obj = bpf_object__new(path, obj_buf, obj_buf_sz);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000234 if (!obj)
235 return NULL;
236
237 if (bpf_object__elf_init(obj))
238 goto out;
Wang Nancc4228d2015-07-01 02:13:55 +0000239 if (bpf_object__check_endianness(obj))
240 goto out;
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000241
242 bpf_object__elf_finish(obj);
243 return obj;
244out:
245 bpf_object__close(obj);
246 return NULL;
247}
248
249struct bpf_object *bpf_object__open(const char *path)
250{
251 /* param validation */
252 if (!path)
253 return NULL;
254
255 pr_debug("loading %s\n", path);
256
Wang Nan6c956392015-07-01 02:13:54 +0000257 return __bpf_object__open(path, NULL, 0);
258}
259
260struct bpf_object *bpf_object__open_buffer(void *obj_buf,
261 size_t obj_buf_sz)
262{
263 /* param validation */
264 if (!obj_buf || obj_buf_sz <= 0)
265 return NULL;
266
267 pr_debug("loading object from buffer\n");
268
269 return __bpf_object__open("[buffer]", obj_buf, obj_buf_sz);
Wang Nan1a5e3fb2015-07-01 02:13:53 +0000270}
271
272void bpf_object__close(struct bpf_object *obj)
273{
274 if (!obj)
275 return;
276
277 bpf_object__elf_finish(obj);
278
279 free(obj);
280}