1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
4 * resolve_btfids scans ELF object for .BTF_ids section and resolves
5 * its symbols with BTF ID values.
7 * Each symbol points to 4 bytes data and is expected to have
8 * following name syntax:
10 * __BTF_ID__<type>__<symbol>[__<id>]
14 * func - lookup BTF_KIND_FUNC symbol with <symbol> name
15 * and store its ID into the data:
17 * __BTF_ID__func__vfs_close__1:
20 * struct - lookup BTF_KIND_STRUCT symbol with <symbol> name
21 * and store its ID into the data:
23 * __BTF_ID__struct__sk_buff__1:
26 * union - lookup BTF_KIND_UNION symbol with <symbol> name
27 * and store its ID into the data:
29 * __BTF_ID__union__thread_union__1:
32 * typedef - lookup BTF_KIND_TYPEDEF symbol with <symbol> name
33 * and store its ID into the data:
35 * __BTF_ID__typedef__pid_t__1:
38 * set - store symbol size into first 4 bytes and sort following
41 * __BTF_ID__set__list:
44 * __BTF_ID__func__vfs_getattr__3:
46 * __BTF_ID__func__vfs_fallocate__4:
49 * set8 - store symbol size into first 4 bytes and sort following
52 * __BTF_ID__set8__list:
55 * __BTF_ID__func__vfs_getattr__3:
57 * .word (1 << 0) | (1 << 2)
58 * __BTF_ID__func__vfs_fallocate__5:
60 * .word (1 << 3) | (1 << 1) | (1 << 2)
73 #include <linux/btf_ids.h>
74 #include <linux/rbtree.h>
75 #include <linux/zalloc.h>
76 #include <linux/err.h>
78 #include <bpf/libbpf.h>
79 #include <subcmd/parse-options.h>
81 #define BTF_IDS_SECTION ".BTF_ids"
82 #define BTF_ID_PREFIX "__BTF_ID__"
84 #define BTF_STRUCT "struct"
85 #define BTF_UNION "union"
86 #define BTF_TYPEDEF "typedef"
87 #define BTF_FUNC "func"
89 #define BTF_SET8 "set8"
93 #if __BYTE_ORDER == __LITTLE_ENDIAN
94 # define ELFDATANATIVE ELFDATA2LSB
95 #elif __BYTE_ORDER == __BIG_ENDIAN
96 # define ELFDATANATIVE ELFDATA2MSB
98 # error "Unknown machine endianness!"
102 struct rb_node rb_node
;
111 Elf64_Addr addr
[ADDR_CNT
];
117 const char *base_btf_path
;
127 unsigned long idlist_addr
;
132 struct rb_root structs
;
133 struct rb_root unions
;
134 struct rb_root typedefs
;
135 struct rb_root funcs
;
145 static int eprintf(int level
, int var
, const char *fmt
, ...)
152 ret
= vfprintf(stderr
, fmt
, args
);
159 #define pr_fmt(fmt) fmt
162 #define pr_debug(fmt, ...) \
163 eprintf(1, verbose, pr_fmt(fmt), ##__VA_ARGS__)
164 #define pr_debugN(n, fmt, ...) \
165 eprintf(n, verbose, pr_fmt(fmt), ##__VA_ARGS__)
166 #define pr_debug2(fmt, ...) pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__)
167 #define pr_err(fmt, ...) \
168 eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
169 #define pr_info(fmt, ...) \
170 eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
172 static bool is_btf_id(const char *name
)
174 return name
&& !strncmp(name
, BTF_ID_PREFIX
, sizeof(BTF_ID_PREFIX
) - 1);
177 static struct btf_id
*btf_id__find(struct rb_root
*root
, const char *name
)
179 struct rb_node
*p
= root
->rb_node
;
184 id
= rb_entry(p
, struct btf_id
, rb_node
);
185 cmp
= strcmp(id
->name
, name
);
196 static struct btf_id
*
197 btf_id__add(struct rb_root
*root
, char *name
, bool unique
)
199 struct rb_node
**p
= &root
->rb_node
;
200 struct rb_node
*parent
= NULL
;
206 id
= rb_entry(parent
, struct btf_id
, rb_node
);
207 cmp
= strcmp(id
->name
, name
);
213 return unique
? NULL
: id
;
216 id
= zalloc(sizeof(*id
));
218 pr_debug("adding symbol %s\n", name
);
220 rb_link_node(&id
->rb_node
, parent
, p
);
221 rb_insert_color(&id
->rb_node
, root
);
226 static char *get_id(const char *prefix_end
)
229 * __BTF_ID__func__vfs_truncate__0
233 int len
= strlen(prefix_end
);
234 int pos
= sizeof("__") - 1;
240 id
= strdup(prefix_end
+ pos
);
243 * __BTF_ID__func__vfs_truncate__0
246 * cut the unique id part
248 p
= strrchr(id
, '_');
259 static struct btf_id
*add_set(struct object
*obj
, char *name
, bool is_set8
)
262 * __BTF_ID__set__name
266 char *id
= name
+ (is_set8
? sizeof(BTF_SET8
"__") : sizeof(BTF_SET
"__")) - 1;
267 int len
= strlen(name
);
269 if (id
>= name
+ len
) {
270 pr_err("FAILED to parse set name: %s\n", name
);
274 return btf_id__add(&obj
->sets
, id
, true);
277 static struct btf_id
*add_symbol(struct rb_root
*root
, char *name
, size_t size
)
281 id
= get_id(name
+ size
);
283 pr_err("FAILED to parse symbol name: %s\n", name
);
287 return btf_id__add(root
, id
, false);
290 /* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
291 #ifndef SHF_COMPRESSED
292 #define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
296 * The data of compressed section should be aligned to 4
297 * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
298 * sets sh_addralign to 1, which makes libelf fail with
299 * misaligned section error during the update:
300 * FAILED elf_update(WRITE): invalid section alignment
302 * While waiting for ld fix, we fix the compressed sections
303 * sh_addralign value manualy.
305 static int compressed_section_fix(Elf
*elf
, Elf_Scn
*scn
, GElf_Shdr
*sh
)
307 int expected
= gelf_getclass(elf
) == ELFCLASS32
? 4 : 8;
309 if (!(sh
->sh_flags
& SHF_COMPRESSED
))
312 if (sh
->sh_addralign
== expected
)
315 pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n",
316 sh
->sh_addralign
, expected
);
318 sh
->sh_addralign
= expected
;
320 if (gelf_update_shdr(scn
, sh
) == 0) {
321 pr_err("FAILED cannot update section header: %s\n",
328 static int elf_collect(struct object
*obj
)
337 fd
= open(obj
->path
, O_RDWR
, 0666);
339 pr_err("FAILED cannot open %s: %s\n",
340 obj
->path
, strerror(errno
));
344 elf_version(EV_CURRENT
);
346 elf
= elf_begin(fd
, ELF_C_RDWR_MMAP
, NULL
);
349 pr_err("FAILED cannot create ELF descriptor: %s\n",
355 obj
->efile
.elf
= elf
;
357 elf_flagelf(elf
, ELF_C_SET
, ELF_F_LAYOUT
);
359 if (elf_getshdrstrndx(elf
, &shdrstrndx
) != 0) {
360 pr_err("FAILED cannot get shdr str ndx\n");
364 if (gelf_getehdr(obj
->efile
.elf
, &ehdr
) == NULL
) {
365 pr_err("FAILED cannot get ELF header: %s\n",
369 obj
->efile
.encoding
= ehdr
.e_ident
[EI_DATA
];
372 * Scan all the elf sections and look for save data
373 * from .BTF_ids section and symbols.
375 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
381 if (gelf_getshdr(scn
, &sh
) != &sh
) {
382 pr_err("FAILED get section(%d) header\n", idx
);
386 name
= elf_strptr(elf
, shdrstrndx
, sh
.sh_name
);
388 pr_err("FAILED get section(%d) name\n", idx
);
392 data
= elf_getdata(scn
, 0);
394 pr_err("FAILED to get section(%d) data from %s\n",
399 pr_debug2("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
400 idx
, name
, (unsigned long) data
->d_size
,
401 (int) sh
.sh_link
, (unsigned long) sh
.sh_flags
,
404 if (sh
.sh_type
== SHT_SYMTAB
) {
405 obj
->efile
.symbols
= data
;
406 obj
->efile
.symbols_shndx
= idx
;
407 obj
->efile
.strtabidx
= sh
.sh_link
;
408 } else if (!strcmp(name
, BTF_IDS_SECTION
)) {
409 obj
->efile
.idlist
= data
;
410 obj
->efile
.idlist_shndx
= idx
;
411 obj
->efile
.idlist_addr
= sh
.sh_addr
;
412 } else if (!strcmp(name
, BTF_BASE_ELF_SEC
)) {
413 /* If a .BTF.base section is found, do not resolve
414 * BTF ids relative to vmlinux; resolve relative
415 * to the .BTF.base section instead. btf__parse_split()
416 * will take care of this once the base BTF it is
419 obj
->base_btf_path
= NULL
;
422 if (compressed_section_fix(elf
, scn
, &sh
))
429 static int symbols_collect(struct object
*obj
)
436 scn
= elf_getscn(obj
->efile
.elf
, obj
->efile
.symbols_shndx
);
440 if (gelf_getshdr(scn
, &sh
) != &sh
)
443 n
= sh
.sh_size
/ sh
.sh_entsize
;
446 * Scan symbols and look for the ones starting with
447 * __BTF_ID__* over .BTF_ids section.
449 for (i
= 0; i
< n
; i
++) {
454 if (!gelf_getsym(obj
->efile
.symbols
, i
, &sym
))
457 if (sym
.st_shndx
!= obj
->efile
.idlist_shndx
)
460 name
= elf_strptr(obj
->efile
.elf
, obj
->efile
.strtabidx
,
463 if (!is_btf_id(name
))
467 * __BTF_ID__TYPE__vfs_truncate__0
470 prefix
= name
+ sizeof(BTF_ID_PREFIX
) - 1;
473 if (!strncmp(prefix
, BTF_STRUCT
, sizeof(BTF_STRUCT
) - 1)) {
475 id
= add_symbol(&obj
->structs
, prefix
, sizeof(BTF_STRUCT
) - 1);
477 } else if (!strncmp(prefix
, BTF_UNION
, sizeof(BTF_UNION
) - 1)) {
479 id
= add_symbol(&obj
->unions
, prefix
, sizeof(BTF_UNION
) - 1);
481 } else if (!strncmp(prefix
, BTF_TYPEDEF
, sizeof(BTF_TYPEDEF
) - 1)) {
483 id
= add_symbol(&obj
->typedefs
, prefix
, sizeof(BTF_TYPEDEF
) - 1);
485 } else if (!strncmp(prefix
, BTF_FUNC
, sizeof(BTF_FUNC
) - 1)) {
487 id
= add_symbol(&obj
->funcs
, prefix
, sizeof(BTF_FUNC
) - 1);
489 } else if (!strncmp(prefix
, BTF_SET8
, sizeof(BTF_SET8
) - 1)) {
490 id
= add_set(obj
, prefix
, true);
492 * SET8 objects store list's count, which is encoded
493 * in symbol's size, together with 'cnt' field hence
497 id
->cnt
= sym
.st_size
/ sizeof(uint64_t) - 1;
501 } else if (!strncmp(prefix
, BTF_SET
, sizeof(BTF_SET
) - 1)) {
502 id
= add_set(obj
, prefix
, false);
504 * SET objects store list's count, which is encoded
505 * in symbol's size, together with 'cnt' field hence
509 id
->cnt
= sym
.st_size
/ sizeof(int) - 1;
513 pr_err("FAILED unsupported prefix %s\n", prefix
);
520 if (id
->addr_cnt
>= ADDR_CNT
) {
521 pr_err("FAILED symbol %s crossed the number of allowed lists\n",
525 id
->addr
[id
->addr_cnt
++] = sym
.st_value
;
531 static int symbols_resolve(struct object
*obj
)
533 int nr_typedefs
= obj
->nr_typedefs
;
534 int nr_structs
= obj
->nr_structs
;
535 int nr_unions
= obj
->nr_unions
;
536 int nr_funcs
= obj
->nr_funcs
;
537 struct btf
*base_btf
= NULL
;
542 if (obj
->base_btf_path
) {
543 base_btf
= btf__parse(obj
->base_btf_path
, NULL
);
544 err
= libbpf_get_error(base_btf
);
546 pr_err("FAILED: load base BTF from %s: %s\n",
547 obj
->base_btf_path
, strerror(-err
));
552 btf
= btf__parse_split(obj
->btf
?: obj
->path
, base_btf
);
553 err
= libbpf_get_error(btf
);
555 pr_err("FAILED: load BTF from %s: %s\n",
556 obj
->btf
?: obj
->path
, strerror(-err
));
561 nr_types
= btf__type_cnt(btf
);
564 * Iterate all the BTF types and search for collected symbol IDs.
566 for (type_id
= 1; type_id
< nr_types
; type_id
++) {
567 const struct btf_type
*type
;
568 struct rb_root
*root
;
573 type
= btf__type_by_id(btf
, type_id
);
575 pr_err("FAILED: malformed BTF, can't resolve type for ID %d\n",
580 if (btf_is_func(type
) && nr_funcs
) {
583 } else if (btf_is_struct(type
) && nr_structs
) {
585 root
= &obj
->structs
;
586 } else if (btf_is_union(type
) && nr_unions
) {
589 } else if (btf_is_typedef(type
) && nr_typedefs
) {
591 root
= &obj
->typedefs
;
595 str
= btf__name_by_offset(btf
, type
->name_off
);
597 pr_err("FAILED: malformed BTF, can't resolve name for ID %d\n",
602 id
= btf_id__find(root
, str
);
605 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
606 str
, id
->id
, type_id
, id
->id
);
621 static int id_patch(struct object
*obj
, struct btf_id
*id
)
623 Elf_Data
*data
= obj
->efile
.idlist
;
624 int *ptr
= data
->d_buf
;
627 /* For set, set8, id->id may be 0 */
628 if (!id
->id
&& !id
->is_set
&& !id
->is_set8
)
629 pr_err("WARN: resolve_btfids: unresolved symbol %s\n", id
->name
);
631 for (i
= 0; i
< id
->addr_cnt
; i
++) {
632 unsigned long addr
= id
->addr
[i
];
633 unsigned long idx
= addr
- obj
->efile
.idlist_addr
;
635 pr_debug("patching addr %5lu: ID %7d [%s]\n",
636 idx
, id
->id
, id
->name
);
638 if (idx
>= data
->d_size
) {
639 pr_err("FAILED patching index %lu out of bounds %lu\n",
644 idx
= idx
/ sizeof(int);
651 static int __symbols_patch(struct object
*obj
, struct rb_root
*root
)
653 struct rb_node
*next
;
656 next
= rb_first(root
);
658 id
= rb_entry(next
, struct btf_id
, rb_node
);
660 if (id_patch(obj
, id
))
663 next
= rb_next(next
);
668 static int cmp_id(const void *pa
, const void *pb
)
670 const int *a
= pa
, *b
= pb
;
675 static int sets_patch(struct object
*obj
)
677 Elf_Data
*data
= obj
->efile
.idlist
;
678 struct rb_node
*next
;
680 next
= rb_first(&obj
->sets
);
682 struct btf_id_set8
*set8
= NULL
;
683 struct btf_id_set
*set
= NULL
;
684 unsigned long addr
, off
;
687 id
= rb_entry(next
, struct btf_id
, rb_node
);
689 off
= addr
- obj
->efile
.idlist_addr
;
691 /* sets are unique */
692 if (id
->addr_cnt
!= 1) {
693 pr_err("FAILED malformed data for set '%s'\n",
699 set
= data
->d_buf
+ off
;
700 qsort(set
->ids
, set
->cnt
, sizeof(set
->ids
[0]), cmp_id
);
702 set8
= data
->d_buf
+ off
;
704 * Make sure id is at the beginning of the pairs
705 * struct, otherwise the below qsort would not work.
707 BUILD_BUG_ON((u32
*)set8
->pairs
!= &set8
->pairs
[0].id
);
708 qsort(set8
->pairs
, set8
->cnt
, sizeof(set8
->pairs
[0]), cmp_id
);
711 * When ELF endianness does not match endianness of the
712 * host, libelf will do the translation when updating
713 * the ELF. This, however, corrupts SET8 flags which are
714 * already in the target endianness. So, let's bswap
715 * them to the host endianness and libelf will then
716 * correctly translate everything.
718 if (obj
->efile
.encoding
!= ELFDATANATIVE
) {
721 set8
->flags
= bswap_32(set8
->flags
);
722 for (i
= 0; i
< set8
->cnt
; i
++) {
723 set8
->pairs
[i
].flags
=
724 bswap_32(set8
->pairs
[i
].flags
);
729 pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
730 off
, id
->is_set
? set
->cnt
: set8
->cnt
, id
->name
);
732 next
= rb_next(next
);
737 static int symbols_patch(struct object
*obj
)
741 if (__symbols_patch(obj
, &obj
->structs
) ||
742 __symbols_patch(obj
, &obj
->unions
) ||
743 __symbols_patch(obj
, &obj
->typedefs
) ||
744 __symbols_patch(obj
, &obj
->funcs
) ||
745 __symbols_patch(obj
, &obj
->sets
))
751 /* Set type to ensure endian translation occurs. */
752 obj
->efile
.idlist
->d_type
= ELF_T_WORD
;
754 elf_flagdata(obj
->efile
.idlist
, ELF_C_SET
, ELF_F_DIRTY
);
756 err
= elf_update(obj
->efile
.elf
, ELF_C_WRITE
);
758 pr_err("FAILED elf_update(WRITE): %s\n",
762 pr_debug("update %s for %s\n",
763 err
>= 0 ? "ok" : "failed", obj
->path
);
764 return err
< 0 ? -1 : 0;
767 static const char * const resolve_btfids_usage
[] = {
768 "resolve_btfids [<options>] <ELF object>",
772 int main(int argc
, const char **argv
)
774 struct object obj
= {
785 struct option btfid_options
[] = {
786 OPT_INCR('v', "verbose", &verbose
,
787 "be more verbose (show errors, etc)"),
788 OPT_STRING(0, "btf", &obj
.btf
, "BTF data",
790 OPT_STRING('b', "btf_base", &obj
.base_btf_path
, "file",
791 "path of file providing base BTF"),
796 argc
= parse_options(argc
, argv
, btfid_options
, resolve_btfids_usage
,
797 PARSE_OPT_STOP_AT_NON_OPTION
);
799 usage_with_options(resolve_btfids_usage
, btfid_options
);
803 if (elf_collect(&obj
))
807 * We did not find .BTF_ids section or symbols section,
810 if (obj
.efile
.idlist_shndx
== -1 ||
811 obj
.efile
.symbols_shndx
== -1) {
812 pr_debug("Cannot find .BTF_ids or symbols sections, nothing to do\n");
817 if (symbols_collect(&obj
))
820 if (symbols_resolve(&obj
))
823 if (symbols_patch(&obj
))
829 elf_end(obj
.efile
.elf
);