btf_relocate.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
  2. /* Copyright (c) 2024, Oracle and/or its affiliates. */
  3. #ifndef _GNU_SOURCE
  4. #define _GNU_SOURCE
  5. #endif
  6. #ifdef __KERNEL__
  7. #include <linux/bpf.h>
  8. #include <linux/bsearch.h>
  9. #include <linux/btf.h>
  10. #include <linux/sort.h>
  11. #include <linux/string.h>
  12. #include <linux/bpf_verifier.h>
  13. #define btf_type_by_id (struct btf_type *)btf_type_by_id
  14. #define btf__type_cnt btf_nr_types
  15. #define btf__base_btf btf_base_btf
  16. #define btf__name_by_offset btf_name_by_offset
  17. #define btf__str_by_offset btf_str_by_offset
  18. #define btf_kflag btf_type_kflag
  19. #define calloc(nmemb, sz) kvcalloc(nmemb, sz, GFP_KERNEL | __GFP_NOWARN)
  20. #define free(ptr) kvfree(ptr)
  21. #define qsort(base, num, sz, cmp) sort(base, num, sz, cmp, NULL)
  22. #else
  23. #include "btf.h"
  24. #include "bpf.h"
  25. #include "libbpf.h"
  26. #include "libbpf_internal.h"
  27. #endif /* __KERNEL__ */
  28. struct btf;
  29. struct btf_relocate {
  30. struct btf *btf;
  31. const struct btf *base_btf;
  32. const struct btf *dist_base_btf;
  33. unsigned int nr_base_types;
  34. unsigned int nr_split_types;
  35. unsigned int nr_dist_base_types;
  36. int dist_str_len;
  37. int base_str_len;
  38. __u32 *id_map;
  39. __u32 *str_map;
  40. };
  41. /* Set temporarily in relocation id_map if distilled base struct/union is
  42. * embedded in a split BTF struct/union; in such a case, size information must
  43. * match between distilled base BTF and base BTF representation of type.
  44. */
  45. #define BTF_IS_EMBEDDED ((__u32)-1)
  46. /* <name, size, id> triple used in sorting/searching distilled base BTF. */
  47. struct btf_name_info {
  48. const char *name;
  49. /* set when search requires a size match */
  50. bool needs_size: 1;
  51. unsigned int size: 31;
  52. __u32 id;
  53. };
  54. static int btf_relocate_rewrite_type_id(struct btf_relocate *r, __u32 i)
  55. {
  56. struct btf_type *t = btf_type_by_id(r->btf, i);
  57. struct btf_field_iter it;
  58. __u32 *id;
  59. int err;
  60. err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
  61. if (err)
  62. return err;
  63. while ((id = btf_field_iter_next(&it)))
  64. *id = r->id_map[*id];
  65. return 0;
  66. }
  67. /* Simple string comparison used for sorting within BTF, since all distilled
  68. * types are named. If strings match, and size is non-zero for both elements
  69. * fall back to using size for ordering.
  70. */
  71. static int cmp_btf_name_size(const void *n1, const void *n2)
  72. {
  73. const struct btf_name_info *ni1 = n1;
  74. const struct btf_name_info *ni2 = n2;
  75. int name_diff = strcmp(ni1->name, ni2->name);
  76. if (!name_diff && ni1->needs_size && ni2->needs_size)
  77. return ni2->size - ni1->size;
  78. return name_diff;
  79. }
  80. /* Binary search with a small twist; find leftmost element that matches
  81. * so that we can then iterate through all exact matches. So for example
  82. * searching { "a", "bb", "bb", "c" } we would always match on the
  83. * leftmost "bb".
  84. */
  85. static struct btf_name_info *search_btf_name_size(struct btf_name_info *key,
  86. struct btf_name_info *vals,
  87. int nelems)
  88. {
  89. struct btf_name_info *ret = NULL;
  90. int high = nelems - 1;
  91. int low = 0;
  92. while (low <= high) {
  93. int mid = (low + high)/2;
  94. struct btf_name_info *val = &vals[mid];
  95. int diff = cmp_btf_name_size(key, val);
  96. if (diff == 0)
  97. ret = val;
  98. /* even if found, keep searching for leftmost match */
  99. if (diff <= 0)
  100. high = mid - 1;
  101. else
  102. low = mid + 1;
  103. }
  104. return ret;
  105. }
  106. /* If a member of a split BTF struct/union refers to a base BTF
  107. * struct/union, mark that struct/union id temporarily in the id_map
  108. * with BTF_IS_EMBEDDED. Members can be const/restrict/volatile/typedef
  109. * reference types, but if a pointer is encountered, the type is no longer
  110. * considered embedded.
  111. */
  112. static int btf_mark_embedded_composite_type_ids(struct btf_relocate *r, __u32 i)
  113. {
  114. struct btf_type *t = btf_type_by_id(r->btf, i);
  115. struct btf_field_iter it;
  116. __u32 *id;
  117. int err;
  118. if (!btf_is_composite(t))
  119. return 0;
  120. err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_IDS);
  121. if (err)
  122. return err;
  123. while ((id = btf_field_iter_next(&it))) {
  124. __u32 next_id = *id;
  125. while (next_id) {
  126. t = btf_type_by_id(r->btf, next_id);
  127. switch (btf_kind(t)) {
  128. case BTF_KIND_CONST:
  129. case BTF_KIND_RESTRICT:
  130. case BTF_KIND_VOLATILE:
  131. case BTF_KIND_TYPEDEF:
  132. case BTF_KIND_TYPE_TAG:
  133. next_id = t->type;
  134. break;
  135. case BTF_KIND_ARRAY: {
  136. struct btf_array *a = btf_array(t);
  137. next_id = a->type;
  138. break;
  139. }
  140. case BTF_KIND_STRUCT:
  141. case BTF_KIND_UNION:
  142. if (next_id < r->nr_dist_base_types)
  143. r->id_map[next_id] = BTF_IS_EMBEDDED;
  144. next_id = 0;
  145. break;
  146. default:
  147. next_id = 0;
  148. break;
  149. }
  150. }
  151. }
  152. return 0;
  153. }
  154. /* Build a map from distilled base BTF ids to base BTF ids. To do so, iterate
  155. * through base BTF looking up distilled type (using binary search) equivalents.
  156. */
  157. static int btf_relocate_map_distilled_base(struct btf_relocate *r)
  158. {
  159. struct btf_name_info *info, *info_end;
  160. struct btf_type *base_t, *dist_t;
  161. __u8 *base_name_cnt = NULL;
  162. int err = 0;
  163. __u32 id;
  164. /* generate a sort index array of name/type ids sorted by name for
  165. * distilled base BTF to speed name-based lookups.
  166. */
  167. info = calloc(r->nr_dist_base_types, sizeof(*info));
  168. if (!info) {
  169. err = -ENOMEM;
  170. goto done;
  171. }
  172. info_end = info + r->nr_dist_base_types;
  173. for (id = 0; id < r->nr_dist_base_types; id++) {
  174. dist_t = btf_type_by_id(r->dist_base_btf, id);
  175. info[id].name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
  176. info[id].id = id;
  177. info[id].size = dist_t->size;
  178. info[id].needs_size = true;
  179. }
  180. qsort(info, r->nr_dist_base_types, sizeof(*info), cmp_btf_name_size);
  181. /* Mark distilled base struct/union members of split BTF structs/unions
  182. * in id_map with BTF_IS_EMBEDDED; this signals that these types
  183. * need to match both name and size, otherwise embedding the base
  184. * struct/union in the split type is invalid.
  185. */
  186. for (id = r->nr_dist_base_types; id < r->nr_dist_base_types + r->nr_split_types; id++) {
  187. err = btf_mark_embedded_composite_type_ids(r, id);
  188. if (err)
  189. goto done;
  190. }
  191. /* Collect name counts for composite types in base BTF. If multiple
  192. * instances of a struct/union of the same name exist, we need to use
  193. * size to determine which to map to since name alone is ambiguous.
  194. */
  195. base_name_cnt = calloc(r->base_str_len, sizeof(*base_name_cnt));
  196. if (!base_name_cnt) {
  197. err = -ENOMEM;
  198. goto done;
  199. }
  200. for (id = 1; id < r->nr_base_types; id++) {
  201. base_t = btf_type_by_id(r->base_btf, id);
  202. if (!btf_is_composite(base_t) || !base_t->name_off)
  203. continue;
  204. if (base_name_cnt[base_t->name_off] < 255)
  205. base_name_cnt[base_t->name_off]++;
  206. }
  207. /* Now search base BTF for matching distilled base BTF types. */
  208. for (id = 1; id < r->nr_base_types; id++) {
  209. struct btf_name_info *dist_info, base_info = {};
  210. int dist_kind, base_kind;
  211. base_t = btf_type_by_id(r->base_btf, id);
  212. /* distilled base consists of named types only. */
  213. if (!base_t->name_off)
  214. continue;
  215. base_kind = btf_kind(base_t);
  216. base_info.id = id;
  217. base_info.name = btf__name_by_offset(r->base_btf, base_t->name_off);
  218. switch (base_kind) {
  219. case BTF_KIND_INT:
  220. case BTF_KIND_FLOAT:
  221. case BTF_KIND_ENUM:
  222. case BTF_KIND_ENUM64:
  223. /* These types should match both name and size */
  224. base_info.needs_size = true;
  225. base_info.size = base_t->size;
  226. break;
  227. case BTF_KIND_FWD:
  228. /* No size considerations for fwds. */
  229. break;
  230. case BTF_KIND_STRUCT:
  231. case BTF_KIND_UNION:
  232. /* Size only needs to be used for struct/union if there
  233. * are multiple types in base BTF with the same name.
  234. * If there are multiple _distilled_ types with the same
  235. * name (a very unlikely scenario), that doesn't matter
  236. * unless corresponding _base_ types to match them are
  237. * missing.
  238. */
  239. base_info.needs_size = base_name_cnt[base_t->name_off] > 1;
  240. base_info.size = base_t->size;
  241. break;
  242. default:
  243. continue;
  244. }
  245. /* iterate over all matching distilled base types */
  246. for (dist_info = search_btf_name_size(&base_info, info, r->nr_dist_base_types);
  247. dist_info != NULL && dist_info < info_end &&
  248. cmp_btf_name_size(&base_info, dist_info) == 0;
  249. dist_info++) {
  250. if (!dist_info->id || dist_info->id >= r->nr_dist_base_types) {
  251. pr_warn("base BTF id [%d] maps to invalid distilled base BTF id [%d]\n",
  252. id, dist_info->id);
  253. err = -EINVAL;
  254. goto done;
  255. }
  256. dist_t = btf_type_by_id(r->dist_base_btf, dist_info->id);
  257. dist_kind = btf_kind(dist_t);
  258. /* Validate that the found distilled type is compatible.
  259. * Do not error out on mismatch as another match may
  260. * occur for an identically-named type.
  261. */
  262. switch (dist_kind) {
  263. case BTF_KIND_FWD:
  264. switch (base_kind) {
  265. case BTF_KIND_FWD:
  266. if (btf_kflag(dist_t) != btf_kflag(base_t))
  267. continue;
  268. break;
  269. case BTF_KIND_STRUCT:
  270. if (btf_kflag(base_t))
  271. continue;
  272. break;
  273. case BTF_KIND_UNION:
  274. if (!btf_kflag(base_t))
  275. continue;
  276. break;
  277. default:
  278. continue;
  279. }
  280. break;
  281. case BTF_KIND_INT:
  282. if (dist_kind != base_kind ||
  283. btf_int_encoding(base_t) != btf_int_encoding(dist_t))
  284. continue;
  285. break;
  286. case BTF_KIND_FLOAT:
  287. if (dist_kind != base_kind)
  288. continue;
  289. break;
  290. case BTF_KIND_ENUM:
  291. /* ENUM and ENUM64 are encoded as sized ENUM in
  292. * distilled base BTF.
  293. */
  294. if (base_kind != dist_kind && base_kind != BTF_KIND_ENUM64)
  295. continue;
  296. break;
  297. case BTF_KIND_STRUCT:
  298. case BTF_KIND_UNION:
  299. /* size verification is required for embedded
  300. * struct/unions.
  301. */
  302. if (r->id_map[dist_info->id] == BTF_IS_EMBEDDED &&
  303. base_t->size != dist_t->size)
  304. continue;
  305. break;
  306. default:
  307. continue;
  308. }
  309. if (r->id_map[dist_info->id] &&
  310. r->id_map[dist_info->id] != BTF_IS_EMBEDDED) {
  311. /* we already have a match; this tells us that
  312. * multiple base types of the same name
  313. * have the same size, since for cases where
  314. * multiple types have the same name we match
  315. * on name and size. In this case, we have
  316. * no way of determining which to relocate
  317. * to in base BTF, so error out.
  318. */
  319. pr_warn("distilled base BTF type '%s' [%u], size %u has multiple candidates of the same size (ids [%u, %u]) in base BTF\n",
  320. base_info.name, dist_info->id,
  321. base_t->size, id, r->id_map[dist_info->id]);
  322. err = -EINVAL;
  323. goto done;
  324. }
  325. /* map id and name */
  326. r->id_map[dist_info->id] = id;
  327. r->str_map[dist_t->name_off] = base_t->name_off;
  328. }
  329. }
  330. /* ensure all distilled BTF ids now have a mapping... */
  331. for (id = 1; id < r->nr_dist_base_types; id++) {
  332. const char *name;
  333. if (r->id_map[id] && r->id_map[id] != BTF_IS_EMBEDDED)
  334. continue;
  335. dist_t = btf_type_by_id(r->dist_base_btf, id);
  336. name = btf__name_by_offset(r->dist_base_btf, dist_t->name_off);
  337. pr_warn("distilled base BTF type '%s' [%d] is not mapped to base BTF id\n",
  338. name, id);
  339. err = -EINVAL;
  340. break;
  341. }
  342. done:
  343. free(base_name_cnt);
  344. free(info);
  345. return err;
  346. }
  347. /* distilled base should only have named int/float/enum/fwd/struct/union types. */
  348. static int btf_relocate_validate_distilled_base(struct btf_relocate *r)
  349. {
  350. unsigned int i;
  351. for (i = 1; i < r->nr_dist_base_types; i++) {
  352. struct btf_type *t = btf_type_by_id(r->dist_base_btf, i);
  353. int kind = btf_kind(t);
  354. switch (kind) {
  355. case BTF_KIND_INT:
  356. case BTF_KIND_FLOAT:
  357. case BTF_KIND_ENUM:
  358. case BTF_KIND_STRUCT:
  359. case BTF_KIND_UNION:
  360. case BTF_KIND_FWD:
  361. if (t->name_off)
  362. break;
  363. pr_warn("type [%d], kind [%d] is invalid for distilled base BTF; it is anonymous\n",
  364. i, kind);
  365. return -EINVAL;
  366. default:
  367. pr_warn("type [%d] in distilled based BTF has unexpected kind [%d]\n",
  368. i, kind);
  369. return -EINVAL;
  370. }
  371. }
  372. return 0;
  373. }
  374. static int btf_relocate_rewrite_strs(struct btf_relocate *r, __u32 i)
  375. {
  376. struct btf_type *t = btf_type_by_id(r->btf, i);
  377. struct btf_field_iter it;
  378. __u32 *str_off;
  379. int off, err;
  380. err = btf_field_iter_init(&it, t, BTF_FIELD_ITER_STRS);
  381. if (err)
  382. return err;
  383. while ((str_off = btf_field_iter_next(&it))) {
  384. if (!*str_off)
  385. continue;
  386. if (*str_off >= r->dist_str_len) {
  387. *str_off += r->base_str_len - r->dist_str_len;
  388. } else {
  389. off = r->str_map[*str_off];
  390. if (!off) {
  391. pr_warn("string '%s' [offset %u] is not mapped to base BTF\n",
  392. btf__str_by_offset(r->btf, off), *str_off);
  393. return -ENOENT;
  394. }
  395. *str_off = off;
  396. }
  397. }
  398. return 0;
  399. }
  400. /* If successful, output of relocation is updated BTF with base BTF pointing
  401. * at base_btf, and type ids, strings adjusted accordingly.
  402. */
  403. int btf_relocate(struct btf *btf, const struct btf *base_btf, __u32 **id_map)
  404. {
  405. unsigned int nr_types = btf__type_cnt(btf);
  406. const struct btf_header *dist_base_hdr;
  407. const struct btf_header *base_hdr;
  408. struct btf_relocate r = {};
  409. int err = 0;
  410. __u32 id, i;
  411. r.dist_base_btf = btf__base_btf(btf);
  412. if (!base_btf || r.dist_base_btf == base_btf)
  413. return -EINVAL;
  414. r.nr_dist_base_types = btf__type_cnt(r.dist_base_btf);
  415. r.nr_base_types = btf__type_cnt(base_btf);
  416. r.nr_split_types = nr_types - r.nr_dist_base_types;
  417. r.btf = btf;
  418. r.base_btf = base_btf;
  419. r.id_map = calloc(nr_types, sizeof(*r.id_map));
  420. r.str_map = calloc(btf_header(r.dist_base_btf)->str_len, sizeof(*r.str_map));
  421. dist_base_hdr = btf_header(r.dist_base_btf);
  422. base_hdr = btf_header(r.base_btf);
  423. r.dist_str_len = dist_base_hdr->str_len;
  424. r.base_str_len = base_hdr->str_len;
  425. if (!r.id_map || !r.str_map) {
  426. err = -ENOMEM;
  427. goto err_out;
  428. }
  429. err = btf_relocate_validate_distilled_base(&r);
  430. if (err)
  431. goto err_out;
  432. /* Split BTF ids need to be adjusted as base and distilled base
  433. * have different numbers of types, changing the start id of split
  434. * BTF.
  435. */
  436. for (id = r.nr_dist_base_types; id < nr_types; id++)
  437. r.id_map[id] = id + r.nr_base_types - r.nr_dist_base_types;
  438. /* Build a map from distilled base ids to actual base BTF ids; it is used
  439. * to update split BTF id references. Also build a str_map mapping from
  440. * distilled base BTF names to base BTF names.
  441. */
  442. err = btf_relocate_map_distilled_base(&r);
  443. if (err)
  444. goto err_out;
  445. /* Next, rewrite type ids in split BTF, replacing split ids with updated
  446. * ids based on number of types in base BTF, and base ids with
  447. * relocated ids from base_btf.
  448. */
  449. for (i = 0, id = r.nr_dist_base_types; i < r.nr_split_types; i++, id++) {
  450. err = btf_relocate_rewrite_type_id(&r, id);
  451. if (err)
  452. goto err_out;
  453. }
  454. /* String offsets now need to be updated using the str_map. */
  455. for (i = 0; i < r.nr_split_types; i++) {
  456. err = btf_relocate_rewrite_strs(&r, i + r.nr_dist_base_types);
  457. if (err)
  458. goto err_out;
  459. }
  460. /* Finally reset base BTF to be base_btf */
  461. btf_set_base_btf(btf, base_btf);
  462. if (id_map) {
  463. *id_map = r.id_map;
  464. r.id_map = NULL;
  465. }
  466. err_out:
  467. free(r.id_map);
  468. free(r.str_map);
  469. return err;
  470. }