On Wed, Jan 10, 2024 at 06:14:25PM -0700, Daniel Xu wrote: SNIP > + > +static int btf_encoder__tag_kfuncs(struct btf_encoder *encoder) > +{ > + const char *filename = encoder->filename; > + Elf_Scn *symscn = NULL; > + int symbols_shndx = -1; > + int fd = -1, err = -1; > + int idlist_shndx = -1; > + Elf_Scn *scn = NULL; > + size_t idlist_addr; > + Elf_Data *symbols; > + Elf_Data *idlist; > + size_t strtabidx; > + Elf *elf = NULL; > + int set_cnt = 0; > + GElf_Shdr shdr; > + size_t strndx; > + char *secname; > + int nr_syms; > + int i = 0; smooth ;-) SNIP > + > + nr_syms = shdr.sh_size / shdr.sh_entsize; > + for (i = 0; i < nr_syms; i++) { > + char *kfunc, *name; > + int new_set_cnt; > + GElf_Sym sym; > + int err; > + > + if (!gelf_getsym(symbols, i, &sym)) { > + elf_error("Failed to get ELF symbol(%d)", i); > + goto out; > + } > + > + if (sym.st_shndx != idlist_shndx) > + continue; > + > + name = elf_strptr(elf, strtabidx, sym.st_name); > + new_set_cnt = get_kfunc_set_cnt(&sym, name, idlist, idlist_addr); > + if (new_set_cnt < 0) { > + err = new_set_cnt; > + goto out; > + } else if (new_set_cnt) { > + if (set_cnt) > + fprintf(stderr, "%s: warning: overlapping set8 '%s'\n", > + __func__, name); > + set_cnt = new_set_cnt; > + continue; > + } > + > + if (!set_cnt) > + continue; > + set_cnt--; > + > + kfunc = get_kfunc_name(name); > + if (!kfunc) > + continue; > + > + err = btf_encoder__tag_kfunc(encoder, kfunc); are .BTF_ids records guaranteed to be sorted by address? so we are sure that the set will be followed by its records? I thought we'd need to find size for each set and then check each .BTF_ids record if it belongs to the set jirka > + if (err) { > + fprintf(stderr, "%s: failed to tag kfunc '%s'\n", __func__, kfunc); > + free(kfunc); > + goto out; > + } > + free(kfunc); > + } > + > + err = 0; > +out: > + if (elf) > + elf_end(elf); > + if (fd != -1) > + close(fd); > + return err; > +} > + > int btf_encoder__encode(struct btf_encoder *encoder) > { > int err; > @@ -1366,6 +1681,14 @@ int btf_encoder__encode(struct btf_encoder *encoder) > if (btf__type_cnt(encoder->btf) == 1) > return 0; > > + /* Note vmlinux may already contain btf_decl_tag's for kfuncs. So > + * take care to call this before btf_dedup(). > + */ > + if (btf_encoder__tag_kfuncs(encoder)) { > + fprintf(stderr, "%s: failed to tag kfuncs!\n", __func__); > + return -1; > + } > + > if (btf__dedup(encoder->btf, NULL)) { > fprintf(stderr, "%s: btf__dedup failed!\n", __func__); > return -1; > @@ -1712,6 +2035,7 @@ void btf_encoder__delete(struct btf_encoder *encoder) > > btf_encoders__delete(encoder); > __gobuffer__delete(&encoder->percpu_secinfo); > + __gobuffer__delete(&encoder->btf_funcs); > zfree(&encoder->filename); > btf__free(encoder->btf); > encoder->btf = NULL; > -- > 2.42.1 >