diff options
Diffstat (limited to 'tools/lib/bpf/btf.c')
-rw-r--r-- | tools/lib/bpf/btf.c | 329 |
1 files changed, 213 insertions, 116 deletions
diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c index 03348c4d6bd4..b2478e98c367 100644 --- a/tools/lib/bpf/btf.c +++ b/tools/lib/bpf/btf.c | |||
@@ -4,14 +4,17 @@ | |||
4 | #include <stdio.h> | 4 | #include <stdio.h> |
5 | #include <stdlib.h> | 5 | #include <stdlib.h> |
6 | #include <string.h> | 6 | #include <string.h> |
7 | #include <fcntl.h> | ||
7 | #include <unistd.h> | 8 | #include <unistd.h> |
8 | #include <errno.h> | 9 | #include <errno.h> |
9 | #include <linux/err.h> | 10 | #include <linux/err.h> |
10 | #include <linux/btf.h> | 11 | #include <linux/btf.h> |
12 | #include <gelf.h> | ||
11 | #include "btf.h" | 13 | #include "btf.h" |
12 | #include "bpf.h" | 14 | #include "bpf.h" |
13 | #include "libbpf.h" | 15 | #include "libbpf.h" |
14 | #include "libbpf_internal.h" | 16 | #include "libbpf_internal.h" |
17 | #include "hashmap.h" | ||
15 | 18 | ||
16 | #define max(a, b) ((a) > (b) ? (a) : (b)) | 19 | #define max(a, b) ((a) > (b) ? (a) : (b)) |
17 | #define min(a, b) ((a) < (b) ? (a) : (b)) | 20 | #define min(a, b) ((a) < (b) ? (a) : (b)) |
@@ -417,6 +420,132 @@ done: | |||
417 | return btf; | 420 | return btf; |
418 | } | 421 | } |
419 | 422 | ||
423 | static bool btf_check_endianness(const GElf_Ehdr *ehdr) | ||
424 | { | ||
425 | #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ | ||
426 | return ehdr->e_ident[EI_DATA] == ELFDATA2LSB; | ||
427 | #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ | ||
428 | return ehdr->e_ident[EI_DATA] == ELFDATA2MSB; | ||
429 | #else | ||
430 | # error "Unrecognized __BYTE_ORDER__" | ||
431 | #endif | ||
432 | } | ||
433 | |||
434 | struct btf *btf__parse_elf(const char *path, struct btf_ext **btf_ext) | ||
435 | { | ||
436 | Elf_Data *btf_data = NULL, *btf_ext_data = NULL; | ||
437 | int err = 0, fd = -1, idx = 0; | ||
438 | struct btf *btf = NULL; | ||
439 | Elf_Scn *scn = NULL; | ||
440 | Elf *elf = NULL; | ||
441 | GElf_Ehdr ehdr; | ||
442 | |||
443 | if (elf_version(EV_CURRENT) == EV_NONE) { | ||
444 | pr_warning("failed to init libelf for %s\n", path); | ||
445 | return ERR_PTR(-LIBBPF_ERRNO__LIBELF); | ||
446 | } | ||
447 | |||
448 | fd = open(path, O_RDONLY); | ||
449 | if (fd < 0) { | ||
450 | err = -errno; | ||
451 | pr_warning("failed to open %s: %s\n", path, strerror(errno)); | ||
452 | return ERR_PTR(err); | ||
453 | } | ||
454 | |||
455 | err = -LIBBPF_ERRNO__FORMAT; | ||
456 | |||
457 | elf = elf_begin(fd, ELF_C_READ, NULL); | ||
458 | if (!elf) { | ||
459 | pr_warning("failed to open %s as ELF file\n", path); | ||
460 | goto done; | ||
461 | } | ||
462 | if (!gelf_getehdr(elf, &ehdr)) { | ||
463 | pr_warning("failed to get EHDR from %s\n", path); | ||
464 | goto done; | ||
465 | } | ||
466 | if (!btf_check_endianness(&ehdr)) { | ||
467 | pr_warning("non-native ELF endianness is not supported\n"); | ||
468 | goto done; | ||
469 | } | ||
470 | if (!elf_rawdata(elf_getscn(elf, ehdr.e_shstrndx), NULL)) { | ||
471 | pr_warning("failed to get e_shstrndx from %s\n", path); | ||
472 | goto done; | ||
473 | } | ||
474 | |||
475 | while ((scn = elf_nextscn(elf, scn)) != NULL) { | ||
476 | GElf_Shdr sh; | ||
477 | char *name; | ||
478 | |||
479 | idx++; | ||
480 | if (gelf_getshdr(scn, &sh) != &sh) { | ||
481 | pr_warning("failed to get section(%d) header from %s\n", | ||
482 | idx, path); | ||
483 | goto done; | ||
484 | } | ||
485 | name = elf_strptr(elf, ehdr.e_shstrndx, sh.sh_name); | ||
486 | if (!name) { | ||
487 | pr_warning("failed to get section(%d) name from %s\n", | ||
488 | idx, path); | ||
489 | goto done; | ||
490 | } | ||
491 | if (strcmp(name, BTF_ELF_SEC) == 0) { | ||
492 | btf_data = elf_getdata(scn, 0); | ||
493 | if (!btf_data) { | ||
494 | pr_warning("failed to get section(%d, %s) data from %s\n", | ||
495 | idx, name, path); | ||
496 | goto done; | ||
497 | } | ||
498 | continue; | ||
499 | } else if (btf_ext && strcmp(name, BTF_EXT_ELF_SEC) == 0) { | ||
500 | btf_ext_data = elf_getdata(scn, 0); | ||
501 | if (!btf_ext_data) { | ||
502 | pr_warning("failed to get section(%d, %s) data from %s\n", | ||
503 | idx, name, path); | ||
504 | goto done; | ||
505 | } | ||
506 | continue; | ||
507 | } | ||
508 | } | ||
509 | |||
510 | err = 0; | ||
511 | |||
512 | if (!btf_data) { | ||
513 | err = -ENOENT; | ||
514 | goto done; | ||
515 | } | ||
516 | btf = btf__new(btf_data->d_buf, btf_data->d_size); | ||
517 | if (IS_ERR(btf)) | ||
518 | goto done; | ||
519 | |||
520 | if (btf_ext && btf_ext_data) { | ||
521 | *btf_ext = btf_ext__new(btf_ext_data->d_buf, | ||
522 | btf_ext_data->d_size); | ||
523 | if (IS_ERR(*btf_ext)) | ||
524 | goto done; | ||
525 | } else if (btf_ext) { | ||
526 | *btf_ext = NULL; | ||
527 | } | ||
528 | done: | ||
529 | if (elf) | ||
530 | elf_end(elf); | ||
531 | close(fd); | ||
532 | |||
533 | if (err) | ||
534 | return ERR_PTR(err); | ||
535 | /* | ||
536 | * btf is always parsed before btf_ext, so no need to clean up | ||
537 | * btf_ext, if btf loading failed | ||
538 | */ | ||
539 | if (IS_ERR(btf)) | ||
540 | return btf; | ||
541 | if (btf_ext && IS_ERR(*btf_ext)) { | ||
542 | btf__free(btf); | ||
543 | err = PTR_ERR(*btf_ext); | ||
544 | return ERR_PTR(err); | ||
545 | } | ||
546 | return btf; | ||
547 | } | ||
548 | |||
420 | static int compare_vsi_off(const void *_a, const void *_b) | 549 | static int compare_vsi_off(const void *_a, const void *_b) |
421 | { | 550 | { |
422 | const struct btf_var_secinfo *a = _a; | 551 | const struct btf_var_secinfo *a = _a; |
@@ -1165,16 +1294,9 @@ done: | |||
1165 | return err; | 1294 | return err; |
1166 | } | 1295 | } |
1167 | 1296 | ||
1168 | #define BTF_DEDUP_TABLE_DEFAULT_SIZE (1 << 14) | ||
1169 | #define BTF_DEDUP_TABLE_MAX_SIZE_LOG 31 | ||
1170 | #define BTF_UNPROCESSED_ID ((__u32)-1) | 1297 | #define BTF_UNPROCESSED_ID ((__u32)-1) |
1171 | #define BTF_IN_PROGRESS_ID ((__u32)-2) | 1298 | #define BTF_IN_PROGRESS_ID ((__u32)-2) |
1172 | 1299 | ||
1173 | struct btf_dedup_node { | ||
1174 | struct btf_dedup_node *next; | ||
1175 | __u32 type_id; | ||
1176 | }; | ||
1177 | |||
1178 | struct btf_dedup { | 1300 | struct btf_dedup { |
1179 | /* .BTF section to be deduped in-place */ | 1301 | /* .BTF section to be deduped in-place */ |
1180 | struct btf *btf; | 1302 | struct btf *btf; |
@@ -1190,7 +1312,7 @@ struct btf_dedup { | |||
1190 | * candidates, which is fine because we rely on subsequent | 1312 | * candidates, which is fine because we rely on subsequent |
1191 | * btf_xxx_equal() checks to authoritatively verify type equality. | 1313 | * btf_xxx_equal() checks to authoritatively verify type equality. |
1192 | */ | 1314 | */ |
1193 | struct btf_dedup_node **dedup_table; | 1315 | struct hashmap *dedup_table; |
1194 | /* Canonical types map */ | 1316 | /* Canonical types map */ |
1195 | __u32 *map; | 1317 | __u32 *map; |
1196 | /* Hypothetical mapping, used during type graph equivalence checks */ | 1318 | /* Hypothetical mapping, used during type graph equivalence checks */ |
@@ -1215,30 +1337,18 @@ struct btf_str_ptrs { | |||
1215 | __u32 cap; | 1337 | __u32 cap; |
1216 | }; | 1338 | }; |
1217 | 1339 | ||
1218 | static inline __u32 hash_combine(__u32 h, __u32 value) | 1340 | static long hash_combine(long h, long value) |
1219 | { | 1341 | { |
1220 | /* 2^31 + 2^29 - 2^25 + 2^22 - 2^19 - 2^16 + 1 */ | 1342 | return h * 31 + value; |
1221 | #define GOLDEN_RATIO_PRIME 0x9e370001UL | ||
1222 | return h * 37 + value * GOLDEN_RATIO_PRIME; | ||
1223 | #undef GOLDEN_RATIO_PRIME | ||
1224 | } | 1343 | } |
1225 | 1344 | ||
1226 | #define for_each_dedup_cand(d, hash, node) \ | 1345 | #define for_each_dedup_cand(d, node, hash) \ |
1227 | for (node = d->dedup_table[hash & (d->opts.dedup_table_size - 1)]; \ | 1346 | hashmap__for_each_key_entry(d->dedup_table, node, (void *)hash) |
1228 | node; \ | ||
1229 | node = node->next) | ||
1230 | 1347 | ||
1231 | static int btf_dedup_table_add(struct btf_dedup *d, __u32 hash, __u32 type_id) | 1348 | static int btf_dedup_table_add(struct btf_dedup *d, long hash, __u32 type_id) |
1232 | { | 1349 | { |
1233 | struct btf_dedup_node *node = malloc(sizeof(struct btf_dedup_node)); | 1350 | return hashmap__append(d->dedup_table, |
1234 | int bucket = hash & (d->opts.dedup_table_size - 1); | 1351 | (void *)hash, (void *)(long)type_id); |
1235 | |||
1236 | if (!node) | ||
1237 | return -ENOMEM; | ||
1238 | node->type_id = type_id; | ||
1239 | node->next = d->dedup_table[bucket]; | ||
1240 | d->dedup_table[bucket] = node; | ||
1241 | return 0; | ||
1242 | } | 1352 | } |
1243 | 1353 | ||
1244 | static int btf_dedup_hypot_map_add(struct btf_dedup *d, | 1354 | static int btf_dedup_hypot_map_add(struct btf_dedup *d, |
@@ -1267,36 +1377,10 @@ static void btf_dedup_clear_hypot_map(struct btf_dedup *d) | |||
1267 | d->hypot_cnt = 0; | 1377 | d->hypot_cnt = 0; |
1268 | } | 1378 | } |
1269 | 1379 | ||
1270 | static void btf_dedup_table_free(struct btf_dedup *d) | ||
1271 | { | ||
1272 | struct btf_dedup_node *head, *tmp; | ||
1273 | int i; | ||
1274 | |||
1275 | if (!d->dedup_table) | ||
1276 | return; | ||
1277 | |||
1278 | for (i = 0; i < d->opts.dedup_table_size; i++) { | ||
1279 | while (d->dedup_table[i]) { | ||
1280 | tmp = d->dedup_table[i]; | ||
1281 | d->dedup_table[i] = tmp->next; | ||
1282 | free(tmp); | ||
1283 | } | ||
1284 | |||
1285 | head = d->dedup_table[i]; | ||
1286 | while (head) { | ||
1287 | tmp = head; | ||
1288 | head = head->next; | ||
1289 | free(tmp); | ||
1290 | } | ||
1291 | } | ||
1292 | |||
1293 | free(d->dedup_table); | ||
1294 | d->dedup_table = NULL; | ||
1295 | } | ||
1296 | |||
1297 | static void btf_dedup_free(struct btf_dedup *d) | 1380 | static void btf_dedup_free(struct btf_dedup *d) |
1298 | { | 1381 | { |
1299 | btf_dedup_table_free(d); | 1382 | hashmap__free(d->dedup_table); |
1383 | d->dedup_table = NULL; | ||
1300 | 1384 | ||
1301 | free(d->map); | 1385 | free(d->map); |
1302 | d->map = NULL; | 1386 | d->map = NULL; |
@@ -1310,40 +1394,43 @@ static void btf_dedup_free(struct btf_dedup *d) | |||
1310 | free(d); | 1394 | free(d); |
1311 | } | 1395 | } |
1312 | 1396 | ||
1313 | /* Find closest power of two >= to size, capped at 2^max_size_log */ | 1397 | static size_t btf_dedup_identity_hash_fn(const void *key, void *ctx) |
1314 | static __u32 roundup_pow2_max(__u32 size, int max_size_log) | ||
1315 | { | 1398 | { |
1316 | int i; | 1399 | return (size_t)key; |
1400 | } | ||
1317 | 1401 | ||
1318 | for (i = 0; i < max_size_log && (1U << i) < size; i++) | 1402 | static size_t btf_dedup_collision_hash_fn(const void *key, void *ctx) |
1319 | ; | 1403 | { |
1320 | return 1U << i; | 1404 | return 0; |
1321 | } | 1405 | } |
1322 | 1406 | ||
1407 | static bool btf_dedup_equal_fn(const void *k1, const void *k2, void *ctx) | ||
1408 | { | ||
1409 | return k1 == k2; | ||
1410 | } | ||
1323 | 1411 | ||
1324 | static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext, | 1412 | static struct btf_dedup *btf_dedup_new(struct btf *btf, struct btf_ext *btf_ext, |
1325 | const struct btf_dedup_opts *opts) | 1413 | const struct btf_dedup_opts *opts) |
1326 | { | 1414 | { |
1327 | struct btf_dedup *d = calloc(1, sizeof(struct btf_dedup)); | 1415 | struct btf_dedup *d = calloc(1, sizeof(struct btf_dedup)); |
1416 | hashmap_hash_fn hash_fn = btf_dedup_identity_hash_fn; | ||
1328 | int i, err = 0; | 1417 | int i, err = 0; |
1329 | __u32 sz; | ||
1330 | 1418 | ||
1331 | if (!d) | 1419 | if (!d) |
1332 | return ERR_PTR(-ENOMEM); | 1420 | return ERR_PTR(-ENOMEM); |
1333 | 1421 | ||
1334 | d->opts.dont_resolve_fwds = opts && opts->dont_resolve_fwds; | 1422 | d->opts.dont_resolve_fwds = opts && opts->dont_resolve_fwds; |
1335 | sz = opts && opts->dedup_table_size ? opts->dedup_table_size | 1423 | /* dedup_table_size is now used only to force collisions in tests */ |
1336 | : BTF_DEDUP_TABLE_DEFAULT_SIZE; | 1424 | if (opts && opts->dedup_table_size == 1) |
1337 | sz = roundup_pow2_max(sz, BTF_DEDUP_TABLE_MAX_SIZE_LOG); | 1425 | hash_fn = btf_dedup_collision_hash_fn; |
1338 | d->opts.dedup_table_size = sz; | ||
1339 | 1426 | ||
1340 | d->btf = btf; | 1427 | d->btf = btf; |
1341 | d->btf_ext = btf_ext; | 1428 | d->btf_ext = btf_ext; |
1342 | 1429 | ||
1343 | d->dedup_table = calloc(d->opts.dedup_table_size, | 1430 | d->dedup_table = hashmap__new(hash_fn, btf_dedup_equal_fn, NULL); |
1344 | sizeof(struct btf_dedup_node *)); | 1431 | if (IS_ERR(d->dedup_table)) { |
1345 | if (!d->dedup_table) { | 1432 | err = PTR_ERR(d->dedup_table); |
1346 | err = -ENOMEM; | 1433 | d->dedup_table = NULL; |
1347 | goto done; | 1434 | goto done; |
1348 | } | 1435 | } |
1349 | 1436 | ||
@@ -1662,9 +1749,9 @@ done: | |||
1662 | return err; | 1749 | return err; |
1663 | } | 1750 | } |
1664 | 1751 | ||
1665 | static __u32 btf_hash_common(struct btf_type *t) | 1752 | static long btf_hash_common(struct btf_type *t) |
1666 | { | 1753 | { |
1667 | __u32 h; | 1754 | long h; |
1668 | 1755 | ||
1669 | h = hash_combine(0, t->name_off); | 1756 | h = hash_combine(0, t->name_off); |
1670 | h = hash_combine(h, t->info); | 1757 | h = hash_combine(h, t->info); |
@@ -1680,10 +1767,10 @@ static bool btf_equal_common(struct btf_type *t1, struct btf_type *t2) | |||
1680 | } | 1767 | } |
1681 | 1768 | ||
1682 | /* Calculate type signature hash of INT. */ | 1769 | /* Calculate type signature hash of INT. */ |
1683 | static __u32 btf_hash_int(struct btf_type *t) | 1770 | static long btf_hash_int(struct btf_type *t) |
1684 | { | 1771 | { |
1685 | __u32 info = *(__u32 *)(t + 1); | 1772 | __u32 info = *(__u32 *)(t + 1); |
1686 | __u32 h; | 1773 | long h; |
1687 | 1774 | ||
1688 | h = btf_hash_common(t); | 1775 | h = btf_hash_common(t); |
1689 | h = hash_combine(h, info); | 1776 | h = hash_combine(h, info); |
@@ -1703,9 +1790,9 @@ static bool btf_equal_int(struct btf_type *t1, struct btf_type *t2) | |||
1703 | } | 1790 | } |
1704 | 1791 | ||
1705 | /* Calculate type signature hash of ENUM. */ | 1792 | /* Calculate type signature hash of ENUM. */ |
1706 | static __u32 btf_hash_enum(struct btf_type *t) | 1793 | static long btf_hash_enum(struct btf_type *t) |
1707 | { | 1794 | { |
1708 | __u32 h; | 1795 | long h; |
1709 | 1796 | ||
1710 | /* don't hash vlen and enum members to support enum fwd resolving */ | 1797 | /* don't hash vlen and enum members to support enum fwd resolving */ |
1711 | h = hash_combine(0, t->name_off); | 1798 | h = hash_combine(0, t->name_off); |
@@ -1757,11 +1844,11 @@ static bool btf_compat_enum(struct btf_type *t1, struct btf_type *t2) | |||
1757 | * as referenced type IDs equivalence is established separately during type | 1844 | * as referenced type IDs equivalence is established separately during type |
1758 | * graph equivalence check algorithm. | 1845 | * graph equivalence check algorithm. |
1759 | */ | 1846 | */ |
1760 | static __u32 btf_hash_struct(struct btf_type *t) | 1847 | static long btf_hash_struct(struct btf_type *t) |
1761 | { | 1848 | { |
1762 | struct btf_member *member = (struct btf_member *)(t + 1); | 1849 | struct btf_member *member = (struct btf_member *)(t + 1); |
1763 | __u32 vlen = BTF_INFO_VLEN(t->info); | 1850 | __u32 vlen = BTF_INFO_VLEN(t->info); |
1764 | __u32 h = btf_hash_common(t); | 1851 | long h = btf_hash_common(t); |
1765 | int i; | 1852 | int i; |
1766 | 1853 | ||
1767 | for (i = 0; i < vlen; i++) { | 1854 | for (i = 0; i < vlen; i++) { |
@@ -1804,10 +1891,10 @@ static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2) | |||
1804 | * under assumption that they were already resolved to canonical type IDs and | 1891 | * under assumption that they were already resolved to canonical type IDs and |
1805 | * are not going to change. | 1892 | * are not going to change. |
1806 | */ | 1893 | */ |
1807 | static __u32 btf_hash_array(struct btf_type *t) | 1894 | static long btf_hash_array(struct btf_type *t) |
1808 | { | 1895 | { |
1809 | struct btf_array *info = (struct btf_array *)(t + 1); | 1896 | struct btf_array *info = (struct btf_array *)(t + 1); |
1810 | __u32 h = btf_hash_common(t); | 1897 | long h = btf_hash_common(t); |
1811 | 1898 | ||
1812 | h = hash_combine(h, info->type); | 1899 | h = hash_combine(h, info->type); |
1813 | h = hash_combine(h, info->index_type); | 1900 | h = hash_combine(h, info->index_type); |
@@ -1858,11 +1945,11 @@ static bool btf_compat_array(struct btf_type *t1, struct btf_type *t2) | |||
1858 | * under assumption that they were already resolved to canonical type IDs and | 1945 | * under assumption that they were already resolved to canonical type IDs and |
1859 | * are not going to change. | 1946 | * are not going to change. |
1860 | */ | 1947 | */ |
1861 | static inline __u32 btf_hash_fnproto(struct btf_type *t) | 1948 | static long btf_hash_fnproto(struct btf_type *t) |
1862 | { | 1949 | { |
1863 | struct btf_param *member = (struct btf_param *)(t + 1); | 1950 | struct btf_param *member = (struct btf_param *)(t + 1); |
1864 | __u16 vlen = BTF_INFO_VLEN(t->info); | 1951 | __u16 vlen = BTF_INFO_VLEN(t->info); |
1865 | __u32 h = btf_hash_common(t); | 1952 | long h = btf_hash_common(t); |
1866 | int i; | 1953 | int i; |
1867 | 1954 | ||
1868 | for (i = 0; i < vlen; i++) { | 1955 | for (i = 0; i < vlen; i++) { |
@@ -1880,7 +1967,7 @@ static inline __u32 btf_hash_fnproto(struct btf_type *t) | |||
1880 | * This function is called during reference types deduplication to compare | 1967 | * This function is called during reference types deduplication to compare |
1881 | * FUNC_PROTO to potential canonical representative. | 1968 | * FUNC_PROTO to potential canonical representative. |
1882 | */ | 1969 | */ |
1883 | static inline bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2) | 1970 | static bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2) |
1884 | { | 1971 | { |
1885 | struct btf_param *m1, *m2; | 1972 | struct btf_param *m1, *m2; |
1886 | __u16 vlen; | 1973 | __u16 vlen; |
@@ -1906,7 +1993,7 @@ static inline bool btf_equal_fnproto(struct btf_type *t1, struct btf_type *t2) | |||
1906 | * IDs. This check is performed during type graph equivalence check and | 1993 | * IDs. This check is performed during type graph equivalence check and |
1907 | * referenced types equivalence is checked separately. | 1994 | * referenced types equivalence is checked separately. |
1908 | */ | 1995 | */ |
1909 | static inline bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2) | 1996 | static bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2) |
1910 | { | 1997 | { |
1911 | struct btf_param *m1, *m2; | 1998 | struct btf_param *m1, *m2; |
1912 | __u16 vlen; | 1999 | __u16 vlen; |
@@ -1937,11 +2024,12 @@ static inline bool btf_compat_fnproto(struct btf_type *t1, struct btf_type *t2) | |||
1937 | static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) | 2024 | static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) |
1938 | { | 2025 | { |
1939 | struct btf_type *t = d->btf->types[type_id]; | 2026 | struct btf_type *t = d->btf->types[type_id]; |
2027 | struct hashmap_entry *hash_entry; | ||
1940 | struct btf_type *cand; | 2028 | struct btf_type *cand; |
1941 | struct btf_dedup_node *cand_node; | ||
1942 | /* if we don't find equivalent type, then we are canonical */ | 2029 | /* if we don't find equivalent type, then we are canonical */ |
1943 | __u32 new_id = type_id; | 2030 | __u32 new_id = type_id; |
1944 | __u32 h; | 2031 | __u32 cand_id; |
2032 | long h; | ||
1945 | 2033 | ||
1946 | switch (BTF_INFO_KIND(t->info)) { | 2034 | switch (BTF_INFO_KIND(t->info)) { |
1947 | case BTF_KIND_CONST: | 2035 | case BTF_KIND_CONST: |
@@ -1960,10 +2048,11 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) | |||
1960 | 2048 | ||
1961 | case BTF_KIND_INT: | 2049 | case BTF_KIND_INT: |
1962 | h = btf_hash_int(t); | 2050 | h = btf_hash_int(t); |
1963 | for_each_dedup_cand(d, h, cand_node) { | 2051 | for_each_dedup_cand(d, hash_entry, h) { |
1964 | cand = d->btf->types[cand_node->type_id]; | 2052 | cand_id = (__u32)(long)hash_entry->value; |
2053 | cand = d->btf->types[cand_id]; | ||
1965 | if (btf_equal_int(t, cand)) { | 2054 | if (btf_equal_int(t, cand)) { |
1966 | new_id = cand_node->type_id; | 2055 | new_id = cand_id; |
1967 | break; | 2056 | break; |
1968 | } | 2057 | } |
1969 | } | 2058 | } |
@@ -1971,10 +2060,11 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) | |||
1971 | 2060 | ||
1972 | case BTF_KIND_ENUM: | 2061 | case BTF_KIND_ENUM: |
1973 | h = btf_hash_enum(t); | 2062 | h = btf_hash_enum(t); |
1974 | for_each_dedup_cand(d, h, cand_node) { | 2063 | for_each_dedup_cand(d, hash_entry, h) { |
1975 | cand = d->btf->types[cand_node->type_id]; | 2064 | cand_id = (__u32)(long)hash_entry->value; |
2065 | cand = d->btf->types[cand_id]; | ||
1976 | if (btf_equal_enum(t, cand)) { | 2066 | if (btf_equal_enum(t, cand)) { |
1977 | new_id = cand_node->type_id; | 2067 | new_id = cand_id; |
1978 | break; | 2068 | break; |
1979 | } | 2069 | } |
1980 | if (d->opts.dont_resolve_fwds) | 2070 | if (d->opts.dont_resolve_fwds) |
@@ -1982,21 +2072,22 @@ static int btf_dedup_prim_type(struct btf_dedup *d, __u32 type_id) | |||
1982 | if (btf_compat_enum(t, cand)) { | 2072 | if (btf_compat_enum(t, cand)) { |
1983 | if (btf_is_enum_fwd(t)) { | 2073 | if (btf_is_enum_fwd(t)) { |
1984 | /* resolve fwd to full enum */ | 2074 | /* resolve fwd to full enum */ |
1985 | new_id = cand_node->type_id; | 2075 | new_id = cand_id; |
1986 | break; | 2076 | break; |
1987 | } | 2077 | } |
1988 | /* resolve canonical enum fwd to full enum */ | 2078 | /* resolve canonical enum fwd to full enum */ |
1989 | d->map[cand_node->type_id] = type_id; | 2079 | d->map[cand_id] = type_id; |
1990 | } | 2080 | } |
1991 | } | 2081 | } |
1992 | break; | 2082 | break; |
1993 | 2083 | ||
1994 | case BTF_KIND_FWD: | 2084 | case BTF_KIND_FWD: |
1995 | h = btf_hash_common(t); | 2085 | h = btf_hash_common(t); |
1996 | for_each_dedup_cand(d, h, cand_node) { | 2086 | for_each_dedup_cand(d, hash_entry, h) { |
1997 | cand = d->btf->types[cand_node->type_id]; | 2087 | cand_id = (__u32)(long)hash_entry->value; |
2088 | cand = d->btf->types[cand_id]; | ||
1998 | if (btf_equal_common(t, cand)) { | 2089 | if (btf_equal_common(t, cand)) { |
1999 | new_id = cand_node->type_id; | 2090 | new_id = cand_id; |
2000 | break; | 2091 | break; |
2001 | } | 2092 | } |
2002 | } | 2093 | } |
@@ -2397,12 +2488,12 @@ static void btf_dedup_merge_hypot_map(struct btf_dedup *d) | |||
2397 | */ | 2488 | */ |
2398 | static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id) | 2489 | static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id) |
2399 | { | 2490 | { |
2400 | struct btf_dedup_node *cand_node; | ||
2401 | struct btf_type *cand_type, *t; | 2491 | struct btf_type *cand_type, *t; |
2492 | struct hashmap_entry *hash_entry; | ||
2402 | /* if we don't find equivalent type, then we are canonical */ | 2493 | /* if we don't find equivalent type, then we are canonical */ |
2403 | __u32 new_id = type_id; | 2494 | __u32 new_id = type_id; |
2404 | __u16 kind; | 2495 | __u16 kind; |
2405 | __u32 h; | 2496 | long h; |
2406 | 2497 | ||
2407 | /* already deduped or is in process of deduping (loop detected) */ | 2498 | /* already deduped or is in process of deduping (loop detected) */ |
2408 | if (d->map[type_id] <= BTF_MAX_NR_TYPES) | 2499 | if (d->map[type_id] <= BTF_MAX_NR_TYPES) |
@@ -2415,7 +2506,8 @@ static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id) | |||
2415 | return 0; | 2506 | return 0; |
2416 | 2507 | ||
2417 | h = btf_hash_struct(t); | 2508 | h = btf_hash_struct(t); |
2418 | for_each_dedup_cand(d, h, cand_node) { | 2509 | for_each_dedup_cand(d, hash_entry, h) { |
2510 | __u32 cand_id = (__u32)(long)hash_entry->value; | ||
2419 | int eq; | 2511 | int eq; |
2420 | 2512 | ||
2421 | /* | 2513 | /* |
@@ -2428,17 +2520,17 @@ static int btf_dedup_struct_type(struct btf_dedup *d, __u32 type_id) | |||
2428 | * creating a loop (FWD -> STRUCT and STRUCT -> FWD), because | 2520 | * creating a loop (FWD -> STRUCT and STRUCT -> FWD), because |
2429 | * FWD and compatible STRUCT/UNION are considered equivalent. | 2521 | * FWD and compatible STRUCT/UNION are considered equivalent. |
2430 | */ | 2522 | */ |
2431 | cand_type = d->btf->types[cand_node->type_id]; | 2523 | cand_type = d->btf->types[cand_id]; |
2432 | if (!btf_shallow_equal_struct(t, cand_type)) | 2524 | if (!btf_shallow_equal_struct(t, cand_type)) |
2433 | continue; | 2525 | continue; |
2434 | 2526 | ||
2435 | btf_dedup_clear_hypot_map(d); | 2527 | btf_dedup_clear_hypot_map(d); |
2436 | eq = btf_dedup_is_equiv(d, type_id, cand_node->type_id); | 2528 | eq = btf_dedup_is_equiv(d, type_id, cand_id); |
2437 | if (eq < 0) | 2529 | if (eq < 0) |
2438 | return eq; | 2530 | return eq; |
2439 | if (!eq) | 2531 | if (!eq) |
2440 | continue; | 2532 | continue; |
2441 | new_id = cand_node->type_id; | 2533 | new_id = cand_id; |
2442 | btf_dedup_merge_hypot_map(d); | 2534 | btf_dedup_merge_hypot_map(d); |
2443 | break; | 2535 | break; |
2444 | } | 2536 | } |
@@ -2488,12 +2580,12 @@ static int btf_dedup_struct_types(struct btf_dedup *d) | |||
2488 | */ | 2580 | */ |
2489 | static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) | 2581 | static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) |
2490 | { | 2582 | { |
2491 | struct btf_dedup_node *cand_node; | 2583 | struct hashmap_entry *hash_entry; |
2584 | __u32 new_id = type_id, cand_id; | ||
2492 | struct btf_type *t, *cand; | 2585 | struct btf_type *t, *cand; |
2493 | /* if we don't find equivalent type, then we are representative type */ | 2586 | /* if we don't find equivalent type, then we are representative type */ |
2494 | __u32 new_id = type_id; | ||
2495 | int ref_type_id; | 2587 | int ref_type_id; |
2496 | __u32 h; | 2588 | long h; |
2497 | 2589 | ||
2498 | if (d->map[type_id] == BTF_IN_PROGRESS_ID) | 2590 | if (d->map[type_id] == BTF_IN_PROGRESS_ID) |
2499 | return -ELOOP; | 2591 | return -ELOOP; |
@@ -2516,10 +2608,11 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) | |||
2516 | t->type = ref_type_id; | 2608 | t->type = ref_type_id; |
2517 | 2609 | ||
2518 | h = btf_hash_common(t); | 2610 | h = btf_hash_common(t); |
2519 | for_each_dedup_cand(d, h, cand_node) { | 2611 | for_each_dedup_cand(d, hash_entry, h) { |
2520 | cand = d->btf->types[cand_node->type_id]; | 2612 | cand_id = (__u32)(long)hash_entry->value; |
2613 | cand = d->btf->types[cand_id]; | ||
2521 | if (btf_equal_common(t, cand)) { | 2614 | if (btf_equal_common(t, cand)) { |
2522 | new_id = cand_node->type_id; | 2615 | new_id = cand_id; |
2523 | break; | 2616 | break; |
2524 | } | 2617 | } |
2525 | } | 2618 | } |
@@ -2539,10 +2632,11 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) | |||
2539 | info->index_type = ref_type_id; | 2632 | info->index_type = ref_type_id; |
2540 | 2633 | ||
2541 | h = btf_hash_array(t); | 2634 | h = btf_hash_array(t); |
2542 | for_each_dedup_cand(d, h, cand_node) { | 2635 | for_each_dedup_cand(d, hash_entry, h) { |
2543 | cand = d->btf->types[cand_node->type_id]; | 2636 | cand_id = (__u32)(long)hash_entry->value; |
2637 | cand = d->btf->types[cand_id]; | ||
2544 | if (btf_equal_array(t, cand)) { | 2638 | if (btf_equal_array(t, cand)) { |
2545 | new_id = cand_node->type_id; | 2639 | new_id = cand_id; |
2546 | break; | 2640 | break; |
2547 | } | 2641 | } |
2548 | } | 2642 | } |
@@ -2570,10 +2664,11 @@ static int btf_dedup_ref_type(struct btf_dedup *d, __u32 type_id) | |||
2570 | } | 2664 | } |
2571 | 2665 | ||
2572 | h = btf_hash_fnproto(t); | 2666 | h = btf_hash_fnproto(t); |
2573 | for_each_dedup_cand(d, h, cand_node) { | 2667 | for_each_dedup_cand(d, hash_entry, h) { |
2574 | cand = d->btf->types[cand_node->type_id]; | 2668 | cand_id = (__u32)(long)hash_entry->value; |
2669 | cand = d->btf->types[cand_id]; | ||
2575 | if (btf_equal_fnproto(t, cand)) { | 2670 | if (btf_equal_fnproto(t, cand)) { |
2576 | new_id = cand_node->type_id; | 2671 | new_id = cand_id; |
2577 | break; | 2672 | break; |
2578 | } | 2673 | } |
2579 | } | 2674 | } |
@@ -2600,7 +2695,9 @@ static int btf_dedup_ref_types(struct btf_dedup *d) | |||
2600 | if (err < 0) | 2695 | if (err < 0) |
2601 | return err; | 2696 | return err; |
2602 | } | 2697 | } |
2603 | btf_dedup_table_free(d); | 2698 | /* we won't need d->dedup_table anymore */ |
2699 | hashmap__free(d->dedup_table); | ||
2700 | d->dedup_table = NULL; | ||
2604 | return 0; | 2701 | return 0; |
2605 | } | 2702 | } |
2606 | 2703 | ||