xref: /openbmc/linux/tools/lib/bpf/btf.c (revision 77ab8d5d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /* Copyright (c) 2018 Facebook */
3 
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <unistd.h>
8 #include <errno.h>
9 #include <linux/err.h>
10 #include <linux/btf.h>
11 #include "btf.h"
12 #include "bpf.h"
13 
14 #define elog(fmt, ...) { if (err_log) err_log(fmt, ##__VA_ARGS__); }
15 #define max(a, b) ((a) > (b) ? (a) : (b))
16 #define min(a, b) ((a) < (b) ? (a) : (b))
17 
18 #define BTF_MAX_NR_TYPES 65535
19 
20 static struct btf_type btf_void;
21 
22 struct btf {
23 	union {
24 		struct btf_header *hdr;
25 		void *data;
26 	};
27 	struct btf_type **types;
28 	const char *strings;
29 	void *nohdr_data;
30 	uint32_t nr_types;
31 	uint32_t types_size;
32 	uint32_t data_size;
33 	int fd;
34 };
35 
36 static const char *btf_name_by_offset(const struct btf *btf, uint32_t offset)
37 {
38 	if (offset < btf->hdr->str_len)
39 		return &btf->strings[offset];
40 	else
41 		return NULL;
42 }
43 
44 static int btf_add_type(struct btf *btf, struct btf_type *t)
45 {
46 	if (btf->types_size - btf->nr_types < 2) {
47 		struct btf_type **new_types;
48 		u32 expand_by, new_size;
49 
50 		if (btf->types_size == BTF_MAX_NR_TYPES)
51 			return -E2BIG;
52 
53 		expand_by = max(btf->types_size >> 2, 16);
54 		new_size = min(BTF_MAX_NR_TYPES, btf->types_size + expand_by);
55 
56 		new_types = realloc(btf->types, sizeof(*new_types) * new_size);
57 		if (!new_types)
58 			return -ENOMEM;
59 
60 		if (btf->nr_types == 0)
61 			new_types[0] = &btf_void;
62 
63 		btf->types = new_types;
64 		btf->types_size = new_size;
65 	}
66 
67 	btf->types[++(btf->nr_types)] = t;
68 
69 	return 0;
70 }
71 
72 static int btf_parse_hdr(struct btf *btf, btf_print_fn_t err_log)
73 {
74 	const struct btf_header *hdr = btf->hdr;
75 	u32 meta_left;
76 
77 	if (btf->data_size < sizeof(struct btf_header)) {
78 		elog("BTF header not found\n");
79 		return -EINVAL;
80 	}
81 
82 	if (hdr->magic != BTF_MAGIC) {
83 		elog("Invalid BTF magic:%x\n", hdr->magic);
84 		return -EINVAL;
85 	}
86 
87 	if (hdr->version != BTF_VERSION) {
88 		elog("Unsupported BTF version:%u\n", hdr->version);
89 		return -ENOTSUP;
90 	}
91 
92 	if (hdr->flags) {
93 		elog("Unsupported BTF flags:%x\n", hdr->flags);
94 		return -ENOTSUP;
95 	}
96 
97 	meta_left = btf->data_size - sizeof(*hdr);
98 	if (!meta_left) {
99 		elog("BTF has no data\n");
100 		return -EINVAL;
101 	}
102 
103 	if (meta_left < hdr->type_off) {
104 		elog("Invalid BTF type section offset:%u\n", hdr->type_off);
105 		return -EINVAL;
106 	}
107 
108 	if (meta_left < hdr->str_off) {
109 		elog("Invalid BTF string section offset:%u\n", hdr->str_off);
110 		return -EINVAL;
111 	}
112 
113 	if (hdr->type_off >= hdr->str_off) {
114 		elog("BTF type section offset >= string section offset. No type?\n");
115 		return -EINVAL;
116 	}
117 
118 	if (hdr->type_off & 0x02) {
119 		elog("BTF type section is not aligned to 4 bytes\n");
120 		return -EINVAL;
121 	}
122 
123 	btf->nohdr_data = btf->hdr + 1;
124 
125 	return 0;
126 }
127 
128 static int btf_parse_str_sec(struct btf *btf, btf_print_fn_t err_log)
129 {
130 	const struct btf_header *hdr = btf->hdr;
131 	const char *start = btf->nohdr_data + hdr->str_off;
132 	const char *end = start + btf->hdr->str_len;
133 
134 	if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_NAME_OFFSET ||
135 	    start[0] || end[-1]) {
136 		elog("Invalid BTF string section\n");
137 		return -EINVAL;
138 	}
139 
140 	btf->strings = start;
141 
142 	return 0;
143 }
144 
145 static int btf_parse_type_sec(struct btf *btf, btf_print_fn_t err_log)
146 {
147 	struct btf_header *hdr = btf->hdr;
148 	void *nohdr_data = btf->nohdr_data;
149 	void *next_type = nohdr_data + hdr->type_off;
150 	void *end_type = nohdr_data + hdr->str_off;
151 
152 	while (next_type < end_type) {
153 		struct btf_type *t = next_type;
154 		uint16_t vlen = BTF_INFO_VLEN(t->info);
155 		int err;
156 
157 		next_type += sizeof(*t);
158 		switch (BTF_INFO_KIND(t->info)) {
159 		case BTF_KIND_INT:
160 			next_type += sizeof(int);
161 			break;
162 		case BTF_KIND_ARRAY:
163 			next_type += sizeof(struct btf_array);
164 			break;
165 		case BTF_KIND_STRUCT:
166 		case BTF_KIND_UNION:
167 			next_type += vlen * sizeof(struct btf_member);
168 			break;
169 		case BTF_KIND_ENUM:
170 			next_type += vlen * sizeof(struct btf_enum);
171 			break;
172 		case BTF_KIND_TYPEDEF:
173 		case BTF_KIND_PTR:
174 		case BTF_KIND_FWD:
175 		case BTF_KIND_VOLATILE:
176 		case BTF_KIND_CONST:
177 		case BTF_KIND_RESTRICT:
178 			break;
179 		default:
180 			elog("Unsupported BTF_KIND:%u\n",
181 			     BTF_INFO_KIND(t->info));
182 			return -EINVAL;
183 		}
184 
185 		err = btf_add_type(btf, t);
186 		if (err)
187 			return err;
188 	}
189 
190 	return 0;
191 }
192 
193 static const struct btf_type *btf_type_by_id(const struct btf *btf,
194 					     uint32_t type_id)
195 {
196 	if (type_id > btf->nr_types)
197 		return NULL;
198 
199 	return btf->types[type_id];
200 }
201 
202 static bool btf_type_is_void(const struct btf_type *t)
203 {
204 	return t == &btf_void || BTF_INFO_KIND(t->info) == BTF_KIND_FWD;
205 }
206 
207 static bool btf_type_is_void_or_null(const struct btf_type *t)
208 {
209 	return !t || btf_type_is_void(t);
210 }
211 
212 static int64_t btf_type_size(const struct btf_type *t)
213 {
214 	switch (BTF_INFO_KIND(t->info)) {
215 	case BTF_KIND_INT:
216 	case BTF_KIND_STRUCT:
217 	case BTF_KIND_UNION:
218 	case BTF_KIND_ENUM:
219 		return t->size;
220 	case BTF_KIND_PTR:
221 		return sizeof(void *);
222 	default:
223 		return -EINVAL;
224 	}
225 }
226 
227 #define MAX_RESOLVE_DEPTH 32
228 
229 int64_t btf__resolve_size(const struct btf *btf, uint32_t type_id)
230 {
231 	const struct btf_array *array;
232 	const struct btf_type *t;
233 	uint32_t nelems = 1;
234 	int64_t size = -1;
235 	int i;
236 
237 	t = btf_type_by_id(btf, type_id);
238 	for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
239 	     i++) {
240 		size = btf_type_size(t);
241 		if (size >= 0)
242 			break;
243 
244 		switch (BTF_INFO_KIND(t->info)) {
245 		case BTF_KIND_TYPEDEF:
246 		case BTF_KIND_VOLATILE:
247 		case BTF_KIND_CONST:
248 		case BTF_KIND_RESTRICT:
249 			type_id = t->type;
250 			break;
251 		case BTF_KIND_ARRAY:
252 			array = (const struct btf_array *)(t + 1);
253 			if (nelems && array->nelems > UINT32_MAX / nelems)
254 				return -E2BIG;
255 			nelems *= array->nelems;
256 			type_id = array->type;
257 			break;
258 		default:
259 			return -EINVAL;
260 		}
261 
262 		t = btf_type_by_id(btf, type_id);
263 	}
264 
265 	if (size < 0)
266 		return -EINVAL;
267 
268 	if (nelems && size > UINT32_MAX / nelems)
269 		return -E2BIG;
270 
271 	return nelems * size;
272 }
273 
274 int32_t btf__find_by_name(const struct btf *btf, const char *type_name)
275 {
276 	uint32_t i;
277 
278 	if (!strcmp(type_name, "void"))
279 		return 0;
280 
281 	for (i = 1; i <= btf->nr_types; i++) {
282 		const struct btf_type *t = btf->types[i];
283 		const char *name = btf_name_by_offset(btf, t->name_off);
284 
285 		if (name && !strcmp(type_name, name))
286 			return i;
287 	}
288 
289 	return -ENOENT;
290 }
291 
292 void btf__free(struct btf *btf)
293 {
294 	if (!btf)
295 		return;
296 
297 	if (btf->fd != -1)
298 		close(btf->fd);
299 
300 	free(btf->data);
301 	free(btf->types);
302 	free(btf);
303 }
304 
305 struct btf *btf__new(uint8_t *data, uint32_t size,
306 		     btf_print_fn_t err_log)
307 {
308 	uint32_t log_buf_size = 0;
309 	char *log_buf = NULL;
310 	struct btf *btf;
311 	int err;
312 
313 	btf = calloc(1, sizeof(struct btf));
314 	if (!btf)
315 		return ERR_PTR(-ENOMEM);
316 
317 	btf->fd = -1;
318 
319 	if (err_log) {
320 		log_buf = malloc(BPF_LOG_BUF_SIZE);
321 		if (!log_buf) {
322 			err = -ENOMEM;
323 			goto done;
324 		}
325 		*log_buf = 0;
326 		log_buf_size = BPF_LOG_BUF_SIZE;
327 	}
328 
329 	btf->data = malloc(size);
330 	if (!btf->data) {
331 		err = -ENOMEM;
332 		goto done;
333 	}
334 
335 	memcpy(btf->data, data, size);
336 	btf->data_size = size;
337 
338 	btf->fd = bpf_load_btf(btf->data, btf->data_size,
339 			       log_buf, log_buf_size, false);
340 
341 	if (btf->fd == -1) {
342 		err = -errno;
343 		elog("Error loading BTF: %s(%d)\n", strerror(errno), errno);
344 		if (log_buf && *log_buf)
345 			elog("%s\n", log_buf);
346 		goto done;
347 	}
348 
349 	err = btf_parse_hdr(btf, err_log);
350 	if (err)
351 		goto done;
352 
353 	err = btf_parse_str_sec(btf, err_log);
354 	if (err)
355 		goto done;
356 
357 	err = btf_parse_type_sec(btf, err_log);
358 
359 done:
360 	free(log_buf);
361 
362 	if (err) {
363 		btf__free(btf);
364 		return ERR_PTR(err);
365 	}
366 
367 	return btf;
368 }
369 
370 int btf__fd(const struct btf *btf)
371 {
372 	return btf->fd;
373 }
374