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);
263 /* Older libelf.h and glibc elf.h might not yet define the ELF compression types. */
264 #ifndef SHF_COMPRESSED
265 #define SHF_COMPRESSED (1 << 11) /* Section with compressed data. */
269 * The data of compressed section should be aligned to 4
270 * (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
271 * sets sh_addralign to 1, which makes libelf fail with
272 * misaligned section error during the update:
273 * FAILED elf_update(WRITE): invalid section alignment
275 * While waiting for ld fix, we fix the compressed sections
276 * sh_addralign value manualy.
278 static int compressed_section_fix(Elf
*elf
, Elf_Scn
*scn
, GElf_Shdr
*sh
)
280 int expected
= gelf_getclass(elf
) == ELFCLASS32
? 4 : 8;
282 if (!(sh
->sh_flags
& SHF_COMPRESSED
))
285 if (sh
->sh_addralign
== expected
)
288 pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n",
289 sh
->sh_addralign
, expected
);
291 sh
->sh_addralign
= expected
;
293 if (gelf_update_shdr(scn
, sh
) == 0) {
294 printf("FAILED cannot update section header: %s\n",
301 static int elf_collect(struct object
*obj
)
309 fd
= open(obj
->path
, O_RDWR
, 0666);
311 pr_err("FAILED cannot open %s: %s\n",
312 obj
->path
, strerror(errno
));
316 elf_version(EV_CURRENT
);
318 elf
= elf_begin(fd
, ELF_C_RDWR_MMAP
, NULL
);
320 pr_err("FAILED cannot create ELF descriptor: %s\n",
326 obj
->efile
.elf
= elf
;
328 elf_flagelf(elf
, ELF_C_SET
, ELF_F_LAYOUT
);
330 if (elf_getshdrstrndx(elf
, &shdrstrndx
) != 0) {
331 pr_err("FAILED cannot get shdr str ndx\n");
336 * Scan all the elf sections and look for save data
337 * from .BTF_ids section and symbols.
339 while ((scn
= elf_nextscn(elf
, scn
)) != NULL
) {
345 if (gelf_getshdr(scn
, &sh
) != &sh
) {
346 pr_err("FAILED get section(%d) header\n", idx
);
350 name
= elf_strptr(elf
, shdrstrndx
, sh
.sh_name
);
352 pr_err("FAILED get section(%d) name\n", idx
);
356 data
= elf_getdata(scn
, 0);
358 pr_err("FAILED to get section(%d) data from %s\n",
363 pr_debug2("section(%d) %s, size %ld, link %d, flags %lx, type=%d\n",
364 idx
, name
, (unsigned long) data
->d_size
,
365 (int) sh
.sh_link
, (unsigned long) sh
.sh_flags
,
368 if (sh
.sh_type
== SHT_SYMTAB
) {
369 obj
->efile
.symbols
= data
;
370 obj
->efile
.symbols_shndx
= idx
;
371 obj
->efile
.strtabidx
= sh
.sh_link
;
372 } else if (!strcmp(name
, BTF_IDS_SECTION
)) {
373 obj
->efile
.idlist
= data
;
374 obj
->efile
.idlist_shndx
= idx
;
375 obj
->efile
.idlist_addr
= sh
.sh_addr
;
378 if (compressed_section_fix(elf
, scn
, &sh
))
385 static int symbols_collect(struct object
*obj
)
392 scn
= elf_getscn(obj
->efile
.elf
, obj
->efile
.symbols_shndx
);
396 if (gelf_getshdr(scn
, &sh
) != &sh
)
399 n
= sh
.sh_size
/ sh
.sh_entsize
;
402 * Scan symbols and look for the ones starting with
403 * __BTF_ID__* over .BTF_ids section.
405 for (i
= 0; !err
&& i
< n
; i
++) {
411 if (!gelf_getsym(obj
->efile
.symbols
, i
, &sym
))
414 if (sym
.st_shndx
!= obj
->efile
.idlist_shndx
)
417 name
= elf_strptr(obj
->efile
.elf
, obj
->efile
.strtabidx
,
420 if (!is_btf_id(name
))
424 * __BTF_ID__TYPE__vfs_truncate__0
427 prefix
= name
+ sizeof(BTF_ID
) - 1;
430 if (!strncmp(prefix
, BTF_STRUCT
, sizeof(BTF_STRUCT
) - 1)) {
432 id
= add_symbol(&obj
->structs
, prefix
, sizeof(BTF_STRUCT
) - 1);
434 } else if (!strncmp(prefix
, BTF_UNION
, sizeof(BTF_UNION
) - 1)) {
436 id
= add_symbol(&obj
->unions
, prefix
, sizeof(BTF_UNION
) - 1);
438 } else if (!strncmp(prefix
, BTF_TYPEDEF
, sizeof(BTF_TYPEDEF
) - 1)) {
440 id
= add_symbol(&obj
->typedefs
, prefix
, sizeof(BTF_TYPEDEF
) - 1);
442 } else if (!strncmp(prefix
, BTF_FUNC
, sizeof(BTF_FUNC
) - 1)) {
444 id
= add_symbol(&obj
->funcs
, prefix
, sizeof(BTF_FUNC
) - 1);
446 } else if (!strncmp(prefix
, BTF_SET
, sizeof(BTF_SET
) - 1)) {
447 id
= add_set(obj
, prefix
);
449 * SET objects store list's count, which is encoded
450 * in symbol's size, together with 'cnt' field hence
454 id
->cnt
= sym
.st_size
/ sizeof(int) - 1;
456 pr_err("FAILED unsupported prefix %s\n", prefix
);
463 if (id
->addr_cnt
>= ADDR_CNT
) {
464 pr_err("FAILED symbol %s crossed the number of allowed lists\n",
468 id
->addr
[id
->addr_cnt
++] = sym
.st_value
;
474 static int symbols_resolve(struct object
*obj
)
476 int nr_typedefs
= obj
->nr_typedefs
;
477 int nr_structs
= obj
->nr_structs
;
478 int nr_unions
= obj
->nr_unions
;
479 int nr_funcs
= obj
->nr_funcs
;
484 btf
= btf__parse(obj
->btf
?: obj
->path
, NULL
);
485 err
= libbpf_get_error(btf
);
487 pr_err("FAILED: load BTF from %s: %s\n",
488 obj
->path
, strerror(-err
));
493 nr_types
= btf__get_nr_types(btf
);
496 * Iterate all the BTF types and search for collected symbol IDs.
498 for (type_id
= 1; type_id
<= nr_types
; type_id
++) {
499 const struct btf_type
*type
;
500 struct rb_root
*root
;
505 type
= btf__type_by_id(btf
, type_id
);
507 pr_err("FAILED: malformed BTF, can't resolve type for ID %d\n",
512 if (btf_is_func(type
) && nr_funcs
) {
515 } else if (btf_is_struct(type
) && nr_structs
) {
517 root
= &obj
->structs
;
518 } else if (btf_is_union(type
) && nr_unions
) {
521 } else if (btf_is_typedef(type
) && nr_typedefs
) {
523 root
= &obj
->typedefs
;
527 str
= btf__name_by_offset(btf
, type
->name_off
);
529 pr_err("FAILED: malformed BTF, can't resolve name for ID %d\n",
534 id
= btf_id__find(root
, str
);
537 pr_info("WARN: multiple IDs found for '%s': %d, %d - using %d\n",
538 str
, id
->id
, type_id
, id
->id
);
552 static int id_patch(struct object
*obj
, struct btf_id
*id
)
554 Elf_Data
*data
= obj
->efile
.idlist
;
555 int *ptr
= data
->d_buf
;
559 pr_err("FAILED unresolved symbol %s\n", id
->name
);
563 for (i
= 0; i
< id
->addr_cnt
; i
++) {
564 unsigned long addr
= id
->addr
[i
];
565 unsigned long idx
= addr
- obj
->efile
.idlist_addr
;
567 pr_debug("patching addr %5lu: ID %7d [%s]\n",
568 idx
, id
->id
, id
->name
);
570 if (idx
>= data
->d_size
) {
571 pr_err("FAILED patching index %lu out of bounds %lu\n",
576 idx
= idx
/ sizeof(int);
583 static int __symbols_patch(struct object
*obj
, struct rb_root
*root
)
585 struct rb_node
*next
;
588 next
= rb_first(root
);
590 id
= rb_entry(next
, struct btf_id
, rb_node
);
592 if (id_patch(obj
, id
))
595 next
= rb_next(next
);
600 static int cmp_id(const void *pa
, const void *pb
)
602 const int *a
= pa
, *b
= pb
;
607 static int sets_patch(struct object
*obj
)
609 Elf_Data
*data
= obj
->efile
.idlist
;
610 int *ptr
= data
->d_buf
;
611 struct rb_node
*next
;
613 next
= rb_first(&obj
->sets
);
615 unsigned long addr
, idx
;
620 id
= rb_entry(next
, struct btf_id
, rb_node
);
622 idx
= addr
- obj
->efile
.idlist_addr
;
624 /* sets are unique */
625 if (id
->addr_cnt
!= 1) {
626 pr_err("FAILED malformed data for set '%s'\n",
631 idx
= idx
/ sizeof(int);
632 base
= &ptr
[idx
] + 1;
635 pr_debug("sorting addr %5lu: cnt %6d [%s]\n",
636 (idx
+ 1) * sizeof(int), cnt
, id
->name
);
638 qsort(base
, cnt
, sizeof(int), cmp_id
);
640 next
= rb_next(next
);
645 static int symbols_patch(struct object
*obj
)
649 if (__symbols_patch(obj
, &obj
->structs
) ||
650 __symbols_patch(obj
, &obj
->unions
) ||
651 __symbols_patch(obj
, &obj
->typedefs
) ||
652 __symbols_patch(obj
, &obj
->funcs
) ||
653 __symbols_patch(obj
, &obj
->sets
))
659 elf_flagdata(obj
->efile
.idlist
, ELF_C_SET
, ELF_F_DIRTY
);
661 err
= elf_update(obj
->efile
.elf
, ELF_C_WRITE
);
663 pr_err("FAILED elf_update(WRITE): %s\n",
667 pr_debug("update %s for %s\n",
668 err
>= 0 ? "ok" : "failed", obj
->path
);
669 return err
< 0 ? -1 : 0;
672 static const char * const resolve_btfids_usage
[] = {
673 "resolve_btfids [<options>] <ELF object>",
677 int main(int argc
, const char **argv
)
679 bool no_fail
= false;
680 struct object obj
= {
691 struct option btfid_options
[] = {
692 OPT_INCR('v', "verbose", &verbose
,
693 "be more verbose (show errors, etc)"),
694 OPT_STRING(0, "btf", &obj
.btf
, "BTF data",
696 OPT_BOOLEAN(0, "no-fail", &no_fail
,
697 "do not fail if " BTF_IDS_SECTION
" section is not found"),
702 argc
= parse_options(argc
, argv
, btfid_options
, resolve_btfids_usage
,
703 PARSE_OPT_STOP_AT_NON_OPTION
);
705 usage_with_options(resolve_btfids_usage
, btfid_options
);
709 if (elf_collect(&obj
))
713 * We did not find .BTF_ids section or symbols section,
716 if (obj
.efile
.idlist_shndx
== -1 ||
717 obj
.efile
.symbols_shndx
== -1) {
720 pr_err("FAILED to find needed sections\n");
724 if (symbols_collect(&obj
))
727 if (symbols_resolve(&obj
))
730 if (symbols_patch(&obj
))
736 elf_end(obj
.efile
.elf
);