blob: 1cd4e5d67158d30cb5abbbe9a0c701eba2d6d613 [file] [log] [blame]
Alexei Starovoitov1bc38b82018-10-05 16:40:00 -07001// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -07002/* Copyright (c) 2018 Facebook */
3
Yonghong Song96408c42019-02-04 11:00:58 -08004#include <stdio.h>
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -07005#include <stdlib.h>
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -07006#include <string.h>
Andrii Nakryikoe6c64852019-05-24 11:58:57 -07007#include <fcntl.h>
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -07008#include <unistd.h>
9#include <errno.h>
10#include <linux/err.h>
11#include <linux/btf.h>
Andrii Nakryikoe6c64852019-05-24 11:58:57 -070012#include <gelf.h>
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070013#include "btf.h"
14#include "bpf.h"
Yonghong Song8461ef82019-02-01 16:14:14 -080015#include "libbpf.h"
Andrii Nakryikod72386f2019-05-15 20:39:27 -070016#include "libbpf_internal.h"
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -070017#include "hashmap.h"
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070018
Andrii Nakryiko5aab3922019-02-15 19:52:18 -080019#define BTF_MAX_NR_TYPES 0x7fffffff
20#define BTF_MAX_STR_OFFSET 0x7fffffff
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070021
22static struct btf_type btf_void;
23
24struct btf {
25 union {
26 struct btf_header *hdr;
27 void *data;
28 };
29 struct btf_type **types;
30 const char *strings;
31 void *nohdr_data;
Martin KaFai Lau5b891af2018-07-24 08:40:21 -070032 __u32 nr_types;
33 __u32 types_size;
34 __u32 data_size;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070035 int fd;
36};
37
Martin KaFai Lau3d650142018-12-07 16:42:31 -080038struct btf_ext_info {
39 /*
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -080040 * info points to the individual info section (e.g. func_info and
41 * line_info) from the .BTF.ext. It does not include the __u32 rec_size.
Martin KaFai Lau3d650142018-12-07 16:42:31 -080042 */
43 void *info;
44 __u32 rec_size;
45 __u32 len;
Yonghong Song2993e052018-11-19 15:29:16 -080046};
47
Martin KaFai Lau3d650142018-12-07 16:42:31 -080048struct btf_ext {
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -080049 union {
50 struct btf_ext_header *hdr;
51 void *data;
52 };
Martin KaFai Lau3d650142018-12-07 16:42:31 -080053 struct btf_ext_info func_info;
54 struct btf_ext_info line_info;
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -080055 __u32 data_size;
Martin KaFai Lau3d650142018-12-07 16:42:31 -080056};
57
58struct btf_ext_info_sec {
Martin KaFai Lauf0187f02018-12-07 16:42:29 -080059 __u32 sec_name_off;
Martin KaFai Lau3d650142018-12-07 16:42:31 -080060 __u32 num_info;
61 /* Followed by num_info * record_size number of bytes */
Martin KaFai Lauf0187f02018-12-07 16:42:29 -080062 __u8 data[0];
63};
64
Yonghong Song2993e052018-11-19 15:29:16 -080065/* The minimum bpf_func_info checked by the loader */
66struct bpf_func_info_min {
Martin KaFai Lau84ecc1f2018-12-05 17:35:47 -080067 __u32 insn_off;
Yonghong Song2993e052018-11-19 15:29:16 -080068 __u32 type_id;
69};
70
Martin KaFai Lau3d650142018-12-07 16:42:31 -080071/* The minimum bpf_line_info checked by the loader */
72struct bpf_line_info_min {
73 __u32 insn_off;
74 __u32 file_name_off;
75 __u32 line_off;
76 __u32 line_col;
77};
78
Yonghong Songd7f5b5e2018-11-19 15:29:18 -080079static inline __u64 ptr_to_u64(const void *ptr)
80{
81 return (__u64) (unsigned long) ptr;
82}
83
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070084static int btf_add_type(struct btf *btf, struct btf_type *t)
85{
86 if (btf->types_size - btf->nr_types < 2) {
87 struct btf_type **new_types;
Martin KaFai Lau5b891af2018-07-24 08:40:21 -070088 __u32 expand_by, new_size;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -070089
90 if (btf->types_size == BTF_MAX_NR_TYPES)
91 return -E2BIG;
92
93 expand_by = max(btf->types_size >> 2, 16);
94 new_size = min(BTF_MAX_NR_TYPES, btf->types_size + expand_by);
95
96 new_types = realloc(btf->types, sizeof(*new_types) * new_size);
97 if (!new_types)
98 return -ENOMEM;
99
100 if (btf->nr_types == 0)
101 new_types[0] = &btf_void;
102
103 btf->types = new_types;
104 btf->types_size = new_size;
105 }
106
107 btf->types[++(btf->nr_types)] = t;
108
109 return 0;
110}
111
Yonghong Song8461ef82019-02-01 16:14:14 -0800112static int btf_parse_hdr(struct btf *btf)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700113{
114 const struct btf_header *hdr = btf->hdr;
Martin KaFai Lau5b891af2018-07-24 08:40:21 -0700115 __u32 meta_left;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700116
117 if (btf->data_size < sizeof(struct btf_header)) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800118 pr_debug("BTF header not found\n");
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700119 return -EINVAL;
120 }
121
122 if (hdr->magic != BTF_MAGIC) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800123 pr_debug("Invalid BTF magic:%x\n", hdr->magic);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700124 return -EINVAL;
125 }
126
127 if (hdr->version != BTF_VERSION) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800128 pr_debug("Unsupported BTF version:%u\n", hdr->version);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700129 return -ENOTSUP;
130 }
131
132 if (hdr->flags) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800133 pr_debug("Unsupported BTF flags:%x\n", hdr->flags);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700134 return -ENOTSUP;
135 }
136
137 meta_left = btf->data_size - sizeof(*hdr);
138 if (!meta_left) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800139 pr_debug("BTF has no data\n");
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700140 return -EINVAL;
141 }
142
143 if (meta_left < hdr->type_off) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800144 pr_debug("Invalid BTF type section offset:%u\n", hdr->type_off);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700145 return -EINVAL;
146 }
147
148 if (meta_left < hdr->str_off) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800149 pr_debug("Invalid BTF string section offset:%u\n", hdr->str_off);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700150 return -EINVAL;
151 }
152
153 if (hdr->type_off >= hdr->str_off) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800154 pr_debug("BTF type section offset >= string section offset. No type?\n");
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700155 return -EINVAL;
156 }
157
158 if (hdr->type_off & 0x02) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800159 pr_debug("BTF type section is not aligned to 4 bytes\n");
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700160 return -EINVAL;
161 }
162
163 btf->nohdr_data = btf->hdr + 1;
164
165 return 0;
166}
167
Yonghong Song8461ef82019-02-01 16:14:14 -0800168static int btf_parse_str_sec(struct btf *btf)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700169{
170 const struct btf_header *hdr = btf->hdr;
171 const char *start = btf->nohdr_data + hdr->str_off;
172 const char *end = start + btf->hdr->str_len;
173
Andrii Nakryiko5aab3922019-02-15 19:52:18 -0800174 if (!hdr->str_len || hdr->str_len - 1 > BTF_MAX_STR_OFFSET ||
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700175 start[0] || end[-1]) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800176 pr_debug("Invalid BTF string section\n");
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700177 return -EINVAL;
178 }
179
180 btf->strings = start;
181
182 return 0;
183}
184
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800185static int btf_type_size(struct btf_type *t)
186{
187 int base_size = sizeof(struct btf_type);
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700188 __u16 vlen = btf_vlen(t);
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800189
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700190 switch (btf_kind(t)) {
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800191 case BTF_KIND_FWD:
192 case BTF_KIND_CONST:
193 case BTF_KIND_VOLATILE:
194 case BTF_KIND_RESTRICT:
195 case BTF_KIND_PTR:
196 case BTF_KIND_TYPEDEF:
197 case BTF_KIND_FUNC:
198 return base_size;
199 case BTF_KIND_INT:
200 return base_size + sizeof(__u32);
201 case BTF_KIND_ENUM:
202 return base_size + vlen * sizeof(struct btf_enum);
203 case BTF_KIND_ARRAY:
204 return base_size + sizeof(struct btf_array);
205 case BTF_KIND_STRUCT:
206 case BTF_KIND_UNION:
207 return base_size + vlen * sizeof(struct btf_member);
208 case BTF_KIND_FUNC_PROTO:
209 return base_size + vlen * sizeof(struct btf_param);
Daniel Borkmann1713d682019-04-09 23:20:14 +0200210 case BTF_KIND_VAR:
211 return base_size + sizeof(struct btf_var);
212 case BTF_KIND_DATASEC:
213 return base_size + vlen * sizeof(struct btf_var_secinfo);
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800214 default:
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700215 pr_debug("Unsupported BTF_KIND:%u\n", btf_kind(t));
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800216 return -EINVAL;
217 }
218}
219
Yonghong Song8461ef82019-02-01 16:14:14 -0800220static int btf_parse_type_sec(struct btf *btf)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700221{
222 struct btf_header *hdr = btf->hdr;
223 void *nohdr_data = btf->nohdr_data;
224 void *next_type = nohdr_data + hdr->type_off;
225 void *end_type = nohdr_data + hdr->str_off;
226
227 while (next_type < end_type) {
228 struct btf_type *t = next_type;
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800229 int type_size;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700230 int err;
231
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800232 type_size = btf_type_size(t);
233 if (type_size < 0)
234 return type_size;
235 next_type += type_size;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700236 err = btf_add_type(btf, t);
237 if (err)
238 return err;
239 }
240
241 return 0;
242}
243
Andrii Nakryiko9c651122019-02-04 17:29:46 -0800244__u32 btf__get_nr_types(const struct btf *btf)
245{
246 return btf->nr_types;
247}
248
Martin KaFai Lau38d5d3b2018-07-24 08:40:22 -0700249const struct btf_type *btf__type_by_id(const struct btf *btf, __u32 type_id)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700250{
251 if (type_id > btf->nr_types)
252 return NULL;
253
254 return btf->types[type_id];
255}
256
257static bool btf_type_is_void(const struct btf_type *t)
258{
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700259 return t == &btf_void || btf_is_fwd(t);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700260}
261
262static bool btf_type_is_void_or_null(const struct btf_type *t)
263{
264 return !t || btf_type_is_void(t);
265}
266
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700267#define MAX_RESOLVE_DEPTH 32
268
Martin KaFai Lau5b891af2018-07-24 08:40:21 -0700269__s64 btf__resolve_size(const struct btf *btf, __u32 type_id)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700270{
271 const struct btf_array *array;
272 const struct btf_type *t;
Martin KaFai Lau5b891af2018-07-24 08:40:21 -0700273 __u32 nelems = 1;
274 __s64 size = -1;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700275 int i;
276
Okash Khawaja92b57122018-07-13 21:57:02 -0700277 t = btf__type_by_id(btf, type_id);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700278 for (i = 0; i < MAX_RESOLVE_DEPTH && !btf_type_is_void_or_null(t);
279 i++) {
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700280 switch (btf_kind(t)) {
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800281 case BTF_KIND_INT:
282 case BTF_KIND_STRUCT:
283 case BTF_KIND_UNION:
284 case BTF_KIND_ENUM:
Daniel Borkmann1713d682019-04-09 23:20:14 +0200285 case BTF_KIND_DATASEC:
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800286 size = t->size;
287 goto done;
288 case BTF_KIND_PTR:
289 size = sizeof(void *);
290 goto done;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700291 case BTF_KIND_TYPEDEF:
292 case BTF_KIND_VOLATILE:
293 case BTF_KIND_CONST:
294 case BTF_KIND_RESTRICT:
Daniel Borkmann1713d682019-04-09 23:20:14 +0200295 case BTF_KIND_VAR:
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700296 type_id = t->type;
297 break;
298 case BTF_KIND_ARRAY:
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700299 array = btf_array(t);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700300 if (nelems && array->nelems > UINT32_MAX / nelems)
301 return -E2BIG;
302 nelems *= array->nelems;
303 type_id = array->type;
304 break;
305 default:
306 return -EINVAL;
307 }
308
Okash Khawaja92b57122018-07-13 21:57:02 -0700309 t = btf__type_by_id(btf, type_id);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700310 }
311
312 if (size < 0)
313 return -EINVAL;
314
Andrii Nakryiko69eaab042019-02-04 17:29:44 -0800315done:
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700316 if (nelems && size > UINT32_MAX / nelems)
317 return -E2BIG;
318
319 return nelems * size;
320}
321
Okash Khawaja92b57122018-07-13 21:57:02 -0700322int btf__resolve_type(const struct btf *btf, __u32 type_id)
323{
324 const struct btf_type *t;
325 int depth = 0;
326
327 t = btf__type_by_id(btf, type_id);
328 while (depth < MAX_RESOLVE_DEPTH &&
329 !btf_type_is_void_or_null(t) &&
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700330 (btf_is_mod(t) || btf_is_typedef(t) || btf_is_var(t))) {
Okash Khawaja92b57122018-07-13 21:57:02 -0700331 type_id = t->type;
332 t = btf__type_by_id(btf, type_id);
333 depth++;
334 }
335
336 if (depth == MAX_RESOLVE_DEPTH || btf_type_is_void_or_null(t))
337 return -EINVAL;
338
339 return type_id;
340}
341
Martin KaFai Lau5b891af2018-07-24 08:40:21 -0700342__s32 btf__find_by_name(const struct btf *btf, const char *type_name)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700343{
Martin KaFai Lau5b891af2018-07-24 08:40:21 -0700344 __u32 i;
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700345
346 if (!strcmp(type_name, "void"))
347 return 0;
348
349 for (i = 1; i <= btf->nr_types; i++) {
350 const struct btf_type *t = btf->types[i];
Okash Khawaja92b57122018-07-13 21:57:02 -0700351 const char *name = btf__name_by_offset(btf, t->name_off);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700352
353 if (name && !strcmp(type_name, name))
354 return i;
355 }
356
357 return -ENOENT;
358}
359
360void btf__free(struct btf *btf)
361{
362 if (!btf)
363 return;
364
365 if (btf->fd != -1)
366 close(btf->fd);
367
368 free(btf->data);
369 free(btf->types);
370 free(btf);
371}
372
Yonghong Song8461ef82019-02-01 16:14:14 -0800373struct btf *btf__new(__u8 *data, __u32 size)
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700374{
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700375 struct btf *btf;
376 int err;
377
378 btf = calloc(1, sizeof(struct btf));
379 if (!btf)
380 return ERR_PTR(-ENOMEM);
381
382 btf->fd = -1;
383
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700384 btf->data = malloc(size);
385 if (!btf->data) {
386 err = -ENOMEM;
387 goto done;
388 }
389
390 memcpy(btf->data, data, size);
391 btf->data_size = size;
392
Yonghong Song8461ef82019-02-01 16:14:14 -0800393 err = btf_parse_hdr(btf);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700394 if (err)
395 goto done;
396
Yonghong Song8461ef82019-02-01 16:14:14 -0800397 err = btf_parse_str_sec(btf);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700398 if (err)
399 goto done;
400
Yonghong Song8461ef82019-02-01 16:14:14 -0800401 err = btf_parse_type_sec(btf);
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700402
403done:
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700404 if (err) {
405 btf__free(btf);
406 return ERR_PTR(err);
407 }
408
409 return btf;
410}
411
Andrii Nakryikoe6c64852019-05-24 11:58:57 -0700412static bool btf_check_endianness(const GElf_Ehdr *ehdr)
413{
414#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
415 return ehdr->e_ident[EI_DATA] == ELFDATA2LSB;
416#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
417 return ehdr->e_ident[EI_DATA] == ELFDATA2MSB;
418#else
419# error "Unrecognized __BYTE_ORDER__"
420#endif
421}
422
423struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext)
424{
425 Elf_Data *btf_data = NULL, *btf_ext_data = NULL;
426 int err = 0, fd = -1, idx = 0;
427 struct btf *btf = NULL;
428 Elf_Scn *scn = NULL;
429 Elf *elf = NULL;
430 GElf_Ehdr ehdr;
431
432 if (elf_version(EV_CURRENT) == EV_NONE) {
433 pr_warning("failed to init libelf for %s\n", path);
434 return ERR_PTR(-LIBBPF_ERRNO__LIBELF);
435 }
436
437 fd = open(path, O_RDONLY);
438 if (fd < 0) {
439 err = -errno;
440 pr_warning("failed to open %s: %s\n", path, strerror(errno));
441 return ERR_PTR(err);
442 }
443
444 err = -LIBBPF_ERRNO__FORMAT;
445
446 elf = elf_begin(fd, ELF_C_READ, NULL);
447 if (!elf) {
448 pr_warning("failed to open %s as ELF file\n", path);
449 goto done;
450 }
451 if (!gelf_getehdr(elf, &ehdr)) {
452 pr_warning("failed to get EHDR from %s\n", path);
453 goto done;
454 }
455 if (!btf_check_endianness(&ehdr)) {
456 pr_warning("non-native ELF endianness is not supported\n");
457 goto done;
458 }
459 if (!elf_rawdata(elf_getscn(elf, ehdr.e_shstrndx), NULL)) {
460 pr_warning("failed to get e_shstrndx from %s\n", path);
461 goto done;
462 }
463
464 while ((scn = elf_nextscn(elf, scn)) != NULL) {
465 GElf_Shdr sh;
466 char *name;
467
468 idx++;
469 if (gelf_getshdr(scn, &sh) != &sh) {
470 pr_warning("failed to get section(%d) header from %s\n",
471 idx, path);
472 goto done;
473 }
474 name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name);
475 if (!name) {
476 pr_warning("failed to get section(%d) name from %s\n",
477 idx, path);
478 goto done;
479 }
480 if (strcmp(name, BTF_ELF_SEC) == 0) {
481 btf_data = elf_getdata(scn, 0);
482 if (!btf_data) {
483 pr_warning("failed to get section(%d, %s) data from %s\n",
484 idx, name, path);
485 goto done;
486 }
487 continue;
488 } else if (btf_ext && strcmp(name, BTF_EXT_ELF_SEC) == 0) {
489 btf_ext_data = elf_getdata(scn, 0);
490 if (!btf_ext_data) {
491 pr_warning("failed to get section(%d, %s) data from %s\n",
492 idx, name, path);
493 goto done;
494 }
495 continue;
496 }
497 }
498
499 err = 0;
500
501 if (!btf_data) {
502 err = -ENOENT;
503 goto done;
504 }
505 btf = btf__new(btf_data->d_buf, btf_data->d_size);
506 if (IS_ERR(btf))
507 goto done;
508
509 if (btf_ext && btf_ext_data) {
510 *btf_ext = btf_ext__new(btf_ext_data->d_buf,
511 btf_ext_data->d_size);
512 if (IS_ERR(*btf_ext))
513 goto done;
514 } else if (btf_ext) {
515 *btf_ext = NULL;
516 }
517done:
518 if (elf)
519 elf_end(elf);
520 close(fd);
521
522 if (err)
523 return ERR_PTR(err);
524 /*
525 * btf is always parsed before btf_ext, so no need to clean up
526 * btf_ext, if btf loading failed
527 */
528 if (IS_ERR(btf))
529 return btf;
530 if (btf_ext && IS_ERR(*btf_ext)) {
531 btf__free(btf);
532 err = PTR_ERR(*btf_ext);
533 return ERR_PTR(err);
534 }
535 return btf;
536}
537
Daniel Borkmann1713d682019-04-09 23:20:14 +0200538static int compare_vsi_off(const void *_a, const void *_b)
539{
540 const struct btf_var_secinfo *a = _a;
541 const struct btf_var_secinfo *b = _b;
542
543 return a->offset - b->offset;
544}
545
546static int btf_fixup_datasec(struct bpf_object *obj, struct btf *btf,
547 struct btf_type *t)
548{
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700549 __u32 size = 0, off = 0, i, vars = btf_vlen(t);
Daniel Borkmann1713d682019-04-09 23:20:14 +0200550 const char *name = btf__name_by_offset(btf, t->name_off);
551 const struct btf_type *t_var;
552 struct btf_var_secinfo *vsi;
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700553 const struct btf_var *var;
Daniel Borkmann1713d682019-04-09 23:20:14 +0200554 int ret;
555
556 if (!name) {
557 pr_debug("No name found in string section for DATASEC kind.\n");
558 return -ENOENT;
559 }
560
561 ret = bpf_object__section_size(obj, name, &size);
562 if (ret || !size || (t->size && t->size != size)) {
563 pr_debug("Invalid size for section %s: %u bytes\n", name, size);
564 return -ENOENT;
565 }
566
567 t->size = size;
568
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700569 for (i = 0, vsi = btf_var_secinfos(t); i < vars; i++, vsi++) {
Daniel Borkmann1713d682019-04-09 23:20:14 +0200570 t_var = btf__type_by_id(btf, vsi->type);
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700571 var = btf_var(t_var);
Daniel Borkmann1713d682019-04-09 23:20:14 +0200572
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700573 if (!btf_is_var(t_var)) {
Daniel Borkmann1713d682019-04-09 23:20:14 +0200574 pr_debug("Non-VAR type seen in section %s\n", name);
575 return -EINVAL;
576 }
577
578 if (var->linkage == BTF_VAR_STATIC)
579 continue;
580
581 name = btf__name_by_offset(btf, t_var->name_off);
582 if (!name) {
583 pr_debug("No name found in string section for VAR kind\n");
584 return -ENOENT;
585 }
586
587 ret = bpf_object__variable_offset(obj, name, &off);
588 if (ret) {
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700589 pr_debug("No offset found in symbol table for VAR %s\n",
590 name);
Daniel Borkmann1713d682019-04-09 23:20:14 +0200591 return -ENOENT;
592 }
593
594 vsi->offset = off;
595 }
596
597 qsort(t + 1, vars, sizeof(*vsi), compare_vsi_off);
598 return 0;
599}
600
601int btf__finalize_data(struct bpf_object *obj, struct btf *btf)
602{
603 int err = 0;
604 __u32 i;
605
606 for (i = 1; i <= btf->nr_types; i++) {
607 struct btf_type *t = btf->types[i];
608
609 /* Loader needs to fix up some of the things compiler
610 * couldn't get its hands on while emitting BTF. This
611 * is section size and global variable offset. We use
612 * the info from the ELF itself for this purpose.
613 */
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700614 if (btf_is_datasec(t)) {
Daniel Borkmann1713d682019-04-09 23:20:14 +0200615 err = btf_fixup_datasec(obj, btf, t);
616 if (err)
617 break;
618 }
619 }
620
621 return err;
622}
623
Andrii Nakryikod29d87f2019-02-08 11:19:36 -0800624int btf__load(struct btf *btf)
625{
626 __u32 log_buf_size = BPF_LOG_BUF_SIZE;
627 char *log_buf = NULL;
628 int err = 0;
629
630 if (btf->fd >= 0)
631 return -EEXIST;
632
633 log_buf = malloc(log_buf_size);
634 if (!log_buf)
635 return -ENOMEM;
636
637 *log_buf = 0;
638
639 btf->fd = bpf_load_btf(btf->data, btf->data_size,
640 log_buf, log_buf_size, false);
641 if (btf->fd < 0) {
642 err = -errno;
643 pr_warning("Error loading BTF: %s(%d)\n", strerror(errno), errno);
644 if (*log_buf)
645 pr_warning("%s\n", log_buf);
646 goto done;
647 }
648
649done:
650 free(log_buf);
651 return err;
652}
653
Martin KaFai Lau8a138ae2018-04-18 15:56:05 -0700654int btf__fd(const struct btf *btf)
655{
656 return btf->fd;
657}
Okash Khawaja92b57122018-07-13 21:57:02 -0700658
Andrii Nakryiko02c87442019-02-08 11:19:37 -0800659const void *btf__get_raw_data(const struct btf *btf, __u32 *size)
660{
661 *size = btf->data_size;
662 return btf->data;
663}
664
Okash Khawaja92b57122018-07-13 21:57:02 -0700665const char *btf__name_by_offset(const struct btf *btf, __u32 offset)
666{
667 if (offset < btf->hdr->str_len)
668 return &btf->strings[offset];
669 else
670 return NULL;
671}
Yonghong Song2993e052018-11-19 15:29:16 -0800672
Martin KaFai Lau1d2f44c2018-11-23 16:44:32 -0800673int btf__get_from_id(__u32 id, struct btf **btf)
Yonghong Songd7f5b5e2018-11-19 15:29:18 -0800674{
675 struct bpf_btf_info btf_info = { 0 };
676 __u32 len = sizeof(btf_info);
677 __u32 last_size;
678 int btf_fd;
679 void *ptr;
680 int err;
681
682 err = 0;
683 *btf = NULL;
684 btf_fd = bpf_btf_get_fd_by_id(id);
685 if (btf_fd < 0)
686 return 0;
687
688 /* we won't know btf_size until we call bpf_obj_get_info_by_fd(). so
689 * let's start with a sane default - 4KiB here - and resize it only if
690 * bpf_obj_get_info_by_fd() needs a bigger buffer.
691 */
692 btf_info.btf_size = 4096;
693 last_size = btf_info.btf_size;
694 ptr = malloc(last_size);
695 if (!ptr) {
696 err = -ENOMEM;
697 goto exit_free;
698 }
699
Andrii Nakryiko1ad9cbb2019-02-13 10:25:53 -0800700 memset(ptr, 0, last_size);
Yonghong Songd7f5b5e2018-11-19 15:29:18 -0800701 btf_info.btf = ptr_to_u64(ptr);
702 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
703
704 if (!err && btf_info.btf_size > last_size) {
705 void *temp_ptr;
706
707 last_size = btf_info.btf_size;
708 temp_ptr = realloc(ptr, last_size);
709 if (!temp_ptr) {
710 err = -ENOMEM;
711 goto exit_free;
712 }
713 ptr = temp_ptr;
Andrii Nakryiko1ad9cbb2019-02-13 10:25:53 -0800714 memset(ptr, 0, last_size);
Yonghong Songd7f5b5e2018-11-19 15:29:18 -0800715 btf_info.btf = ptr_to_u64(ptr);
716 err = bpf_obj_get_info_by_fd(btf_fd, &btf_info, &len);
717 }
718
719 if (err || btf_info.btf_size > last_size) {
720 err = errno;
721 goto exit_free;
722 }
723
Yonghong Song8461ef82019-02-01 16:14:14 -0800724 *btf = btf__new((__u8 *)(long)btf_info.btf, btf_info.btf_size);
Yonghong Songd7f5b5e2018-11-19 15:29:18 -0800725 if (IS_ERR(*btf)) {
726 err = PTR_ERR(*btf);
727 *btf = NULL;
728 }
729
730exit_free:
731 close(btf_fd);
732 free(ptr);
733
734 return err;
735}
736
Yonghong Songa6c109a2019-02-05 11:48:22 -0800737int btf__get_map_kv_tids(const struct btf *btf, const char *map_name,
Yonghong Song96408c42019-02-04 11:00:58 -0800738 __u32 expected_key_size, __u32 expected_value_size,
739 __u32 *key_type_id, __u32 *value_type_id)
740{
741 const struct btf_type *container_type;
742 const struct btf_member *key, *value;
743 const size_t max_name = 256;
744 char container_name[max_name];
745 __s64 key_size, value_size;
746 __s32 container_id;
747
748 if (snprintf(container_name, max_name, "____btf_map_%s", map_name) ==
749 max_name) {
750 pr_warning("map:%s length of '____btf_map_%s' is too long\n",
751 map_name, map_name);
752 return -EINVAL;
753 }
754
755 container_id = btf__find_by_name(btf, container_name);
756 if (container_id < 0) {
Yonghong Songf7748e22019-02-05 21:38:30 -0800757 pr_debug("map:%s container_name:%s cannot be found in BTF. Missing BPF_ANNOTATE_KV_PAIR?\n",
758 map_name, container_name);
Yonghong Song96408c42019-02-04 11:00:58 -0800759 return container_id;
760 }
761
762 container_type = btf__type_by_id(btf, container_id);
763 if (!container_type) {
764 pr_warning("map:%s cannot find BTF type for container_id:%u\n",
765 map_name, container_id);
766 return -EINVAL;
767 }
768
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700769 if (!btf_is_struct(container_type) || btf_vlen(container_type) < 2) {
Yonghong Song96408c42019-02-04 11:00:58 -0800770 pr_warning("map:%s container_name:%s is an invalid container struct\n",
771 map_name, container_name);
772 return -EINVAL;
773 }
774
Andrii Nakryikob03bc682019-08-07 14:39:49 -0700775 key = btf_members(container_type);
Yonghong Song96408c42019-02-04 11:00:58 -0800776 value = key + 1;
777
778 key_size = btf__resolve_size(btf, key->type);
779 if (key_size < 0) {
780 pr_warning("map:%s invalid BTF key_type_size\n", map_name);
781 return key_size;
782 }
783
784 if (expected_key_size != key_size) {
785 pr_warning("map:%s btf_key_type_size:%u != map_def_key_size:%u\n",
786 map_name, (__u32)key_size, expected_key_size);
787 return -EINVAL;
788 }
789
790 value_size = btf__resolve_size(btf, value->type);
791 if (value_size < 0) {
792 pr_warning("map:%s invalid BTF value_type_size\n", map_name);
793 return value_size;
794 }
795
796 if (expected_value_size != value_size) {
797 pr_warning("map:%s btf_value_type_size:%u != map_def_value_size:%u\n",
798 map_name, (__u32)value_size, expected_value_size);
799 return -EINVAL;
800 }
801
802 *key_type_id = key->type;
803 *value_type_id = value->type;
804
805 return 0;
806}
807
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800808struct btf_ext_sec_setup_param {
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800809 __u32 off;
810 __u32 len;
811 __u32 min_rec_size;
812 struct btf_ext_info *ext_info;
813 const char *desc;
814};
815
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800816static int btf_ext_setup_info(struct btf_ext *btf_ext,
817 struct btf_ext_sec_setup_param *ext_sec)
Yonghong Song2993e052018-11-19 15:29:16 -0800818{
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800819 const struct btf_ext_info_sec *sinfo;
820 struct btf_ext_info *ext_info;
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800821 __u32 info_left, record_size;
822 /* The start of the info sec (including the __u32 record_size). */
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800823 void *info;
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800824
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800825 if (ext_sec->off & 0x03) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800826 pr_debug(".BTF.ext %s section is not aligned to 4 bytes\n",
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800827 ext_sec->desc);
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800828 return -EINVAL;
829 }
830
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800831 info = btf_ext->data + btf_ext->hdr->hdr_len + ext_sec->off;
832 info_left = ext_sec->len;
833
834 if (btf_ext->data + btf_ext->data_size < info + ext_sec->len) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800835 pr_debug("%s section (off:%u len:%u) is beyond the end of the ELF section .BTF.ext\n",
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800836 ext_sec->desc, ext_sec->off, ext_sec->len);
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800837 return -EINVAL;
838 }
839
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800840 /* At least a record size */
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800841 if (info_left < sizeof(__u32)) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800842 pr_debug(".BTF.ext %s record size not found\n", ext_sec->desc);
Yonghong Song2993e052018-11-19 15:29:16 -0800843 return -EINVAL;
844 }
845
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800846 /* The record size needs to meet the minimum standard */
847 record_size = *(__u32 *)info;
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800848 if (record_size < ext_sec->min_rec_size ||
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800849 record_size & 0x03) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800850 pr_debug("%s section in .BTF.ext has invalid record size %u\n",
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800851 ext_sec->desc, record_size);
Yonghong Song2993e052018-11-19 15:29:16 -0800852 return -EINVAL;
853 }
854
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800855 sinfo = info + sizeof(__u32);
856 info_left -= sizeof(__u32);
Yonghong Song2993e052018-11-19 15:29:16 -0800857
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800858 /* If no records, return failure now so .BTF.ext won't be used. */
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800859 if (!info_left) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800860 pr_debug("%s section in .BTF.ext has no records", ext_sec->desc);
Yonghong Song2993e052018-11-19 15:29:16 -0800861 return -EINVAL;
862 }
863
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800864 while (info_left) {
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800865 unsigned int sec_hdrlen = sizeof(struct btf_ext_info_sec);
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800866 __u64 total_record_size;
867 __u32 num_records;
868
869 if (info_left < sec_hdrlen) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800870 pr_debug("%s section header is not found in .BTF.ext\n",
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800871 ext_sec->desc);
Yonghong Song2993e052018-11-19 15:29:16 -0800872 return -EINVAL;
873 }
874
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800875 num_records = sinfo->num_info;
Yonghong Song2993e052018-11-19 15:29:16 -0800876 if (num_records == 0) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800877 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800878 ext_sec->desc);
Yonghong Song2993e052018-11-19 15:29:16 -0800879 return -EINVAL;
880 }
881
882 total_record_size = sec_hdrlen +
883 (__u64)num_records * record_size;
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800884 if (info_left < total_record_size) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800885 pr_debug("%s section has incorrect num_records in .BTF.ext\n",
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800886 ext_sec->desc);
Yonghong Song2993e052018-11-19 15:29:16 -0800887 return -EINVAL;
888 }
889
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800890 info_left -= total_record_size;
Yonghong Song2993e052018-11-19 15:29:16 -0800891 sinfo = (void *)sinfo + total_record_size;
892 }
893
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800894 ext_info = ext_sec->ext_info;
895 ext_info->len = ext_sec->len - sizeof(__u32);
896 ext_info->rec_size = record_size;
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800897 ext_info->info = info + sizeof(__u32);
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800898
Yonghong Song2993e052018-11-19 15:29:16 -0800899 return 0;
900}
901
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800902static int btf_ext_setup_func_info(struct btf_ext *btf_ext)
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800903{
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800904 struct btf_ext_sec_setup_param param = {
905 .off = btf_ext->hdr->func_info_off,
906 .len = btf_ext->hdr->func_info_len,
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800907 .min_rec_size = sizeof(struct bpf_func_info_min),
908 .ext_info = &btf_ext->func_info,
909 .desc = "func_info"
910 };
911
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800912 return btf_ext_setup_info(btf_ext, &param);
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800913}
914
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800915static int btf_ext_setup_line_info(struct btf_ext *btf_ext)
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800916{
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800917 struct btf_ext_sec_setup_param param = {
918 .off = btf_ext->hdr->line_info_off,
919 .len = btf_ext->hdr->line_info_len,
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800920 .min_rec_size = sizeof(struct bpf_line_info_min),
921 .ext_info = &btf_ext->line_info,
922 .desc = "line_info",
923 };
924
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800925 return btf_ext_setup_info(btf_ext, &param);
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800926}
927
Yonghong Song8461ef82019-02-01 16:14:14 -0800928static int btf_ext_parse_hdr(__u8 *data, __u32 data_size)
Yonghong Song2993e052018-11-19 15:29:16 -0800929{
930 const struct btf_ext_header *hdr = (struct btf_ext_header *)data;
Yonghong Song2993e052018-11-19 15:29:16 -0800931
932 if (data_size < offsetof(struct btf_ext_header, func_info_off) ||
933 data_size < hdr->hdr_len) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800934 pr_debug("BTF.ext header not found");
Yonghong Song2993e052018-11-19 15:29:16 -0800935 return -EINVAL;
936 }
937
938 if (hdr->magic != BTF_MAGIC) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800939 pr_debug("Invalid BTF.ext magic:%x\n", hdr->magic);
Yonghong Song2993e052018-11-19 15:29:16 -0800940 return -EINVAL;
941 }
942
943 if (hdr->version != BTF_VERSION) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800944 pr_debug("Unsupported BTF.ext version:%u\n", hdr->version);
Yonghong Song2993e052018-11-19 15:29:16 -0800945 return -ENOTSUP;
946 }
947
948 if (hdr->flags) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800949 pr_debug("Unsupported BTF.ext flags:%x\n", hdr->flags);
Yonghong Song2993e052018-11-19 15:29:16 -0800950 return -ENOTSUP;
951 }
952
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800953 if (data_size == hdr->hdr_len) {
Yonghong Song8461ef82019-02-01 16:14:14 -0800954 pr_debug("BTF.ext has no data\n");
Yonghong Song2993e052018-11-19 15:29:16 -0800955 return -EINVAL;
956 }
957
Martin KaFai Lauf0187f02018-12-07 16:42:29 -0800958 return 0;
Yonghong Song2993e052018-11-19 15:29:16 -0800959}
960
961void btf_ext__free(struct btf_ext *btf_ext)
962{
963 if (!btf_ext)
964 return;
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800965 free(btf_ext->data);
Yonghong Song2993e052018-11-19 15:29:16 -0800966 free(btf_ext);
967}
968
Yonghong Song8461ef82019-02-01 16:14:14 -0800969struct btf_ext *btf_ext__new(__u8 *data, __u32 size)
Yonghong Song2993e052018-11-19 15:29:16 -0800970{
Yonghong Song2993e052018-11-19 15:29:16 -0800971 struct btf_ext *btf_ext;
Yonghong Song2993e052018-11-19 15:29:16 -0800972 int err;
973
Yonghong Song8461ef82019-02-01 16:14:14 -0800974 err = btf_ext_parse_hdr(data, size);
Yonghong Song2993e052018-11-19 15:29:16 -0800975 if (err)
976 return ERR_PTR(err);
977
978 btf_ext = calloc(1, sizeof(struct btf_ext));
979 if (!btf_ext)
980 return ERR_PTR(-ENOMEM);
981
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800982 btf_ext->data_size = size;
983 btf_ext->data = malloc(size);
984 if (!btf_ext->data) {
985 err = -ENOMEM;
986 goto done;
Yonghong Song2993e052018-11-19 15:29:16 -0800987 }
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800988 memcpy(btf_ext->data, data, size);
Yonghong Song2993e052018-11-19 15:29:16 -0800989
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -0800990 err = btf_ext_setup_func_info(btf_ext);
991 if (err)
992 goto done;
993
994 err = btf_ext_setup_line_info(btf_ext);
995 if (err)
996 goto done;
997
998done:
Martin KaFai Lau3d650142018-12-07 16:42:31 -0800999 if (err) {
1000 btf_ext__free(btf_ext);
1001 return ERR_PTR(err);
1002 }
1003
Yonghong Song2993e052018-11-19 15:29:16 -08001004 return btf_ext;
1005}
1006
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -08001007const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, __u32 *size)
1008{
1009 *size = btf_ext->data_size;
1010 return btf_ext->data;
1011}
1012
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001013static int btf_ext_reloc_info(const struct btf *btf,
1014 const struct btf_ext_info *ext_info,
1015 const char *sec_name, __u32 insns_cnt,
1016 void **info, __u32 *cnt)
Yonghong Song2993e052018-11-19 15:29:16 -08001017{
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001018 __u32 sec_hdrlen = sizeof(struct btf_ext_info_sec);
1019 __u32 i, record_size, existing_len, records_len;
1020 struct btf_ext_info_sec *sinfo;
Yonghong Song2993e052018-11-19 15:29:16 -08001021 const char *info_sec_name;
1022 __u64 remain_len;
1023 void *data;
1024
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001025 record_size = ext_info->rec_size;
1026 sinfo = ext_info->info;
1027 remain_len = ext_info->len;
Yonghong Song2993e052018-11-19 15:29:16 -08001028 while (remain_len > 0) {
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001029 records_len = sinfo->num_info * record_size;
Yonghong Song2993e052018-11-19 15:29:16 -08001030 info_sec_name = btf__name_by_offset(btf, sinfo->sec_name_off);
1031 if (strcmp(info_sec_name, sec_name)) {
1032 remain_len -= sec_hdrlen + records_len;
1033 sinfo = (void *)sinfo + sec_hdrlen + records_len;
1034 continue;
1035 }
1036
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001037 existing_len = (*cnt) * record_size;
1038 data = realloc(*info, existing_len + records_len);
Yonghong Song2993e052018-11-19 15:29:16 -08001039 if (!data)
1040 return -ENOMEM;
1041
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001042 memcpy(data + existing_len, sinfo->data, records_len);
Martin KaFai Lau84ecc1f2018-12-05 17:35:47 -08001043 /* adjust insn_off only, the rest data will be passed
Yonghong Song2993e052018-11-19 15:29:16 -08001044 * to the kernel.
1045 */
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001046 for (i = 0; i < sinfo->num_info; i++) {
1047 __u32 *insn_off;
Yonghong Song2993e052018-11-19 15:29:16 -08001048
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001049 insn_off = data + existing_len + (i * record_size);
1050 *insn_off = *insn_off / sizeof(struct bpf_insn) +
Yonghong Song2993e052018-11-19 15:29:16 -08001051 insns_cnt;
1052 }
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001053 *info = data;
1054 *cnt += sinfo->num_info;
Yonghong Song2993e052018-11-19 15:29:16 -08001055 return 0;
1056 }
1057
Martin KaFai Lauf0187f02018-12-07 16:42:29 -08001058 return -ENOENT;
1059}
1060
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -08001061int btf_ext__reloc_func_info(const struct btf *btf,
1062 const struct btf_ext *btf_ext,
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001063 const char *sec_name, __u32 insns_cnt,
1064 void **func_info, __u32 *cnt)
1065{
1066 return btf_ext_reloc_info(btf, &btf_ext->func_info, sec_name,
1067 insns_cnt, func_info, cnt);
1068}
1069
Andrii Nakryikoae4ab4b2019-02-08 11:19:38 -08001070int btf_ext__reloc_line_info(const struct btf *btf,
1071 const struct btf_ext *btf_ext,
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001072 const char *sec_name, __u32 insns_cnt,
1073 void **line_info, __u32 *cnt)
1074{
1075 return btf_ext_reloc_info(btf, &btf_ext->line_info, sec_name,
1076 insns_cnt, line_info, cnt);
1077}
1078
Martin KaFai Lauf0187f02018-12-07 16:42:29 -08001079__u32 btf_ext__func_info_rec_size(const struct btf_ext *btf_ext)
1080{
Martin KaFai Lau3d650142018-12-07 16:42:31 -08001081 return btf_ext->func_info.rec_size;
1082}
1083
1084__u32 btf_ext__line_info_rec_size(const struct btf_ext *btf_ext)
1085{
1086 return btf_ext->line_info.rec_size;
Yonghong Song2993e052018-11-19 15:29:16 -08001087}
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001088
1089struct btf_dedup;
1090
1091static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
1092 const struct btf_dedup_opts *opts);
1093static void btf_dedup_free(struct btf_dedup *d);
1094static int btf_dedup_strings(struct btf_dedup *d);
1095static int btf_dedup_prim_types(struct btf_dedup *d);
1096static int btf_dedup_struct_types(struct btf_dedup *d);
1097static int btf_dedup_ref_types(struct btf_dedup *d);
1098static int btf_dedup_compact_types(struct btf_dedup *d);
1099static int btf_dedup_remap_types(struct btf_dedup *d);
1100
1101/*
1102 * Deduplicate BTF types and strings.
1103 *
1104 * BTF dedup algorithm takes as an input `struct btf` representing `.BTF` ELF
1105 * section with all BTF type descriptors and string data. It overwrites that
1106 * memory in-place with deduplicated types and strings without any loss of
1107 * information. If optional `struct btf_ext` representing '.BTF.ext' ELF section
1108 * is provided, all the strings referenced from .BTF.ext section are honored
1109 * and updated to point to the right offsets after deduplication.
1110 *
1111 * If function returns with error, type/string data might be garbled and should
1112 * be discarded.
1113 *
1114 * More verbose and detailed description of both problem btf_dedup is solving,
1115 * as well as solution could be found at:
1116 * https://facebookmicrosites.github.io/bpf/blog/2018/11/14/btf-enhancement.html
1117 *
1118 * Problem description and justification
1119 * =====================================
1120 *
1121 * BTF type information is typically emitted either as a result of conversion
1122 * from DWARF to BTF or directly by compiler. In both cases, each compilation
1123 * unit contains information about a subset of all the types that are used
1124 * in an application. These subsets are frequently overlapping and contain a lot
1125 * of duplicated information when later concatenated together into a single
1126 * binary. This algorithm ensures that each unique type is represented by single
1127 * BTF type descriptor, greatly reducing resulting size of BTF data.
1128 *
1129 * Compilation unit isolation and subsequent duplication of data is not the only
1130 * problem. The same type hierarchy (e.g., struct and all the type that struct
1131 * references) in different compilation units can be represented in BTF to
1132 * various degrees of completeness (or, rather, incompleteness) due to
1133 * struct/union forward declarations.
1134 *
1135 * Let's take a look at an example, that we'll use to better understand the
1136 * problem (and solution). Suppose we have two compilation units, each using
1137 * same `struct S`, but each of them having incomplete type information about
1138 * struct's fields:
1139 *
1140 * // CU #1:
1141 * struct S;
1142 * struct A {
1143 * int a;
1144 * struct A* self;
1145 * struct S* parent;
1146 * };
1147 * struct B;
1148 * struct S {
1149 * struct A* a_ptr;
1150 * struct B* b_ptr;
1151 * };
1152 *
1153 * // CU #2:
1154 * struct S;
1155 * struct A;
1156 * struct B {
1157 * int b;
1158 * struct B* self;
1159 * struct S* parent;
1160 * };
1161 * struct S {
1162 * struct A* a_ptr;
1163 * struct B* b_ptr;
1164 * };
1165 *
1166 * In case of CU #1, BTF data will know only that `struct B` exist (but no
1167 * more), but will know the complete type information about `struct A`. While
1168 * for CU #2, it will know full type information about `struct B`, but will
1169 * only know about forward declaration of `struct A` (in BTF terms, it will
1170 * have `BTF_KIND_FWD` type descriptor with name `B`).
1171 *
1172 * This compilation unit isolation means that it's possible that there is no
1173 * single CU with complete type information describing structs `S`, `A`, and
1174 * `B`. Also, we might get tons of duplicated and redundant type information.
1175 *
1176 * Additional complication we need to keep in mind comes from the fact that
1177 * types, in general, can form graphs containing cycles, not just DAGs.
1178 *
1179 * While algorithm does deduplication, it also merges and resolves type
1180 * information (unless disabled throught `struct btf_opts`), whenever possible.
1181 * E.g., in the example above with two compilation units having partial type
1182 * information for structs `A` and `B`, the output of algorithm will emit
1183 * a single copy of each BTF type that describes structs `A`, `B`, and `S`
1184 * (as well as type information for `int` and pointers), as if they were defined
1185 * in a single compilation unit as:
1186 *
1187 * struct A {
1188 * int a;
1189 * struct A* self;
1190 * struct S* parent;
1191 * };
1192 * struct B {
1193 * int b;
1194 * struct B* self;
1195 * struct S* parent;
1196 * };
1197 * struct S {
1198 * struct A* a_ptr;
1199 * struct B* b_ptr;
1200 * };
1201 *
1202 * Algorithm summary
1203 * =================
1204 *
1205 * Algorithm completes its work in 6 separate passes:
1206 *
1207 * 1. Strings deduplication.
1208 * 2. Primitive types deduplication (int, enum, fwd).
1209 * 3. Struct/union types deduplication.
1210 * 4. Reference types deduplication (pointers, typedefs, arrays, funcs, func
1211 * protos, and const/volatile/restrict modifiers).
1212 * 5. Types compaction.
1213 * 6. Types remapping.
1214 *
1215 * Algorithm determines canonical type descriptor, which is a single
1216 * representative type for each truly unique type. This canonical type is the
1217 * one that will go into final deduplicated BTF type information. For
1218 * struct/unions, it is also the type that algorithm will merge additional type
1219 * information into (while resolving FWDs), as it discovers it from data in
1220 * other CUs. Each input BTF type eventually gets either mapped to itself, if
1221 * that type is canonical, or to some other type, if that type is equivalent
1222 * and was chosen as canonical representative. This mapping is stored in
1223 * `btf_dedup->map` array. This map is also used to record STRUCT/UNION that
1224 * FWD type got resolved to.
1225 *
1226 * To facilitate fast discovery of canonical types, we also maintain canonical
1227 * index (`btf_dedup->dedup_table`), which maps type descriptor's signature hash
1228 * (i.e., hashed kind, name, size, fields, etc) into a list of canonical types
1229 * that match that signature. With sufficiently good choice of type signature
1230 * hashing function, we can limit number of canonical types for each unique type
1231 * signature to a very small number, allowing to find canonical type for any
1232 * duplicated type very quickly.
1233 *
1234 * Struct/union deduplication is the most critical part and algorithm for
1235 * deduplicating structs/unions is described in greater details in comments for
1236 * `btf_dedup_is_equiv` function.
1237 */
1238int btf__dedup(struct btf *btf, struct btf_ext *btf_ext,
1239 const struct btf_dedup_opts *opts)
1240{
1241 struct btf_dedup *d = btf_dedup_new(btf, btf_ext, opts);
1242 int err;
1243
1244 if (IS_ERR(d)) {
1245 pr_debug("btf_dedup_new failed: %ld", PTR_ERR(d));
1246 return -EINVAL;
1247 }
1248
1249 err = btf_dedup_strings(d);
1250 if (err < 0) {
1251 pr_debug("btf_dedup_strings failed:%d\n", err);
1252 goto done;
1253 }
1254 err = btf_dedup_prim_types(d);
1255 if (err < 0) {
1256 pr_debug("btf_dedup_prim_types failed:%d\n", err);
1257 goto done;
1258 }
1259 err = btf_dedup_struct_types(d);
1260 if (err < 0) {
1261 pr_debug("btf_dedup_struct_types failed:%d\n", err);
1262 goto done;
1263 }
1264 err = btf_dedup_ref_types(d);
1265 if (err < 0) {
1266 pr_debug("btf_dedup_ref_types failed:%d\n", err);
1267 goto done;
1268 }
1269 err = btf_dedup_compact_types(d);
1270 if (err < 0) {
1271 pr_debug("btf_dedup_compact_types failed:%d\n", err);
1272 goto done;
1273 }
1274 err = btf_dedup_remap_types(d);
1275 if (err < 0) {
1276 pr_debug("btf_dedup_remap_types failed:%d\n", err);
1277 goto done;
1278 }
1279
1280done:
1281 btf_dedup_free(d);
1282 return err;
1283}
1284
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001285#define BTF_UNPROCESSED_ID ((__u32)-1)
1286#define BTF_IN_PROGRESS_ID ((__u32)-2)
1287
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001288struct btf_dedup {
1289 /* .BTF section to be deduped in-place */
1290 struct btf *btf;
1291 /*
1292 * Optional .BTF.ext section. When provided, any strings referenced
1293 * from it will be taken into account when deduping strings
1294 */
1295 struct btf_ext *btf_ext;
1296 /*
1297 * This is a map from any type's signature hash to a list of possible
1298 * canonical representative type candidates. Hash collisions are
1299 * ignored, so even types of various kinds can share same list of
1300 * candidates, which is fine because we rely on subsequent
1301 * btf_xxx_equal() checks to authoritatively verify type equality.
1302 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001303 struct hashmap *dedup_table;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001304 /* Canonical types map */
1305 __u32 *map;
1306 /* Hypothetical mapping, used during type graph equivalence checks */
1307 __u32 *hypot_map;
1308 __u32 *hypot_list;
1309 size_t hypot_cnt;
1310 size_t hypot_cap;
1311 /* Various option modifying behavior of algorithm */
1312 struct btf_dedup_opts opts;
1313};
1314
1315struct btf_str_ptr {
1316 const char *str;
1317 __u32 new_off;
1318 bool used;
1319};
1320
1321struct btf_str_ptrs {
1322 struct btf_str_ptr *ptrs;
1323 const char *data;
1324 __u32 cnt;
1325 __u32 cap;
1326};
1327
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001328static long hash_combine(long h, long value)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001329{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001330 return h * 31 + value;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001331}
1332
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001333#define for_each_dedup_cand(d, node, hash) \
1334 hashmap__for_each_key_entry(d->dedup_table, node, (void *)hash)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001335
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001336static int btf_dedup_table_add(struct btf_dedup *d, long hash, __u32 type_id)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001337{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001338 return hashmap__append(d->dedup_table,
1339 (void *)hash, (void *)(long)type_id);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001340}
1341
1342static int btf_dedup_hypot_map_add(struct btf_dedup *d,
1343 __u32 from_id, __u32 to_id)
1344{
1345 if (d->hypot_cnt == d->hypot_cap) {
1346 __u32 *new_list;
1347
1348 d->hypot_cap += max(16, d->hypot_cap / 2);
1349 new_list = realloc(d->hypot_list, sizeof(__u32) * d->hypot_cap);
1350 if (!new_list)
1351 return -ENOMEM;
1352 d->hypot_list = new_list;
1353 }
1354 d->hypot_list[d->hypot_cnt++] = from_id;
1355 d->hypot_map[from_id] = to_id;
1356 return 0;
1357}
1358
1359static void btf_dedup_clear_hypot_map(struct btf_dedup *d)
1360{
1361 int i;
1362
1363 for (i = 0; i < d->hypot_cnt; i++)
1364 d->hypot_map[d->hypot_list[i]] = BTF_UNPROCESSED_ID;
1365 d->hypot_cnt = 0;
1366}
1367
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001368static void btf_dedup_free(struct btf_dedup *d)
1369{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001370 hashmap__free(d->dedup_table);
1371 d->dedup_table = NULL;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001372
1373 free(d->map);
1374 d->map = NULL;
1375
1376 free(d->hypot_map);
1377 d->hypot_map = NULL;
1378
1379 free(d->hypot_list);
1380 d->hypot_list = NULL;
1381
1382 free(d);
1383}
1384
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001385static size_t btf_dedup_identity_hash_fn(const void *key, void *ctx)
Andrii Nakryiko51edf5f2019-02-28 15:31:23 -08001386{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001387 return (size_t)key;
Andrii Nakryiko51edf5f2019-02-28 15:31:23 -08001388}
1389
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001390static size_t btf_dedup_collision_hash_fn(const void *key, void *ctx)
1391{
1392 return 0;
1393}
1394
1395static bool btf_dedup_equal_fn(const void *k1, const void *k2, void *ctx)
1396{
1397 return k1 == k2;
1398}
Andrii Nakryiko51edf5f2019-02-28 15:31:23 -08001399
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001400static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext,
1401 const struct btf_dedup_opts *opts)
1402{
1403 struct btf_dedup *d = calloc(1, sizeof(struct btf_dedup));
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001404 hashmap_hash_fn hash_fn = btf_dedup_identity_hash_fn;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001405 int i, err = 0;
1406
1407 if (!d)
1408 return ERR_PTR(-ENOMEM);
1409
Andrii Nakryiko51edf5f2019-02-28 15:31:23 -08001410 d->opts.dont_resolve_fwds = opts && opts->dont_resolve_fwds;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001411 /* dedup_table_size is now used only to force collisions in tests */
1412 if (opts && opts->dedup_table_size == 1)
1413 hash_fn = btf_dedup_collision_hash_fn;
Andrii Nakryiko51edf5f2019-02-28 15:31:23 -08001414
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001415 d->btf = btf;
1416 d->btf_ext = btf_ext;
1417
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001418 d->dedup_table = hashmap__new(hash_fn, btf_dedup_equal_fn, NULL);
1419 if (IS_ERR(d->dedup_table)) {
1420 err = PTR_ERR(d->dedup_table);
1421 d->dedup_table = NULL;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001422 goto done;
1423 }
1424
1425 d->map = malloc(sizeof(__u32) * (1 + btf->nr_types));
1426 if (!d->map) {
1427 err = -ENOMEM;
1428 goto done;
1429 }
1430 /* special BTF "void" type is made canonical immediately */
1431 d->map[0] = 0;
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07001432 for (i = 1; i <= btf->nr_types; i++) {
1433 struct btf_type *t = d->btf->types[i];
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07001434
1435 /* VAR and DATASEC are never deduped and are self-canonical */
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001436 if (btf_is_var(t) || btf_is_datasec(t))
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07001437 d->map[i] = i;
1438 else
1439 d->map[i] = BTF_UNPROCESSED_ID;
1440 }
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001441
1442 d->hypot_map = malloc(sizeof(__u32) * (1 + btf->nr_types));
1443 if (!d->hypot_map) {
1444 err = -ENOMEM;
1445 goto done;
1446 }
1447 for (i = 0; i <= btf->nr_types; i++)
1448 d->hypot_map[i] = BTF_UNPROCESSED_ID;
1449
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001450done:
1451 if (err) {
1452 btf_dedup_free(d);
1453 return ERR_PTR(err);
1454 }
1455
1456 return d;
1457}
1458
1459typedef int (*str_off_fn_t)(__u32 *str_off_ptr, void *ctx);
1460
1461/*
1462 * Iterate over all possible places in .BTF and .BTF.ext that can reference
1463 * string and pass pointer to it to a provided callback `fn`.
1464 */
1465static int btf_for_each_str_off(struct btf_dedup *d, str_off_fn_t fn, void *ctx)
1466{
1467 void *line_data_cur, *line_data_end;
1468 int i, j, r, rec_size;
1469 struct btf_type *t;
1470
1471 for (i = 1; i <= d->btf->nr_types; i++) {
1472 t = d->btf->types[i];
1473 r = fn(&t->name_off, ctx);
1474 if (r)
1475 return r;
1476
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001477 switch (btf_kind(t)) {
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001478 case BTF_KIND_STRUCT:
1479 case BTF_KIND_UNION: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001480 struct btf_member *m = btf_members(t);
1481 __u16 vlen = btf_vlen(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001482
1483 for (j = 0; j < vlen; j++) {
1484 r = fn(&m->name_off, ctx);
1485 if (r)
1486 return r;
1487 m++;
1488 }
1489 break;
1490 }
1491 case BTF_KIND_ENUM: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001492 struct btf_enum *m = btf_enum(t);
1493 __u16 vlen = btf_vlen(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001494
1495 for (j = 0; j < vlen; j++) {
1496 r = fn(&m->name_off, ctx);
1497 if (r)
1498 return r;
1499 m++;
1500 }
1501 break;
1502 }
1503 case BTF_KIND_FUNC_PROTO: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001504 struct btf_param *m = btf_params(t);
1505 __u16 vlen = btf_vlen(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001506
1507 for (j = 0; j < vlen; j++) {
1508 r = fn(&m->name_off, ctx);
1509 if (r)
1510 return r;
1511 m++;
1512 }
1513 break;
1514 }
1515 default:
1516 break;
1517 }
1518 }
1519
1520 if (!d->btf_ext)
1521 return 0;
1522
1523 line_data_cur = d->btf_ext->line_info.info;
1524 line_data_end = d->btf_ext->line_info.info + d->btf_ext->line_info.len;
1525 rec_size = d->btf_ext->line_info.rec_size;
1526
1527 while (line_data_cur < line_data_end) {
1528 struct btf_ext_info_sec *sec = line_data_cur;
1529 struct bpf_line_info_min *line_info;
1530 __u32 num_info = sec->num_info;
1531
1532 r = fn(&sec->sec_name_off, ctx);
1533 if (r)
1534 return r;
1535
1536 line_data_cur += sizeof(struct btf_ext_info_sec);
1537 for (i = 0; i < num_info; i++) {
1538 line_info = line_data_cur;
1539 r = fn(&line_info->file_name_off, ctx);
1540 if (r)
1541 return r;
1542 r = fn(&line_info->line_off, ctx);
1543 if (r)
1544 return r;
1545 line_data_cur += rec_size;
1546 }
1547 }
1548
1549 return 0;
1550}
1551
1552static int str_sort_by_content(const void *a1, const void *a2)
1553{
1554 const struct btf_str_ptr *p1 = a1;
1555 const struct btf_str_ptr *p2 = a2;
1556
1557 return strcmp(p1->str, p2->str);
1558}
1559
1560static int str_sort_by_offset(const void *a1, const void *a2)
1561{
1562 const struct btf_str_ptr *p1 = a1;
1563 const struct btf_str_ptr *p2 = a2;
1564
1565 if (p1->str != p2->str)
1566 return p1->str < p2->str ? -1 : 1;
1567 return 0;
1568}
1569
1570static int btf_dedup_str_ptr_cmp(const void *str_ptr, const void *pelem)
1571{
1572 const struct btf_str_ptr *p = pelem;
1573
1574 if (str_ptr != p->str)
1575 return (const char *)str_ptr < p->str ? -1 : 1;
1576 return 0;
1577}
1578
1579static int btf_str_mark_as_used(__u32 *str_off_ptr, void *ctx)
1580{
1581 struct btf_str_ptrs *strs;
1582 struct btf_str_ptr *s;
1583
1584 if (*str_off_ptr == 0)
1585 return 0;
1586
1587 strs = ctx;
1588 s = bsearch(strs->data + *str_off_ptr, strs->ptrs, strs->cnt,
1589 sizeof(struct btf_str_ptr), btf_dedup_str_ptr_cmp);
1590 if (!s)
1591 return -EINVAL;
1592 s->used = true;
1593 return 0;
1594}
1595
1596static int btf_str_remap_offset(__u32 *str_off_ptr, void *ctx)
1597{
1598 struct btf_str_ptrs *strs;
1599 struct btf_str_ptr *s;
1600
1601 if (*str_off_ptr == 0)
1602 return 0;
1603
1604 strs = ctx;
1605 s = bsearch(strs->data + *str_off_ptr, strs->ptrs, strs->cnt,
1606 sizeof(struct btf_str_ptr), btf_dedup_str_ptr_cmp);
1607 if (!s)
1608 return -EINVAL;
1609 *str_off_ptr = s->new_off;
1610 return 0;
1611}
1612
1613/*
1614 * Dedup string and filter out those that are not referenced from either .BTF
1615 * or .BTF.ext (if provided) sections.
1616 *
1617 * This is done by building index of all strings in BTF's string section,
1618 * then iterating over all entities that can reference strings (e.g., type
1619 * names, struct field names, .BTF.ext line info, etc) and marking corresponding
1620 * strings as used. After that all used strings are deduped and compacted into
1621 * sequential blob of memory and new offsets are calculated. Then all the string
1622 * references are iterated again and rewritten using new offsets.
1623 */
1624static int btf_dedup_strings(struct btf_dedup *d)
1625{
1626 const struct btf_header *hdr = d->btf->hdr;
1627 char *start = (char *)d->btf->nohdr_data + hdr->str_off;
1628 char *end = start + d->btf->hdr->str_len;
1629 char *p = start, *tmp_strs = NULL;
1630 struct btf_str_ptrs strs = {
1631 .cnt = 0,
1632 .cap = 0,
1633 .ptrs = NULL,
1634 .data = start,
1635 };
1636 int i, j, err = 0, grp_idx;
1637 bool grp_used;
1638
1639 /* build index of all strings */
1640 while (p < end) {
1641 if (strs.cnt + 1 > strs.cap) {
1642 struct btf_str_ptr *new_ptrs;
1643
1644 strs.cap += max(strs.cnt / 2, 16);
1645 new_ptrs = realloc(strs.ptrs,
1646 sizeof(strs.ptrs[0]) * strs.cap);
1647 if (!new_ptrs) {
1648 err = -ENOMEM;
1649 goto done;
1650 }
1651 strs.ptrs = new_ptrs;
1652 }
1653
1654 strs.ptrs[strs.cnt].str = p;
1655 strs.ptrs[strs.cnt].used = false;
1656
1657 p += strlen(p) + 1;
1658 strs.cnt++;
1659 }
1660
1661 /* temporary storage for deduplicated strings */
1662 tmp_strs = malloc(d->btf->hdr->str_len);
1663 if (!tmp_strs) {
1664 err = -ENOMEM;
1665 goto done;
1666 }
1667
1668 /* mark all used strings */
1669 strs.ptrs[0].used = true;
1670 err = btf_for_each_str_off(d, btf_str_mark_as_used, &strs);
1671 if (err)
1672 goto done;
1673
1674 /* sort strings by context, so that we can identify duplicates */
1675 qsort(strs.ptrs, strs.cnt, sizeof(strs.ptrs[0]), str_sort_by_content);
1676
1677 /*
1678 * iterate groups of equal strings and if any instance in a group was
1679 * referenced, emit single instance and remember new offset
1680 */
1681 p = tmp_strs;
1682 grp_idx = 0;
1683 grp_used = strs.ptrs[0].used;
1684 /* iterate past end to avoid code duplication after loop */
1685 for (i = 1; i <= strs.cnt; i++) {
1686 /*
1687 * when i == strs.cnt, we want to skip string comparison and go
1688 * straight to handling last group of strings (otherwise we'd
1689 * need to handle last group after the loop w/ duplicated code)
1690 */
1691 if (i < strs.cnt &&
1692 !strcmp(strs.ptrs[i].str, strs.ptrs[grp_idx].str)) {
1693 grp_used = grp_used || strs.ptrs[i].used;
1694 continue;
1695 }
1696
1697 /*
1698 * this check would have been required after the loop to handle
1699 * last group of strings, but due to <= condition in a loop
1700 * we avoid that duplication
1701 */
1702 if (grp_used) {
1703 int new_off = p - tmp_strs;
1704 __u32 len = strlen(strs.ptrs[grp_idx].str);
1705
1706 memmove(p, strs.ptrs[grp_idx].str, len + 1);
1707 for (j = grp_idx; j < i; j++)
1708 strs.ptrs[j].new_off = new_off;
1709 p += len + 1;
1710 }
1711
1712 if (i < strs.cnt) {
1713 grp_idx = i;
1714 grp_used = strs.ptrs[i].used;
1715 }
1716 }
1717
1718 /* replace original strings with deduped ones */
1719 d->btf->hdr->str_len = p - tmp_strs;
1720 memmove(start, tmp_strs, d->btf->hdr->str_len);
1721 end = start + d->btf->hdr->str_len;
1722
1723 /* restore original order for further binary search lookups */
1724 qsort(strs.ptrs, strs.cnt, sizeof(strs.ptrs[0]), str_sort_by_offset);
1725
1726 /* remap string offsets */
1727 err = btf_for_each_str_off(d, btf_str_remap_offset, &strs);
1728 if (err)
1729 goto done;
1730
1731 d->btf->hdr->str_len = end - start;
1732
1733done:
1734 free(tmp_strs);
1735 free(strs.ptrs);
1736 return err;
1737}
1738
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001739static long btf_hash_common(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001740{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001741 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001742
1743 h = hash_combine(0, t->name_off);
1744 h = hash_combine(h, t->info);
1745 h = hash_combine(h, t->size);
1746 return h;
1747}
1748
1749static bool btf_equal_common(struct btf_type *t1, struct btf_type *t2)
1750{
1751 return t1->name_off == t2->name_off &&
1752 t1->info == t2->info &&
1753 t1->size == t2->size;
1754}
1755
1756/* Calculate type signature hash of INT. */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001757static long btf_hash_int(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001758{
1759 __u32 info = *(__u32 *)(t + 1);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001760 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001761
1762 h = btf_hash_common(t);
1763 h = hash_combine(h, info);
1764 return h;
1765}
1766
1767/* Check structural equality of two INTs. */
1768static bool btf_equal_int(struct btf_type *t1, struct btf_type *t2)
1769{
1770 __u32 info1, info2;
1771
1772 if (!btf_equal_common(t1, t2))
1773 return false;
1774 info1 = *(__u32 *)(t1 + 1);
1775 info2 = *(__u32 *)(t2 + 1);
1776 return info1 == info2;
1777}
1778
1779/* Calculate type signature hash of ENUM. */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001780static long btf_hash_enum(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001781{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001782 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001783
Andrii Nakryiko97680952019-03-10 17:44:09 -07001784 /* don't hash vlen and enum members to support enum fwd resolving */
1785 h = hash_combine(0, t->name_off);
1786 h = hash_combine(h, t->info & ~0xffff);
1787 h = hash_combine(h, t->size);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001788 return h;
1789}
1790
1791/* Check structural equality of two ENUMs. */
1792static bool btf_equal_enum(struct btf_type *t1, struct btf_type *t2)
1793{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001794 const struct btf_enum *m1, *m2;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001795 __u16 vlen;
1796 int i;
1797
1798 if (!btf_equal_common(t1, t2))
1799 return false;
1800
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001801 vlen = btf_vlen(t1);
1802 m1 = btf_enum(t1);
1803 m2 = btf_enum(t2);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001804 for (i = 0; i < vlen; i++) {
1805 if (m1->name_off != m2->name_off || m1->val != m2->val)
1806 return false;
1807 m1++;
1808 m2++;
1809 }
1810 return true;
1811}
1812
Andrii Nakryiko97680952019-03-10 17:44:09 -07001813static inline bool btf_is_enum_fwd(struct btf_type *t)
1814{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001815 return btf_is_enum(t) && btf_vlen(t) == 0;
Andrii Nakryiko97680952019-03-10 17:44:09 -07001816}
1817
1818static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2)
1819{
1820 if (!btf_is_enum_fwd(t1) && !btf_is_enum_fwd(t2))
1821 return btf_equal_enum(t1, t2);
1822 /* ignore vlen when comparing */
1823 return t1->name_off == t2->name_off &&
1824 (t1->info & ~0xffff) == (t2->info & ~0xffff) &&
1825 t1->size == t2->size;
1826}
1827
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001828/*
1829 * Calculate type signature hash of STRUCT/UNION, ignoring referenced type IDs,
1830 * as referenced type IDs equivalence is established separately during type
1831 * graph equivalence check algorithm.
1832 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001833static long btf_hash_struct(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001834{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001835 const struct btf_member *member = btf_members(t);
1836 __u32 vlen = btf_vlen(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001837 long h = btf_hash_common(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001838 int i;
1839
1840 for (i = 0; i < vlen; i++) {
1841 h = hash_combine(h, member->name_off);
1842 h = hash_combine(h, member->offset);
1843 /* no hashing of referenced type ID, it can be unresolved yet */
1844 member++;
1845 }
1846 return h;
1847}
1848
1849/*
1850 * Check structural compatibility of two FUNC_PROTOs, ignoring referenced type
1851 * IDs. This check is performed during type graph equivalence check and
1852 * referenced types equivalence is checked separately.
1853 */
Andrii Nakryiko91097fb2019-02-28 15:31:24 -08001854static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001855{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001856 const struct btf_member *m1, *m2;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001857 __u16 vlen;
1858 int i;
1859
1860 if (!btf_equal_common(t1, t2))
1861 return false;
1862
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001863 vlen = btf_vlen(t1);
1864 m1 = btf_members(t1);
1865 m2 = btf_members(t2);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001866 for (i = 0; i < vlen; i++) {
1867 if (m1->name_off != m2->name_off || m1->offset != m2->offset)
1868 return false;
1869 m1++;
1870 m2++;
1871 }
1872 return true;
1873}
1874
1875/*
1876 * Calculate type signature hash of ARRAY, including referenced type IDs,
1877 * under assumption that they were already resolved to canonical type IDs and
1878 * are not going to change.
1879 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001880static long btf_hash_array(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001881{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001882 const struct btf_array *info = btf_array(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001883 long h = btf_hash_common(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001884
1885 h = hash_combine(h, info->type);
1886 h = hash_combine(h, info->index_type);
1887 h = hash_combine(h, info->nelems);
1888 return h;
1889}
1890
1891/*
1892 * Check exact equality of two ARRAYs, taking into account referenced
1893 * type IDs, under assumption that they were already resolved to canonical
1894 * type IDs and are not going to change.
1895 * This function is called during reference types deduplication to compare
1896 * ARRAY to potential canonical representative.
1897 */
1898static bool btf_equal_array(struct btf_type *t1, struct btf_type *t2)
1899{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001900 const struct btf_array *info1, *info2;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001901
1902 if (!btf_equal_common(t1, t2))
1903 return false;
1904
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001905 info1 = btf_array(t1);
1906 info2 = btf_array(t2);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001907 return info1->type == info2->type &&
1908 info1->index_type == info2->index_type &&
1909 info1->nelems == info2->nelems;
1910}
1911
1912/*
1913 * Check structural compatibility of two ARRAYs, ignoring referenced type
1914 * IDs. This check is performed during type graph equivalence check and
1915 * referenced types equivalence is checked separately.
1916 */
1917static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2)
1918{
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001919 if (!btf_equal_common(t1, t2))
1920 return false;
1921
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001922 return btf_array(t1)->nelems == btf_array(t2)->nelems;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001923}
1924
1925/*
1926 * Calculate type signature hash of FUNC_PROTO, including referenced type IDs,
1927 * under assumption that they were already resolved to canonical type IDs and
1928 * are not going to change.
1929 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001930static long btf_hash_fnproto(struct btf_type *t)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001931{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001932 const struct btf_param *member = btf_params(t);
1933 __u16 vlen = btf_vlen(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001934 long h = btf_hash_common(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001935 int i;
1936
1937 for (i = 0; i < vlen; i++) {
1938 h = hash_combine(h, member->name_off);
1939 h = hash_combine(h, member->type);
1940 member++;
1941 }
1942 return h;
1943}
1944
1945/*
1946 * Check exact equality of two FUNC_PROTOs, taking into account referenced
1947 * type IDs, under assumption that they were already resolved to canonical
1948 * type IDs and are not going to change.
1949 * This function is called during reference types deduplication to compare
1950 * FUNC_PROTO to potential canonical representative.
1951 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001952static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001953{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001954 const struct btf_param *m1, *m2;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001955 __u16 vlen;
1956 int i;
1957
1958 if (!btf_equal_common(t1, t2))
1959 return false;
1960
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001961 vlen = btf_vlen(t1);
1962 m1 = btf_params(t1);
1963 m2 = btf_params(t2);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001964 for (i = 0; i < vlen; i++) {
1965 if (m1->name_off != m2->name_off || m1->type != m2->type)
1966 return false;
1967 m1++;
1968 m2++;
1969 }
1970 return true;
1971}
1972
1973/*
1974 * Check structural compatibility of two FUNC_PROTOs, ignoring referenced type
1975 * IDs. This check is performed during type graph equivalence check and
1976 * referenced types equivalence is checked separately.
1977 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07001978static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001979{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001980 const struct btf_param *m1, *m2;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001981 __u16 vlen;
1982 int i;
1983
1984 /* skip return type ID */
1985 if (t1->name_off != t2->name_off || t1->info != t2->info)
1986 return false;
1987
Andrii Nakryikob03bc682019-08-07 14:39:49 -07001988 vlen = btf_vlen(t1);
1989 m1 = btf_params(t1);
1990 m2 = btf_params(t2);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08001991 for (i = 0; i < vlen; i++) {
1992 if (m1->name_off != m2->name_off)
1993 return false;
1994 m1++;
1995 m2++;
1996 }
1997 return true;
1998}
1999
2000/*
2001 * Deduplicate primitive types, that can't reference other types, by calculating
2002 * their type signature hash and comparing them with any possible canonical
2003 * candidate. If no canonical candidate matches, type itself is marked as
2004 * canonical and is added into `btf_dedup->dedup_table` as another candidate.
2005 */
2006static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id)
2007{
2008 struct btf_type *t = d->btf->types[type_id];
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002009 struct hashmap_entry *hash_entry;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002010 struct btf_type *cand;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002011 /* if we don't find equivalent type, then we are canonical */
2012 __u32 new_id = type_id;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002013 __u32 cand_id;
2014 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002015
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002016 switch (btf_kind(t)) {
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002017 case BTF_KIND_CONST:
2018 case BTF_KIND_VOLATILE:
2019 case BTF_KIND_RESTRICT:
2020 case BTF_KIND_PTR:
2021 case BTF_KIND_TYPEDEF:
2022 case BTF_KIND_ARRAY:
2023 case BTF_KIND_STRUCT:
2024 case BTF_KIND_UNION:
2025 case BTF_KIND_FUNC:
2026 case BTF_KIND_FUNC_PROTO:
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07002027 case BTF_KIND_VAR:
2028 case BTF_KIND_DATASEC:
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002029 return 0;
2030
2031 case BTF_KIND_INT:
2032 h = btf_hash_int(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002033 for_each_dedup_cand(d, hash_entry, h) {
2034 cand_id = (__u32)(long)hash_entry->value;
2035 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002036 if (btf_equal_int(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002037 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002038 break;
2039 }
2040 }
2041 break;
2042
2043 case BTF_KIND_ENUM:
2044 h = btf_hash_enum(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002045 for_each_dedup_cand(d, hash_entry, h) {
2046 cand_id = (__u32)(long)hash_entry->value;
2047 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002048 if (btf_equal_enum(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002049 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002050 break;
2051 }
Andrii Nakryiko97680952019-03-10 17:44:09 -07002052 if (d->opts.dont_resolve_fwds)
2053 continue;
2054 if (btf_compat_enum(t, cand)) {
2055 if (btf_is_enum_fwd(t)) {
2056 /* resolve fwd to full enum */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002057 new_id = cand_id;
Andrii Nakryiko97680952019-03-10 17:44:09 -07002058 break;
2059 }
2060 /* resolve canonical enum fwd to full enum */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002061 d->map[cand_id] = type_id;
Andrii Nakryiko97680952019-03-10 17:44:09 -07002062 }
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002063 }
2064 break;
2065
2066 case BTF_KIND_FWD:
2067 h = btf_hash_common(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002068 for_each_dedup_cand(d, hash_entry, h) {
2069 cand_id = (__u32)(long)hash_entry->value;
2070 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002071 if (btf_equal_common(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002072 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002073 break;
2074 }
2075 }
2076 break;
2077
2078 default:
2079 return -EINVAL;
2080 }
2081
2082 d->map[type_id] = new_id;
2083 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
2084 return -ENOMEM;
2085
2086 return 0;
2087}
2088
2089static int btf_dedup_prim_types(struct btf_dedup *d)
2090{
2091 int i, err;
2092
2093 for (i = 1; i <= d->btf->nr_types; i++) {
2094 err = btf_dedup_prim_type(d, i);
2095 if (err)
2096 return err;
2097 }
2098 return 0;
2099}
2100
2101/*
2102 * Check whether type is already mapped into canonical one (could be to itself).
2103 */
2104static inline bool is_type_mapped(struct btf_dedup *d, uint32_t type_id)
2105{
Andrii Nakryiko5aab3922019-02-15 19:52:18 -08002106 return d->map[type_id] <= BTF_MAX_NR_TYPES;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002107}
2108
2109/*
2110 * Resolve type ID into its canonical type ID, if any; otherwise return original
2111 * type ID. If type is FWD and is resolved into STRUCT/UNION already, follow
2112 * STRUCT/UNION link and resolve it into canonical type ID as well.
2113 */
2114static inline __u32 resolve_type_id(struct btf_dedup *d, __u32 type_id)
2115{
2116 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
2117 type_id = d->map[type_id];
2118 return type_id;
2119}
2120
2121/*
2122 * Resolve FWD to underlying STRUCT/UNION, if any; otherwise return original
2123 * type ID.
2124 */
2125static uint32_t resolve_fwd_id(struct btf_dedup *d, uint32_t type_id)
2126{
2127 __u32 orig_type_id = type_id;
2128
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002129 if (!btf_is_fwd(d->btf->types[type_id]))
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002130 return type_id;
2131
2132 while (is_type_mapped(d, type_id) && d->map[type_id] != type_id)
2133 type_id = d->map[type_id];
2134
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002135 if (!btf_is_fwd(d->btf->types[type_id]))
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002136 return type_id;
2137
2138 return orig_type_id;
2139}
2140
2141
2142static inline __u16 btf_fwd_kind(struct btf_type *t)
2143{
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002144 return btf_kflag(t) ? BTF_KIND_UNION : BTF_KIND_STRUCT;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002145}
2146
2147/*
2148 * Check equivalence of BTF type graph formed by candidate struct/union (we'll
2149 * call it "candidate graph" in this description for brevity) to a type graph
2150 * formed by (potential) canonical struct/union ("canonical graph" for brevity
2151 * here, though keep in mind that not all types in canonical graph are
2152 * necessarily canonical representatives themselves, some of them might be
2153 * duplicates or its uniqueness might not have been established yet).
2154 * Returns:
2155 * - >0, if type graphs are equivalent;
2156 * - 0, if not equivalent;
2157 * - <0, on error.
2158 *
2159 * Algorithm performs side-by-side DFS traversal of both type graphs and checks
2160 * equivalence of BTF types at each step. If at any point BTF types in candidate
2161 * and canonical graphs are not compatible structurally, whole graphs are
2162 * incompatible. If types are structurally equivalent (i.e., all information
2163 * except referenced type IDs is exactly the same), a mapping from `canon_id` to
2164 * a `cand_id` is recored in hypothetical mapping (`btf_dedup->hypot_map`).
2165 * If a type references other types, then those referenced types are checked
2166 * for equivalence recursively.
2167 *
2168 * During DFS traversal, if we find that for current `canon_id` type we
2169 * already have some mapping in hypothetical map, we check for two possible
2170 * situations:
2171 * - `canon_id` is mapped to exactly the same type as `cand_id`. This will
2172 * happen when type graphs have cycles. In this case we assume those two
2173 * types are equivalent.
2174 * - `canon_id` is mapped to different type. This is contradiction in our
2175 * hypothetical mapping, because same graph in canonical graph corresponds
2176 * to two different types in candidate graph, which for equivalent type
2177 * graphs shouldn't happen. This condition terminates equivalence check
2178 * with negative result.
2179 *
2180 * If type graphs traversal exhausts types to check and find no contradiction,
2181 * then type graphs are equivalent.
2182 *
2183 * When checking types for equivalence, there is one special case: FWD types.
2184 * If FWD type resolution is allowed and one of the types (either from canonical
2185 * or candidate graph) is FWD and other is STRUCT/UNION (depending on FWD's kind
2186 * flag) and their names match, hypothetical mapping is updated to point from
2187 * FWD to STRUCT/UNION. If graphs will be determined as equivalent successfully,
2188 * this mapping will be used to record FWD -> STRUCT/UNION mapping permanently.
2189 *
2190 * Technically, this could lead to incorrect FWD to STRUCT/UNION resolution,
2191 * if there are two exactly named (or anonymous) structs/unions that are
2192 * compatible structurally, one of which has FWD field, while other is concrete
2193 * STRUCT/UNION, but according to C sources they are different structs/unions
2194 * that are referencing different types with the same name. This is extremely
2195 * unlikely to happen, but btf_dedup API allows to disable FWD resolution if
2196 * this logic is causing problems.
2197 *
2198 * Doing FWD resolution means that both candidate and/or canonical graphs can
2199 * consists of portions of the graph that come from multiple compilation units.
2200 * This is due to the fact that types within single compilation unit are always
2201 * deduplicated and FWDs are already resolved, if referenced struct/union
2202 * definiton is available. So, if we had unresolved FWD and found corresponding
2203 * STRUCT/UNION, they will be from different compilation units. This
2204 * consequently means that when we "link" FWD to corresponding STRUCT/UNION,
2205 * type graph will likely have at least two different BTF types that describe
2206 * same type (e.g., most probably there will be two different BTF types for the
2207 * same 'int' primitive type) and could even have "overlapping" parts of type
2208 * graph that describe same subset of types.
2209 *
2210 * This in turn means that our assumption that each type in canonical graph
2211 * must correspond to exactly one type in candidate graph might not hold
2212 * anymore and will make it harder to detect contradictions using hypothetical
2213 * map. To handle this problem, we allow to follow FWD -> STRUCT/UNION
2214 * resolution only in canonical graph. FWDs in candidate graphs are never
2215 * resolved. To see why it's OK, let's check all possible situations w.r.t. FWDs
2216 * that can occur:
2217 * - Both types in canonical and candidate graphs are FWDs. If they are
2218 * structurally equivalent, then they can either be both resolved to the
2219 * same STRUCT/UNION or not resolved at all. In both cases they are
2220 * equivalent and there is no need to resolve FWD on candidate side.
2221 * - Both types in canonical and candidate graphs are concrete STRUCT/UNION,
2222 * so nothing to resolve as well, algorithm will check equivalence anyway.
2223 * - Type in canonical graph is FWD, while type in candidate is concrete
2224 * STRUCT/UNION. In this case candidate graph comes from single compilation
2225 * unit, so there is exactly one BTF type for each unique C type. After
2226 * resolving FWD into STRUCT/UNION, there might be more than one BTF type
2227 * in canonical graph mapping to single BTF type in candidate graph, but
2228 * because hypothetical mapping maps from canonical to candidate types, it's
2229 * alright, and we still maintain the property of having single `canon_id`
2230 * mapping to single `cand_id` (there could be two different `canon_id`
2231 * mapped to the same `cand_id`, but it's not contradictory).
2232 * - Type in canonical graph is concrete STRUCT/UNION, while type in candidate
2233 * graph is FWD. In this case we are just going to check compatibility of
2234 * STRUCT/UNION and corresponding FWD, and if they are compatible, we'll
2235 * assume that whatever STRUCT/UNION FWD resolves to must be equivalent to
2236 * a concrete STRUCT/UNION from canonical graph. If the rest of type graphs
2237 * turn out equivalent, we'll re-resolve FWD to concrete STRUCT/UNION from
2238 * canonical graph.
2239 */
2240static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id,
2241 __u32 canon_id)
2242{
2243 struct btf_type *cand_type;
2244 struct btf_type *canon_type;
2245 __u32 hypot_type_id;
2246 __u16 cand_kind;
2247 __u16 canon_kind;
2248 int i, eq;
2249
2250 /* if both resolve to the same canonical, they must be equivalent */
2251 if (resolve_type_id(d, cand_id) == resolve_type_id(d, canon_id))
2252 return 1;
2253
2254 canon_id = resolve_fwd_id(d, canon_id);
2255
2256 hypot_type_id = d->hypot_map[canon_id];
Andrii Nakryiko5aab3922019-02-15 19:52:18 -08002257 if (hypot_type_id <= BTF_MAX_NR_TYPES)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002258 return hypot_type_id == cand_id;
2259
2260 if (btf_dedup_hypot_map_add(d, canon_id, cand_id))
2261 return -ENOMEM;
2262
2263 cand_type = d->btf->types[cand_id];
2264 canon_type = d->btf->types[canon_id];
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002265 cand_kind = btf_kind(cand_type);
2266 canon_kind = btf_kind(canon_type);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002267
2268 if (cand_type->name_off != canon_type->name_off)
2269 return 0;
2270
2271 /* FWD <--> STRUCT/UNION equivalence check, if enabled */
2272 if (!d->opts.dont_resolve_fwds
2273 && (cand_kind == BTF_KIND_FWD || canon_kind == BTF_KIND_FWD)
2274 && cand_kind != canon_kind) {
2275 __u16 real_kind;
2276 __u16 fwd_kind;
2277
2278 if (cand_kind == BTF_KIND_FWD) {
2279 real_kind = canon_kind;
2280 fwd_kind = btf_fwd_kind(cand_type);
2281 } else {
2282 real_kind = cand_kind;
2283 fwd_kind = btf_fwd_kind(canon_type);
2284 }
2285 return fwd_kind == real_kind;
2286 }
2287
Andrii Nakryiko9ec71c12019-03-26 22:00:06 -07002288 if (cand_kind != canon_kind)
2289 return 0;
2290
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002291 switch (cand_kind) {
2292 case BTF_KIND_INT:
2293 return btf_equal_int(cand_type, canon_type);
2294
2295 case BTF_KIND_ENUM:
Andrii Nakryiko97680952019-03-10 17:44:09 -07002296 if (d->opts.dont_resolve_fwds)
2297 return btf_equal_enum(cand_type, canon_type);
2298 else
2299 return btf_compat_enum(cand_type, canon_type);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002300
2301 case BTF_KIND_FWD:
2302 return btf_equal_common(cand_type, canon_type);
2303
2304 case BTF_KIND_CONST:
2305 case BTF_KIND_VOLATILE:
2306 case BTF_KIND_RESTRICT:
2307 case BTF_KIND_PTR:
2308 case BTF_KIND_TYPEDEF:
2309 case BTF_KIND_FUNC:
Andrii Nakryiko97680952019-03-10 17:44:09 -07002310 if (cand_type->info != canon_type->info)
2311 return 0;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002312 return btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
2313
2314 case BTF_KIND_ARRAY: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002315 const struct btf_array *cand_arr, *canon_arr;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002316
2317 if (!btf_compat_array(cand_type, canon_type))
2318 return 0;
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002319 cand_arr = btf_array(cand_type);
2320 canon_arr = btf_array(canon_type);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002321 eq = btf_dedup_is_equiv(d,
2322 cand_arr->index_type, canon_arr->index_type);
2323 if (eq <= 0)
2324 return eq;
2325 return btf_dedup_is_equiv(d, cand_arr->type, canon_arr->type);
2326 }
2327
2328 case BTF_KIND_STRUCT:
2329 case BTF_KIND_UNION: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002330 const struct btf_member *cand_m, *canon_m;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002331 __u16 vlen;
2332
Andrii Nakryiko91097fb2019-02-28 15:31:24 -08002333 if (!btf_shallow_equal_struct(cand_type, canon_type))
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002334 return 0;
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002335 vlen = btf_vlen(cand_type);
2336 cand_m = btf_members(cand_type);
2337 canon_m = btf_members(canon_type);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002338 for (i = 0; i < vlen; i++) {
2339 eq = btf_dedup_is_equiv(d, cand_m->type, canon_m->type);
2340 if (eq <= 0)
2341 return eq;
2342 cand_m++;
2343 canon_m++;
2344 }
2345
2346 return 1;
2347 }
2348
2349 case BTF_KIND_FUNC_PROTO: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002350 const struct btf_param *cand_p, *canon_p;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002351 __u16 vlen;
2352
2353 if (!btf_compat_fnproto(cand_type, canon_type))
2354 return 0;
2355 eq = btf_dedup_is_equiv(d, cand_type->type, canon_type->type);
2356 if (eq <= 0)
2357 return eq;
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002358 vlen = btf_vlen(cand_type);
2359 cand_p = btf_params(cand_type);
2360 canon_p = btf_params(canon_type);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002361 for (i = 0; i < vlen; i++) {
2362 eq = btf_dedup_is_equiv(d, cand_p->type, canon_p->type);
2363 if (eq <= 0)
2364 return eq;
2365 cand_p++;
2366 canon_p++;
2367 }
2368 return 1;
2369 }
2370
2371 default:
2372 return -EINVAL;
2373 }
2374 return 0;
2375}
2376
2377/*
2378 * Use hypothetical mapping, produced by successful type graph equivalence
2379 * check, to augment existing struct/union canonical mapping, where possible.
2380 *
2381 * If BTF_KIND_FWD resolution is allowed, this mapping is also used to record
2382 * FWD -> STRUCT/UNION correspondence as well. FWD resolution is bidirectional:
2383 * it doesn't matter if FWD type was part of canonical graph or candidate one,
2384 * we are recording the mapping anyway. As opposed to carefulness required
2385 * for struct/union correspondence mapping (described below), for FWD resolution
2386 * it's not important, as by the time that FWD type (reference type) will be
2387 * deduplicated all structs/unions will be deduped already anyway.
2388 *
2389 * Recording STRUCT/UNION mapping is purely a performance optimization and is
2390 * not required for correctness. It needs to be done carefully to ensure that
2391 * struct/union from candidate's type graph is not mapped into corresponding
2392 * struct/union from canonical type graph that itself hasn't been resolved into
2393 * canonical representative. The only guarantee we have is that canonical
2394 * struct/union was determined as canonical and that won't change. But any
2395 * types referenced through that struct/union fields could have been not yet
2396 * resolved, so in case like that it's too early to establish any kind of
2397 * correspondence between structs/unions.
2398 *
2399 * No canonical correspondence is derived for primitive types (they are already
2400 * deduplicated completely already anyway) or reference types (they rely on
2401 * stability of struct/union canonical relationship for equivalence checks).
2402 */
2403static void btf_dedup_merge_hypot_map(struct btf_dedup *d)
2404{
2405 __u32 cand_type_id, targ_type_id;
2406 __u16 t_kind, c_kind;
2407 __u32 t_id, c_id;
2408 int i;
2409
2410 for (i = 0; i < d->hypot_cnt; i++) {
2411 cand_type_id = d->hypot_list[i];
2412 targ_type_id = d->hypot_map[cand_type_id];
2413 t_id = resolve_type_id(d, targ_type_id);
2414 c_id = resolve_type_id(d, cand_type_id);
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002415 t_kind = btf_kind(d->btf->types[t_id]);
2416 c_kind = btf_kind(d->btf->types[c_id]);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002417 /*
2418 * Resolve FWD into STRUCT/UNION.
2419 * It's ok to resolve FWD into STRUCT/UNION that's not yet
2420 * mapped to canonical representative (as opposed to
2421 * STRUCT/UNION <--> STRUCT/UNION mapping logic below), because
2422 * eventually that struct is going to be mapped and all resolved
2423 * FWDs will automatically resolve to correct canonical
2424 * representative. This will happen before ref type deduping,
2425 * which critically depends on stability of these mapping. This
2426 * stability is not a requirement for STRUCT/UNION equivalence
2427 * checks, though.
2428 */
2429 if (t_kind != BTF_KIND_FWD && c_kind == BTF_KIND_FWD)
2430 d->map[c_id] = t_id;
2431 else if (t_kind == BTF_KIND_FWD && c_kind != BTF_KIND_FWD)
2432 d->map[t_id] = c_id;
2433
2434 if ((t_kind == BTF_KIND_STRUCT || t_kind == BTF_KIND_UNION) &&
2435 c_kind != BTF_KIND_FWD &&
2436 is_type_mapped(d, c_id) &&
2437 !is_type_mapped(d, t_id)) {
2438 /*
2439 * as a perf optimization, we can map struct/union
2440 * that's part of type graph we just verified for
2441 * equivalence. We can do that for struct/union that has
2442 * canonical representative only, though.
2443 */
2444 d->map[t_id] = c_id;
2445 }
2446 }
2447}
2448
2449/*
2450 * Deduplicate struct/union types.
2451 *
2452 * For each struct/union type its type signature hash is calculated, taking
2453 * into account type's name, size, number, order and names of fields, but
2454 * ignoring type ID's referenced from fields, because they might not be deduped
2455 * completely until after reference types deduplication phase. This type hash
2456 * is used to iterate over all potential canonical types, sharing same hash.
2457 * For each canonical candidate we check whether type graphs that they form
2458 * (through referenced types in fields and so on) are equivalent using algorithm
2459 * implemented in `btf_dedup_is_equiv`. If such equivalence is found and
2460 * BTF_KIND_FWD resolution is allowed, then hypothetical mapping
2461 * (btf_dedup->hypot_map) produced by aforementioned type graph equivalence
2462 * algorithm is used to record FWD -> STRUCT/UNION mapping. It's also used to
2463 * potentially map other structs/unions to their canonical representatives,
2464 * if such relationship hasn't yet been established. This speeds up algorithm
2465 * by eliminating some of the duplicate work.
2466 *
2467 * If no matching canonical representative was found, struct/union is marked
2468 * as canonical for itself and is added into btf_dedup->dedup_table hash map
2469 * for further look ups.
2470 */
2471static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id)
2472{
Andrii Nakryiko91097fb2019-02-28 15:31:24 -08002473 struct btf_type *cand_type, *t;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002474 struct hashmap_entry *hash_entry;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002475 /* if we don't find equivalent type, then we are canonical */
2476 __u32 new_id = type_id;
2477 __u16 kind;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002478 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002479
2480 /* already deduped or is in process of deduping (loop detected) */
Andrii Nakryiko5aab3922019-02-15 19:52:18 -08002481 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002482 return 0;
2483
2484 t = d->btf->types[type_id];
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002485 kind = btf_kind(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002486
2487 if (kind != BTF_KIND_STRUCT && kind != BTF_KIND_UNION)
2488 return 0;
2489
2490 h = btf_hash_struct(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002491 for_each_dedup_cand(d, hash_entry, h) {
2492 __u32 cand_id = (__u32)(long)hash_entry->value;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002493 int eq;
2494
Andrii Nakryiko91097fb2019-02-28 15:31:24 -08002495 /*
2496 * Even though btf_dedup_is_equiv() checks for
2497 * btf_shallow_equal_struct() internally when checking two
2498 * structs (unions) for equivalence, we need to guard here
2499 * from picking matching FWD type as a dedup candidate.
2500 * This can happen due to hash collision. In such case just
2501 * relying on btf_dedup_is_equiv() would lead to potentially
2502 * creating a loop (FWD -> STRUCT and STRUCT -> FWD), because
2503 * FWD and compatible STRUCT/UNION are considered equivalent.
2504 */
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002505 cand_type = d->btf->types[cand_id];
Andrii Nakryiko91097fb2019-02-28 15:31:24 -08002506 if (!btf_shallow_equal_struct(t, cand_type))
2507 continue;
2508
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002509 btf_dedup_clear_hypot_map(d);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002510 eq = btf_dedup_is_equiv(d, type_id, cand_id);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002511 if (eq < 0)
2512 return eq;
2513 if (!eq)
2514 continue;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002515 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002516 btf_dedup_merge_hypot_map(d);
2517 break;
2518 }
2519
2520 d->map[type_id] = new_id;
2521 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
2522 return -ENOMEM;
2523
2524 return 0;
2525}
2526
2527static int btf_dedup_struct_types(struct btf_dedup *d)
2528{
2529 int i, err;
2530
2531 for (i = 1; i <= d->btf->nr_types; i++) {
2532 err = btf_dedup_struct_type(d, i);
2533 if (err)
2534 return err;
2535 }
2536 return 0;
2537}
2538
2539/*
2540 * Deduplicate reference type.
2541 *
2542 * Once all primitive and struct/union types got deduplicated, we can easily
2543 * deduplicate all other (reference) BTF types. This is done in two steps:
2544 *
2545 * 1. Resolve all referenced type IDs into their canonical type IDs. This
2546 * resolution can be done either immediately for primitive or struct/union types
2547 * (because they were deduped in previous two phases) or recursively for
2548 * reference types. Recursion will always terminate at either primitive or
2549 * struct/union type, at which point we can "unwind" chain of reference types
2550 * one by one. There is no danger of encountering cycles because in C type
2551 * system the only way to form type cycle is through struct/union, so any chain
2552 * of reference types, even those taking part in a type cycle, will inevitably
2553 * reach struct/union at some point.
2554 *
2555 * 2. Once all referenced type IDs are resolved into canonical ones, BTF type
2556 * becomes "stable", in the sense that no further deduplication will cause
2557 * any changes to it. With that, it's now possible to calculate type's signature
2558 * hash (this time taking into account referenced type IDs) and loop over all
2559 * potential canonical representatives. If no match was found, current type
2560 * will become canonical representative of itself and will be added into
2561 * btf_dedup->dedup_table as another possible canonical representative.
2562 */
2563static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id)
2564{
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002565 struct hashmap_entry *hash_entry;
2566 __u32 new_id = type_id, cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002567 struct btf_type *t, *cand;
2568 /* if we don't find equivalent type, then we are representative type */
Dan Carpenter3d8669e2019-02-28 21:06:47 +03002569 int ref_type_id;
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002570 long h;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002571
2572 if (d->map[type_id] == BTF_IN_PROGRESS_ID)
2573 return -ELOOP;
Andrii Nakryiko5aab3922019-02-15 19:52:18 -08002574 if (d->map[type_id] <= BTF_MAX_NR_TYPES)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002575 return resolve_type_id(d, type_id);
2576
2577 t = d->btf->types[type_id];
2578 d->map[type_id] = BTF_IN_PROGRESS_ID;
2579
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002580 switch (btf_kind(t)) {
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002581 case BTF_KIND_CONST:
2582 case BTF_KIND_VOLATILE:
2583 case BTF_KIND_RESTRICT:
2584 case BTF_KIND_PTR:
2585 case BTF_KIND_TYPEDEF:
2586 case BTF_KIND_FUNC:
2587 ref_type_id = btf_dedup_ref_type(d, t->type);
2588 if (ref_type_id < 0)
2589 return ref_type_id;
2590 t->type = ref_type_id;
2591
2592 h = btf_hash_common(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002593 for_each_dedup_cand(d, hash_entry, h) {
2594 cand_id = (__u32)(long)hash_entry->value;
2595 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002596 if (btf_equal_common(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002597 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002598 break;
2599 }
2600 }
2601 break;
2602
2603 case BTF_KIND_ARRAY: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002604 struct btf_array *info = btf_array(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002605
2606 ref_type_id = btf_dedup_ref_type(d, info->type);
2607 if (ref_type_id < 0)
2608 return ref_type_id;
2609 info->type = ref_type_id;
2610
2611 ref_type_id = btf_dedup_ref_type(d, info->index_type);
2612 if (ref_type_id < 0)
2613 return ref_type_id;
2614 info->index_type = ref_type_id;
2615
2616 h = btf_hash_array(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002617 for_each_dedup_cand(d, hash_entry, h) {
2618 cand_id = (__u32)(long)hash_entry->value;
2619 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002620 if (btf_equal_array(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002621 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002622 break;
2623 }
2624 }
2625 break;
2626 }
2627
2628 case BTF_KIND_FUNC_PROTO: {
2629 struct btf_param *param;
2630 __u16 vlen;
2631 int i;
2632
2633 ref_type_id = btf_dedup_ref_type(d, t->type);
2634 if (ref_type_id < 0)
2635 return ref_type_id;
2636 t->type = ref_type_id;
2637
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002638 vlen = btf_vlen(t);
2639 param = btf_params(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002640 for (i = 0; i < vlen; i++) {
2641 ref_type_id = btf_dedup_ref_type(d, param->type);
2642 if (ref_type_id < 0)
2643 return ref_type_id;
2644 param->type = ref_type_id;
2645 param++;
2646 }
2647
2648 h = btf_hash_fnproto(t);
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002649 for_each_dedup_cand(d, hash_entry, h) {
2650 cand_id = (__u32)(long)hash_entry->value;
2651 cand = d->btf->types[cand_id];
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002652 if (btf_equal_fnproto(t, cand)) {
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002653 new_id = cand_id;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002654 break;
2655 }
2656 }
2657 break;
2658 }
2659
2660 default:
2661 return -EINVAL;
2662 }
2663
2664 d->map[type_id] = new_id;
2665 if (type_id == new_id && btf_dedup_table_add(d, h, type_id))
2666 return -ENOMEM;
2667
2668 return new_id;
2669}
2670
2671static int btf_dedup_ref_types(struct btf_dedup *d)
2672{
2673 int i, err;
2674
2675 for (i = 1; i <= d->btf->nr_types; i++) {
2676 err = btf_dedup_ref_type(d, i);
2677 if (err < 0)
2678 return err;
2679 }
Andrii Nakryiko2fc3fc02019-05-24 11:59:02 -07002680 /* we won't need d->dedup_table anymore */
2681 hashmap__free(d->dedup_table);
2682 d->dedup_table = NULL;
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002683 return 0;
2684}
2685
2686/*
2687 * Compact types.
2688 *
2689 * After we established for each type its corresponding canonical representative
2690 * type, we now can eliminate types that are not canonical and leave only
2691 * canonical ones layed out sequentially in memory by copying them over
2692 * duplicates. During compaction btf_dedup->hypot_map array is reused to store
2693 * a map from original type ID to a new compacted type ID, which will be used
2694 * during next phase to "fix up" type IDs, referenced from struct/union and
2695 * reference types.
2696 */
2697static int btf_dedup_compact_types(struct btf_dedup *d)
2698{
2699 struct btf_type **new_types;
2700 __u32 next_type_id = 1;
2701 char *types_start, *p;
2702 int i, len;
2703
2704 /* we are going to reuse hypot_map to store compaction remapping */
2705 d->hypot_map[0] = 0;
2706 for (i = 1; i <= d->btf->nr_types; i++)
2707 d->hypot_map[i] = BTF_UNPROCESSED_ID;
2708
2709 types_start = d->btf->nohdr_data + d->btf->hdr->type_off;
2710 p = types_start;
2711
2712 for (i = 1; i <= d->btf->nr_types; i++) {
2713 if (d->map[i] != i)
2714 continue;
2715
2716 len = btf_type_size(d->btf->types[i]);
2717 if (len < 0)
2718 return len;
2719
2720 memmove(p, d->btf->types[i], len);
2721 d->hypot_map[i] = next_type_id;
2722 d->btf->types[next_type_id] = (struct btf_type *)p;
2723 p += len;
2724 next_type_id++;
2725 }
2726
2727 /* shrink struct btf's internal types index and update btf_header */
2728 d->btf->nr_types = next_type_id - 1;
2729 d->btf->types_size = d->btf->nr_types;
2730 d->btf->hdr->type_len = p - types_start;
2731 new_types = realloc(d->btf->types,
2732 (1 + d->btf->nr_types) * sizeof(struct btf_type *));
2733 if (!new_types)
2734 return -ENOMEM;
2735 d->btf->types = new_types;
2736
2737 /* make sure string section follows type information without gaps */
2738 d->btf->hdr->str_off = p - (char *)d->btf->nohdr_data;
2739 memmove(p, d->btf->strings, d->btf->hdr->str_len);
2740 d->btf->strings = p;
2741 p += d->btf->hdr->str_len;
2742
2743 d->btf->data_size = p - (char *)d->btf->data;
2744 return 0;
2745}
2746
2747/*
2748 * Figure out final (deduplicated and compacted) type ID for provided original
2749 * `type_id` by first resolving it into corresponding canonical type ID and
2750 * then mapping it to a deduplicated type ID, stored in btf_dedup->hypot_map,
2751 * which is populated during compaction phase.
2752 */
2753static int btf_dedup_remap_type_id(struct btf_dedup *d, __u32 type_id)
2754{
2755 __u32 resolved_type_id, new_type_id;
2756
2757 resolved_type_id = resolve_type_id(d, type_id);
2758 new_type_id = d->hypot_map[resolved_type_id];
Andrii Nakryiko5aab3922019-02-15 19:52:18 -08002759 if (new_type_id > BTF_MAX_NR_TYPES)
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002760 return -EINVAL;
2761 return new_type_id;
2762}
2763
2764/*
2765 * Remap referenced type IDs into deduped type IDs.
2766 *
2767 * After BTF types are deduplicated and compacted, their final type IDs may
2768 * differ from original ones. The map from original to a corresponding
2769 * deduped type ID is stored in btf_dedup->hypot_map and is populated during
2770 * compaction phase. During remapping phase we are rewriting all type IDs
2771 * referenced from any BTF type (e.g., struct fields, func proto args, etc) to
2772 * their final deduped type IDs.
2773 */
2774static int btf_dedup_remap_type(struct btf_dedup *d, __u32 type_id)
2775{
2776 struct btf_type *t = d->btf->types[type_id];
2777 int i, r;
2778
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002779 switch (btf_kind(t)) {
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002780 case BTF_KIND_INT:
2781 case BTF_KIND_ENUM:
2782 break;
2783
2784 case BTF_KIND_FWD:
2785 case BTF_KIND_CONST:
2786 case BTF_KIND_VOLATILE:
2787 case BTF_KIND_RESTRICT:
2788 case BTF_KIND_PTR:
2789 case BTF_KIND_TYPEDEF:
2790 case BTF_KIND_FUNC:
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07002791 case BTF_KIND_VAR:
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002792 r = btf_dedup_remap_type_id(d, t->type);
2793 if (r < 0)
2794 return r;
2795 t->type = r;
2796 break;
2797
2798 case BTF_KIND_ARRAY: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002799 struct btf_array *arr_info = btf_array(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002800
2801 r = btf_dedup_remap_type_id(d, arr_info->type);
2802 if (r < 0)
2803 return r;
2804 arr_info->type = r;
2805 r = btf_dedup_remap_type_id(d, arr_info->index_type);
2806 if (r < 0)
2807 return r;
2808 arr_info->index_type = r;
2809 break;
2810 }
2811
2812 case BTF_KIND_STRUCT:
2813 case BTF_KIND_UNION: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002814 struct btf_member *member = btf_members(t);
2815 __u16 vlen = btf_vlen(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002816
2817 for (i = 0; i < vlen; i++) {
2818 r = btf_dedup_remap_type_id(d, member->type);
2819 if (r < 0)
2820 return r;
2821 member->type = r;
2822 member++;
2823 }
2824 break;
2825 }
2826
2827 case BTF_KIND_FUNC_PROTO: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002828 struct btf_param *param = btf_params(t);
2829 __u16 vlen = btf_vlen(t);
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002830
2831 r = btf_dedup_remap_type_id(d, t->type);
2832 if (r < 0)
2833 return r;
2834 t->type = r;
2835
2836 for (i = 0; i < vlen; i++) {
2837 r = btf_dedup_remap_type_id(d, param->type);
2838 if (r < 0)
2839 return r;
2840 param->type = r;
2841 param++;
2842 }
2843 break;
2844 }
2845
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07002846 case BTF_KIND_DATASEC: {
Andrii Nakryikob03bc682019-08-07 14:39:49 -07002847 struct btf_var_secinfo *var = btf_var_secinfos(t);
2848 __u16 vlen = btf_vlen(t);
Andrii Nakryiko189cf5a2019-04-15 16:48:07 -07002849
2850 for (i = 0; i < vlen; i++) {
2851 r = btf_dedup_remap_type_id(d, var->type);
2852 if (r < 0)
2853 return r;
2854 var->type = r;
2855 var++;
2856 }
2857 break;
2858 }
2859
Andrii Nakryikod5caef52019-02-04 17:29:45 -08002860 default:
2861 return -EINVAL;
2862 }
2863
2864 return 0;
2865}
2866
2867static int btf_dedup_remap_types(struct btf_dedup *d)
2868{
2869 int i, r;
2870
2871 for (i = 1; i <= d->btf->nr_types; i++) {
2872 r = btf_dedup_remap_type(d, i);
2873 if (r < 0)
2874 return r;
2875 }
2876 return 0;
2877}