1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2 /* Copyright (c) 2024, Oracle and/or its affiliates. */
10 #include <linux/bsearch.h>
11 #include <linux/btf.h>
12 #include <linux/sort.h>
13 #include <linux/string.h>
14 #include <linux/bpf_verifier.h>
16 #define btf_type_by_id (struct btf_type *)btf_type_by_id
17 #define btf__type_cnt btf_nr_types
18 #define btf__base_btf btf_base_btf
19 #define btf__name_by_offset btf_name_by_offset
20 #define btf__str_by_offset btf_str_by_offset
21 #define btf_kflag btf_type_kflag
23 #define calloc(nmemb, sz) kvcalloc(nmemb, sz, GFP_KERNEL | __GFP_NOWARN)
24 #define free(ptr) kvfree(ptr)
25 #define qsort(base, num, sz, cmp) sort(base, num, sz, cmp, NULL)
32 #include "libbpf_internal.h"
34 #endif /* __KERNEL__ */
40 const struct btf *base_btf;
41 const struct btf *dist_base_btf;
42 unsigned int nr_base_types;
43 unsigned int nr_split_types;
44 unsigned int nr_dist_base_types;
51 /* Set temporarily in relocation id_map if distilled base struct/union is
52 * embedded in a split BTF struct/union; in such a case, size information must
53 * match between distilled base BTF and base BTF representation of type.
55 #define BTF_IS_EMBEDDED ((__u32)-1)
57 /* <name, size, id> triple used in sorting/searching distilled base BTF. */
58 struct btf_name_info {
60 /* set when search requires a size match */
62 unsigned int size: 31;
66 static int btf_relocate_rewrite_type_id(struct btf_relocate *r, __u32 i)
68 struct btf_type *t = btf_type_by_id(r->btf, i);
69 struct btf_field_iter it;
73 err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
77 while ((id = btf_field_iter_next(&it)))
82 /* Simple string comparison used for sorting within BTF, since all distilled
83 * types are named. If strings match, and size is non-zero for both elements
84 * fall back to using size for ordering.
86 static int cmp_btf_name_size(const void *n1, const void *n2)
88 const struct btf_name_info *ni1 = n1;
89 const struct btf_name_info *ni2 = n2;
90 int name_diff = strcmp(ni1->name, ni2->name);
92 if (!name_diff && ni1->needs_size && ni2->needs_size)
93 return ni2->size - ni1->size;
97 /* Binary search with a small twist; find leftmost element that matches
98 * so that we can then iterate through all exact matches. So for example
99 * searching { "a", "bb", "bb", "c" } we would always match on the
102 static struct btf_name_info *search_btf_name_size(struct btf_name_info *key,
103 struct btf_name_info *vals,
106 struct btf_name_info *ret = NULL;
107 int high = nelems - 1;
110 while (low <= high) {
111 int mid = (low + high)/2;
112 struct btf_name_info *val = &vals[mid];
113 int diff = cmp_btf_name_size(key, val);
117 /* even if found, keep searching for leftmost match */
126 /* If a member of a split BTF struct/union refers to a base BTF
127 * struct/union, mark that struct/union id temporarily in the id_map
128 * with BTF_IS_EMBEDDED. Members can be const/restrict/volatile/typedef
129 * reference types, but if a pointer is encountered, the type is no longer
130 * considered embedded.
132 static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i)
134 struct btf_type *t = btf_type_by_id(r->btf, i);
135 struct btf_field_iter it;
139 if (!btf_is_composite(t))
142 err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
146 while ((id = btf_field_iter_next(&it))) {
150 t = btf_type_by_id(r->btf, next_id);
151 switch (btf_kind(t)) {
153 case BTF_KIND_RESTRICT:
154 case BTF_KIND_VOLATILE:
155 case BTF_KIND_TYPEDEF:
156 case BTF_KIND_TYPE_TAG:
159 case BTF_KIND_ARRAY: {
160 struct btf_array *a = btf_array(t);
165 case BTF_KIND_STRUCT:
167 if (next_id < r->nr_dist_base_types)
168 r->id_map[next_id] = BTF_IS_EMBEDDED;
181 /* Build a map from distilled base BTF ids to base BTF ids. To do so, iterate
182 * through base BTF looking up distilled type (using binary search) equivalents.
184 static int btf_relocate_map_distilled_base(struct btf_relocate *r)
186 struct btf_name_info *info, *info_end;
187 struct btf_type *base_t, *dist_t;
188 __u8 *base_name_cnt = NULL;
192 /* generate a sort index array of name/type ids sorted by name for
193 * distilled base BTF to speed name-based lookups.
195 info = calloc(r->nr_dist_base_types, sizeof(*info));
200 info_end = info + r->nr_dist_base_types;
201 for (id = 0; id < r->nr_dist_base_types; id++) {
202 dist_t = btf_type_by_id(r->dist_base_btf, id);
203 info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
205 info[id].size = dist_t->size;
206 info[id].needs_size = true;
208 qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size);
210 /* Mark distilled base struct/union members of split BTF structs/unions
211 * in id_map with BTF_IS_EMBEDDED; this signals that these types
212 * need to match both name and size, otherwise embedding the base
213 * struct/union in the split type is invalid.
215 for (id = r->nr_dist_base_types; id < r->nr_split_types; id++) {
216 err = btf_mark_embedded_composite_type_ids(r, id);
221 /* Collect name counts for composite types in base BTF. If multiple
222 * instances of a struct/union of the same name exist, we need to use
223 * size to determine which to map to since name alone is ambiguous.
225 base_name_cnt = calloc(r->base_str_len, sizeof(*base_name_cnt));
226 if (!base_name_cnt) {
230 for (id = 1; id < r->nr_base_types; id++) {
231 base_t = btf_type_by_id(r->base_btf, id);
232 if (!btf_is_composite(base_t) || !base_t->name_off)
234 if (base_name_cnt[base_t->name_off] < 255)
235 base_name_cnt[base_t->name_off]++;
238 /* Now search base BTF for matching distilled base BTF types. */
239 for (id = 1; id < r->nr_base_types; id++) {
240 struct btf_name_info *dist_info, base_info = {};
241 int dist_kind, base_kind;
243 base_t = btf_type_by_id(r->base_btf, id);
244 /* distilled base consists of named types only. */
245 if (!base_t->name_off)
247 base_kind = btf_kind(base_t);
249 base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
254 case BTF_KIND_ENUM64:
255 /* These types should match both name and size */
256 base_info.needs_size = true;
257 base_info.size = base_t->size;
260 /* No size considerations for fwds. */
262 case BTF_KIND_STRUCT:
264 /* Size only needs to be used for struct/union if there
265 * are multiple types in base BTF with the same name.
266 * If there are multiple _distilled_ types with the same
267 * name (a very unlikely scenario), that doesn't matter
268 * unless corresponding _base_ types to match them are
271 base_info.needs_size = base_name_cnt[base_t->name_off] > 1;
272 base_info.size = base_t->size;
277 /* iterate over all matching distilled base types */
278 for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types);
279 dist_info != NULL && dist_info < info_end &&
280 cmp_btf_name_size(&base_info, dist_info) == 0;
282 if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) {
283 pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
288 dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id);
289 dist_kind = btf_kind(dist_t);
291 /* Validate that the found distilled type is compatible.
292 * Do not error out on mismatch as another match may
293 * occur for an identically-named type.
299 if (btf_kflag(dist_t) != btf_kflag(base_t))
302 case BTF_KIND_STRUCT:
303 if (btf_kflag(base_t))
307 if (!btf_kflag(base_t))
315 if (dist_kind != base_kind ||
316 btf_int_encoding(base_t) != btf_int_encoding(dist_t))
320 if (dist_kind != base_kind)
324 /* ENUM and ENUM64 are encoded as sized ENUM in
325 * distilled base BTF.
327 if (base_kind != dist_kind && base_kind != BTF_KIND_ENUM64)
330 case BTF_KIND_STRUCT:
332 /* size verification is required for embedded
335 if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED &&
336 base_t->size != dist_t->size)
342 if (r->id_map[dist_info->id] &&
343 r->id_map[dist_info->id] != BTF_IS_EMBEDDED) {
344 /* we already have a match; this tells us that
345 * multiple base types of the same name
346 * have the same size, since for cases where
347 * multiple types have the same name we match
348 * on name and size. In this case, we have
349 * no way of determining which to relocate
350 * to in base BTF, so error out.
352 pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
353 base_info.name, dist_info->id,
354 base_t->size, id, r->id_map[dist_info->id]);
358 /* map id and name */
359 r->id_map[dist_info->id] = id;
360 r->str_map[dist_t->name_off] = base_t->name_off;
363 /* ensure all distilled BTF ids now have a mapping... */
364 for (id = 1; id < r->nr_dist_base_types; id++) {
367 if (r->id_map[id] && r->id_map[id] != BTF_IS_EMBEDDED)
369 dist_t = btf_type_by_id(r->dist_base_btf, id);
370 name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
371 pr_warn("distilled base BTF type '%s' [%d] is not mapped to base BTF id\n",
382 /* distilled base should only have named int/float/enum/fwd/struct/union types. */
383 static int btf_relocate_validate_distilled_base(struct btf_relocate *r)
387 for (i = 1; i < r->nr_dist_base_types; i++) {
388 struct btf_type *t = btf_type_by_id(r->dist_base_btf, i);
389 int kind = btf_kind(t);
395 case BTF_KIND_STRUCT:
400 pr_warn("type [%d], kind [%d] is invalid for distilled base BTF; it is anonymous\n",
404 pr_warn("type [%d] in distilled based BTF has unexpected kind [%d]\n",
412 static int btf_relocate_rewrite_strs(struct btf_relocate *r, __u32 i)
414 struct btf_type *t = btf_type_by_id(r->btf, i);
415 struct btf_field_iter it;
419 err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
423 while ((str_off = btf_field_iter_next(&it))) {
426 if (*str_off >= r->dist_str_len) {
427 *str_off += r->base_str_len - r->dist_str_len;
429 off = r->str_map[*str_off];
431 pr_warn("string '%s' [offset %u] is not mapped to base BTF\n",
432 btf__str_by_offset(r->btf, off), *str_off);
441 /* If successful, output of relocation is updated BTF with base BTF pointing
442 * at base_btf, and type ids, strings adjusted accordingly.
444 int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **id_map)
446 unsigned int nr_types = btf__type_cnt(btf);
447 const struct btf_header *dist_base_hdr;
448 const struct btf_header *base_hdr;
449 struct btf_relocate r = {};
453 r.dist_base_btf = btf__base_btf(btf);
454 if (!base_btf || r.dist_base_btf == base_btf)
457 r.nr_dist_base_types = btf__type_cnt(r.dist_base_btf);
458 r.nr_base_types = btf__type_cnt(base_btf);
459 r.nr_split_types = nr_types - r.nr_dist_base_types;
461 r.base_btf = base_btf;
463 r.id_map = calloc(nr_types, sizeof(*r.id_map));
464 r.str_map = calloc(btf_header(r.dist_base_btf)->str_len, sizeof(*r.str_map));
465 dist_base_hdr = btf_header(r.dist_base_btf);
466 base_hdr = btf_header(r.base_btf);
467 r.dist_str_len = dist_base_hdr->str_len;
468 r.base_str_len = base_hdr->str_len;
469 if (!r.id_map || !r.str_map) {
474 err = btf_relocate_validate_distilled_base(&r);
478 /* Split BTF ids need to be adjusted as base and distilled base
479 * have different numbers of types, changing the start id of split
482 for (id = r.nr_dist_base_types; id < nr_types; id++)
483 r.id_map[id] = id + r.nr_base_types - r.nr_dist_base_types;
485 /* Build a map from distilled base ids to actual base BTF ids; it is used
486 * to update split BTF id references. Also build a str_map mapping from
487 * distilled base BTF names to base BTF names.
489 err = btf_relocate_map_distilled_base(&r);
493 /* Next, rewrite type ids in split BTF, replacing split ids with updated
494 * ids based on number of types in base BTF, and base ids with
495 * relocated ids from base_btf.
497 for (i = 0, id = r.nr_dist_base_types; i < r.nr_split_types; i++, id++) {
498 err = btf_relocate_rewrite_type_id(&r, id);
502 /* String offsets now need to be updated using the str_map. */
503 for (i = 0; i < r.nr_split_types; i++) {
504 err = btf_relocate_rewrite_strs(&r, i + r.nr_dist_base_types);
508 /* Finally reset base BTF to be base_btf */
509 btf_set_base_btf(btf, base_btf);