On Fri, Jan 22, 2021 at 12:47 PM Jiri Olsa <jolsa@xxxxxxxxxx> wrote: > > On Thu, Jan 21, 2021 at 03:32:40PM -0800, Andrii Nakryiko wrote: > > SNIP > > > > @@ -598,9 +599,36 @@ static void collect_symbol(GElf_Sym *sym, struct funcs_layout *fl) > > > fl->mcount_stop = sym->st_value; > > > } > > > > > > +static bool elf_sym__get(Elf_Data *syms, Elf_Data *syms_sec_idx_table, > > > + int id, GElf_Sym *sym, Elf32_Word *sym_sec_idx) > > > +{ > > > + if (!gelf_getsym(syms, id, sym)) > > > + return false; > > > + > > > + *sym_sec_idx = sym->st_shndx; > > > + > > > + if (sym->st_shndx == SHN_XINDEX) { > > > + if (!syms_sec_idx_table) > > > + return false; > > > + if (!gelf_getsymshndx(syms, syms_sec_idx_table, > > > + id, sym, sym_sec_idx)) > > > > > > gelf_getsymshndx() is supposed to work even for cases that don't use > > extended numbering, so this should work, right? > > > > if (!gelf_getsymshndx(syms, syms_sec_idx_table, id, sym, sym_sec_idx)) > > return false; > > > > it seems you're right, gelf_getsymshndx seem to work for > both cases, I'll check > > > > if (sym->st_shndx == SHN_XINDEX) > > *sym_sec_idx = sym->st_shndx; > > I don't understand this.. gelf_getsymshndx will return both > symbol and proper index, no? also sym_sec_idx is already > assigned from previou call Reading (some) implementation of gelf_getsymshndx() that I found online, it won't set sym_sec_idx, if the symbol *doesn't* use extended numbering. But it will still return symbol data. So to return the section index in all cases, we need to check again *after* we got symbol, and if it's not extended, then set index manually. > > > > > return true; > > > > ? > > > > > + return false; > > > + } > > > + > > > + return true; > > > +} > > > + > > > +#define elf_symtab__for_each_symbol_index(symtab, id, sym, sym_sec_idx) \ > > > + for (id = 0, elf_sym__get(symtab->syms, symtab->syms_sec_idx_table, \ > > > + id, &sym, &sym_sec_idx); \ > > > + id < symtab->nr_syms; \ > > > + id++, elf_sym__get(symtab->syms, symtab->syms_sec_idx_table, \ > > > + id, &sym, &sym_sec_idx)) > > > > what do we want to do if elf_sym__get() returns error (false)? We can > > either stop or ignore that symbol, right? But currently you are > > returning invalid symbol data. > > > > so either > > > > for (id = 0; id < symtab->nr_syms && elf_sym__get(symtab->syms, > > symtab->syms_sec_idx_table, d, &sym, &sym_sec_idx); id++) > > > > or > > > > for (id = 0; id < symtab->nr_syms; id++) > > if (elf_sym__get(symtab->syms, symtab->syms_sec_idx_table, d, &sym, > > &sym_sec_idx)) > > if we go ahead with skipping symbols, this one seems good I think skipping symbols is nicer. If ELF is totally broken, then all symbols are going to be ignored anyway. If it's some one-off issue for a specific symbol, we'll just ignore it (unfortunately, silently). > > > > > > > But the current variant looks broken. Oh, and > > elf_symtab__for_each_symbol() is similarly broken, can you please fix > > that as well? > > > > And this new macro should probably be in elf_symtab.h, along the > > elf_symtab__for_each_symbol. > > thanks, > jirka >