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:
60 #include <linux/rbtree.h>
61 #include <linux/zalloc.h>
62 #include <linux/err.h>
65 #include <parse-options.h>
67 #define BTF_IDS_SECTION ".BTF_ids"
68 #define BTF_ID "__BTF_ID__"
70 #define BTF_STRUCT "struct"
71 #define BTF_UNION "union"
72 #define BTF_TYPEDEF "typedef"
73 #define BTF_FUNC "func"
79 struct rb_node rb_node
;
86 Elf64_Addr addr
[ADDR_CNT
];
101 unsigned long idlist_addr
;
105 struct rb_root structs
;
106 struct rb_root unions
;
107 struct rb_root typedefs
;
108 struct rb_root funcs
;
118 int eprintf(int level
, int var
, const char *fmt
, ...)
125 ret
= vfprintf(stderr
, fmt
, args
);
132 #define pr_fmt(fmt) fmt
135 #define pr_debug(fmt, ...) \
136 eprintf(1, verbose, pr_fmt(fmt), ##__VA_ARGS__)
137 #define pr_debugN(n, fmt, ...) \
138 eprintf(n, verbose, pr_fmt(fmt), ##__VA_ARGS__)
139 #define pr_debug2(fmt, ...) pr_debugN(2, pr_fmt(fmt), ##__VA_ARGS__)
140 #define pr_err(fmt, ...) \
141 eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
142 #define pr_info(fmt, ...) \
143 eprintf(0, verbose, pr_fmt(fmt), ##__VA_ARGS__)
145 static bool is_btf_id(const char *name
)
147 return name
&& !strncmp(name
, BTF_ID
, sizeof(BTF_ID
) - 1);
150 static struct btf_id
*btf_id__find(struct rb_root
*root
, const char *name
)
152 struct rb_node
*p
= root
->rb_node
;
157 id
= rb_entry(p
, struct btf_id
, rb_node
);
158 cmp
= strcmp(id
->name
, name
);
169 static struct btf_id
*
170 btf_id__add(struct rb_root
*root
, char *name
, bool unique
)
172 struct rb_node
**p
= &root
->rb_node
;
173 struct rb_node
*parent
= NULL
;
179 id
= rb_entry(parent
, struct btf_id
, rb_node
);
180 cmp
= strcmp(id
->name
, name
);
186 return unique
? NULL
: id
;
189 id
= zalloc(sizeof(*id
));
191 pr_debug("adding symbol %s\n", name
);
193 rb_link_node(&id
->rb_node
, parent
, p
);
194 rb_insert_color(&id
->rb_node
, root
);
199 static char *get_id(const char *prefix_end
)
202 * __BTF_ID__func__vfs_truncate__0
206 int len
= strlen(prefix_end
);
207 int pos
= sizeof("__") - 1;
213 id
= strdup(prefix_end
+ pos
);
216 * __BTF_ID__func__vfs_truncate__0
219 * cut the unique id part
221 p
= strrchr(id
, '_');
232 static struct btf_id
*add_set(struct object
*obj
, char *name
)
235 * __BTF_ID__set__name
239 char *id
= name
+ sizeof(BTF_SET
"__") - 1;
240 int len
= strlen(name
);
242 if (id
>= name
+ len
) {
243 pr_err("FAILED to parse set name: %s\n", name
);
247 return btf_id__add(&obj
->sets
, id
, true);
250 static struct btf_id
*add_symbol(struct rb_root
*root
, char *name
, size_t size
)
254 id
= get_id(name
+ size
);
256 pr_err("FAILED to parse symbol name: %s\n", name
);
260 return btf_id__add(root
, id
, false);
264 * The data of compressed section should be aligned to 4
265 * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
266 * sets sh_addralign to 1, which makes libelf fail with
267 * misaligned section error during the update:
268 * FAILED elf_update(WRITE): invalid section alignment
270 * While waiting for ld fix, we fix the compressed sections
271 * sh_addralign value manualy.
273 static int compressed_section_fix(Elf
*elf
, Elf_Scn
*scn
, GElf_Shdr
*sh
)
275 int expected
= gelf_getclass(elf
) == ELFCLASS32
? 4 : 8;
277 if (!(sh
->sh_flags
& SHF_COMPRESSED
))
280 if (sh
->sh_addralign
== expected
)
283 pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n",
284 sh
->sh_addralign
, expected
);
286 sh
->sh_addralign
= expected
;
288 if (gelf_update_shdr(scn
, sh
) == 0) {
289 printf("FAILED cannot update section header: %s\n",
296 static int elf_collect(struct object
*obj
)
304 fd
= open(obj
->path
, O_RDWR
, 0666);
306 pr_err("FAILED cannot open %s: %s\n",
307 obj
->path
, strerror(errno
));
311 elf_version(EV_CURRENT
);
313 elf
= elf_begin(fd
, ELF_C_RDWR_MMAP
, NULL
);
315 pr_err("FAILED cannot create ELF descriptor: %s\n",
321 obj
->efile
.elf
= elf
;
323 elf_flagelf(elf
, ELF_C_SET
, ELF_F_LAYOUT
);
325 if (elf_getshdrstrndx(elf
, &shdrstrndx
) != 0) {
326 pr_err("FAILED cannot get shdr str ndx\n");
331 * Scan all the elf sections and look for save data
332 * from .BTF_ids section and symbols.
334 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
340 if (gelf_getshdr(scn
, &sh
) != &sh
) {
341 pr_err("FAILED get section(%d) header\n", idx
);
345 name
= elf_strptr(elf
, shdrstrndx
, sh
.sh_name
);
347 pr_err("FAILED get section(%d) name\n", idx
);
351 data
= elf_getdata(scn
, 0);
353 pr_err("FAILED to get section(%d) data from %s\n",
358 pr_debug2("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
359 idx
, name
, (unsigned long) data
->d_size
,
360 (int) sh
.sh_link
, (unsigned long) sh
.sh_flags
,
363 if (sh
.sh_type
== SHT_SYMTAB
) {
364 obj
->efile
.symbols
= data
;
365 obj
->efile
.symbols_shndx
= idx
;
366 obj
->efile
.strtabidx
= sh
.sh_link
;
367 } else if (!strcmp(name
, BTF_IDS_SECTION
)) {
368 obj
->efile
.idlist
= data
;
369 obj
->efile
.idlist_shndx
= idx
;
370 obj
->efile
.idlist_addr
= sh
.sh_addr
;
373 if (compressed_section_fix(elf
, scn
, &sh
))
380 static int symbols_collect(struct object
*obj
)
387 scn
= elf_getscn(obj
->efile
.elf
, obj
->efile
.symbols_shndx
);
391 if (gelf_getshdr(scn
, &sh
) != &sh
)
394 n
= sh
.sh_size
/ sh
.sh_entsize
;
397 * Scan symbols and look for the ones starting with
398 * __BTF_ID__* over .BTF_ids section.
400 for (i
= 0; !err
&& i
< n
; i
++) {
406 if (!gelf_getsym(obj
->efile
.symbols
, i
, &sym
))
409 if (sym
.st_shndx
!= obj
->efile
.idlist_shndx
)
412 name
= elf_strptr(obj
->efile
.elf
, obj
->efile
.strtabidx
,
415 if (!is_btf_id(name
))
419 * __BTF_ID__TYPE__vfs_truncate__0
422 prefix
= name
+ sizeof(BTF_ID
) - 1;
425 if (!strncmp(prefix
, BTF_STRUCT
, sizeof(BTF_STRUCT
) - 1)) {
427 id
= add_symbol(&obj
->structs
, prefix
, sizeof(BTF_STRUCT
) - 1);
429 } else if (!strncmp(prefix
, BTF_UNION
, sizeof(BTF_UNION
) - 1)) {
431 id
= add_symbol(&obj
->unions
, prefix
, sizeof(BTF_UNION
) - 1);
433 } else if (!strncmp(prefix
, BTF_TYPEDEF
, sizeof(BTF_TYPEDEF
) - 1)) {
435 id
= add_symbol(&obj
->typedefs
, prefix
, sizeof(BTF_TYPEDEF
) - 1);
437 } else if (!strncmp(prefix
, BTF_FUNC
, sizeof(BTF_FUNC
) - 1)) {
439 id
= add_symbol(&obj
->funcs
, prefix
, sizeof(BTF_FUNC
) - 1);
441 } else if (!strncmp(prefix
, BTF_SET
, sizeof(BTF_SET
) - 1)) {
442 id
= add_set(obj
, prefix
);
444 * SET objects store list's count, which is encoded
445 * in symbol's size, together with 'cnt' field hence
449 id
->cnt
= sym
.st_size
/ sizeof(int) - 1;
451 pr_err("FAILED unsupported prefix %s\n", prefix
);
458 if (id
->addr_cnt
>= ADDR_CNT
) {
459 pr_err("FAILED symbol %s crossed the number of allowed lists\n",
463 id
->addr
[id
->addr_cnt
++] = sym
.st_value
;
469 static int symbols_resolve(struct object
*obj
)
471 int nr_typedefs
= obj
->nr_typedefs
;
472 int nr_structs
= obj
->nr_structs
;
473 int nr_unions
= obj
->nr_unions
;
474 int nr_funcs
= obj
->nr_funcs
;
479 btf
= btf__parse(obj
->btf
?: obj
->path
, NULL
);
480 err
= libbpf_get_error(btf
);
482 pr_err("FAILED: load BTF from %s: %s\n",
483 obj
->path
, strerror(-err
));
488 nr_types
= btf__get_nr_types(btf
);
491 * Iterate all the BTF types and search for collected symbol IDs.
493 for (type_id
= 1; type_id
<= nr_types
; type_id
++) {
494 const struct btf_type
*type
;
495 struct rb_root
*root
;
500 type
= btf__type_by_id(btf
, type_id
);
502 pr_err("FAILED: malformed BTF, can't resolve type for ID %d\n",
507 if (btf_is_func(type
) && nr_funcs
) {
510 } else if (btf_is_struct(type
) && nr_structs
) {
512 root
= &obj
->structs
;
513 } else if (btf_is_union(type
) && nr_unions
) {
516 } else if (btf_is_typedef(type
) && nr_typedefs
) {
518 root
= &obj
->typedefs
;
522 str
= btf__name_by_offset(btf
, type
->name_off
);
524 pr_err("FAILED: malformed BTF, can't resolve name for ID %d\n",
529 id
= btf_id__find(root
, str
);
532 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
533 str
, id
->id
, type_id
, id
->id
);
547 static int id_patch(struct object
*obj
, struct btf_id
*id
)
549 Elf_Data
*data
= obj
->efile
.idlist
;
550 int *ptr
= data
->d_buf
;
554 pr_err("FAILED unresolved symbol %s\n", id
->name
);
558 for (i
= 0; i
< id
->addr_cnt
; i
++) {
559 unsigned long addr
= id
->addr
[i
];
560 unsigned long idx
= addr
- obj
->efile
.idlist_addr
;
562 pr_debug("patching addr %5lu: ID %7d [%s]\n",
563 idx
, id
->id
, id
->name
);
565 if (idx
>= data
->d_size
) {
566 pr_err("FAILED patching index %lu out of bounds %lu\n",
571 idx
= idx
/ sizeof(int);
578 static int __symbols_patch(struct object
*obj
, struct rb_root
*root
)
580 struct rb_node
*next
;
583 next
= rb_first(root
);
585 id
= rb_entry(next
, struct btf_id
, rb_node
);
587 if (id_patch(obj
, id
))
590 next
= rb_next(next
);
595 static int cmp_id(const void *pa
, const void *pb
)
597 const int *a
= pa
, *b
= pb
;
602 static int sets_patch(struct object
*obj
)
604 Elf_Data
*data
= obj
->efile
.idlist
;
605 int *ptr
= data
->d_buf
;
606 struct rb_node
*next
;
608 next
= rb_first(&obj
->sets
);
610 unsigned long addr
, idx
;
615 id
= rb_entry(next
, struct btf_id
, rb_node
);
617 idx
= addr
- obj
->efile
.idlist_addr
;
619 /* sets are unique */
620 if (id
->addr_cnt
!= 1) {
621 pr_err("FAILED malformed data for set '%s'\n",
626 idx
= idx
/ sizeof(int);
627 base
= &ptr
[idx
] + 1;
630 pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
631 (idx
+ 1) * sizeof(int), cnt
, id
->name
);
633 qsort(base
, cnt
, sizeof(int), cmp_id
);
635 next
= rb_next(next
);
640 static int symbols_patch(struct object
*obj
)
644 if (__symbols_patch(obj
, &obj
->structs
) ||
645 __symbols_patch(obj
, &obj
->unions
) ||
646 __symbols_patch(obj
, &obj
->typedefs
) ||
647 __symbols_patch(obj
, &obj
->funcs
) ||
648 __symbols_patch(obj
, &obj
->sets
))
654 elf_flagdata(obj
->efile
.idlist
, ELF_C_SET
, ELF_F_DIRTY
);
656 err
= elf_update(obj
->efile
.elf
, ELF_C_WRITE
);
658 pr_err("FAILED elf_update(WRITE): %s\n",
662 pr_debug("update %s for %s\n",
663 err
>= 0 ? "ok" : "failed", obj
->path
);
664 return err
< 0 ? -1 : 0;
667 static const char * const resolve_btfids_usage
[] = {
668 "resolve_btfids [<options>] <ELF object>",
672 int main(int argc
, const char **argv
)
674 bool no_fail
= false;
675 struct object obj
= {
686 struct option btfid_options
[] = {
687 OPT_INCR('v', "verbose", &verbose
,
688 "be more verbose (show errors, etc)"),
689 OPT_STRING(0, "btf", &obj
.btf
, "BTF data",
691 OPT_BOOLEAN(0, "no-fail", &no_fail
,
692 "do not fail if " BTF_IDS_SECTION
" section is not found"),
697 argc
= parse_options(argc
, argv
, btfid_options
, resolve_btfids_usage
,
698 PARSE_OPT_STOP_AT_NON_OPTION
);
700 usage_with_options(resolve_btfids_usage
, btfid_options
);
704 if (elf_collect(&obj
))
708 * We did not find .BTF_ids section or symbols section,
711 if (obj
.efile
.idlist_shndx
== -1 ||
712 obj
.efile
.symbols_shndx
== -1) {
715 pr_err("FAILED to find needed sections\n");
719 if (symbols_collect(&obj
))
722 if (symbols_resolve(&obj
))
725 if (symbols_patch(&obj
))
731 elf_end(obj
.efile
.elf
);