On Fri, Aug 16, 2024 at 2:39 AM Sami Tolvanen <samitolvanen@xxxxxxxxxx> wrote: > > The compiler may choose not to emit type information in DWARF for all > aliases, but it's possible for each alias to be exported separately. > To ensure we find type information for the aliases as well, read > {section, address} tuples from the symbol table and match symbols also > by address. > > Signed-off-by: Sami Tolvanen <samitolvanen@xxxxxxxxxx> > --- > scripts/gendwarfksyms/gendwarfksyms.c | 2 + > scripts/gendwarfksyms/gendwarfksyms.h | 7 ++ > scripts/gendwarfksyms/symbols.c | 161 +++++++++++++++++++++++++- > 3 files changed, 165 insertions(+), 5 deletions(-) > > diff --git a/scripts/gendwarfksyms/gendwarfksyms.c b/scripts/gendwarfksyms/gendwarfksyms.c > index d209b237766b..e2f8ee5a4bf3 100644 > --- a/scripts/gendwarfksyms/gendwarfksyms.c > +++ b/scripts/gendwarfksyms/gendwarfksyms.c > @@ -118,6 +118,8 @@ int main(int argc, const char **argv) > return -1; > } > > + check(symbol_read_symtab(fd)); > + > dwfl = dwfl_begin(&callbacks); > if (!dwfl) { > error("dwfl_begin failed for '%s': %s", object_files[n], > diff --git a/scripts/gendwarfksyms/gendwarfksyms.h b/scripts/gendwarfksyms/gendwarfksyms.h > index 03f3e408a839..cb9106dfddb9 100644 > --- a/scripts/gendwarfksyms/gendwarfksyms.h > +++ b/scripts/gendwarfksyms/gendwarfksyms.h > @@ -61,6 +61,10 @@ extern bool debug; > /* > * symbols.c > */ > +struct symbol_addr { > + uint32_t section; > + Elf64_Addr address; > +}; > > static inline u32 name_hash(const char *name) > { > @@ -69,10 +73,13 @@ static inline u32 name_hash(const char *name) > > struct symbol { > const char *name; > + struct symbol_addr addr; > + struct hlist_node addr_hash; > struct hlist_node name_hash; > }; > > extern int symbol_read_exports(FILE *file); > +extern int symbol_read_symtab(int fd); > extern struct symbol *symbol_get(const char *name); > > /* > diff --git a/scripts/gendwarfksyms/symbols.c b/scripts/gendwarfksyms/symbols.c > index 673ad9cf9e77..f96acb941196 100644 > --- a/scripts/gendwarfksyms/symbols.c > +++ b/scripts/gendwarfksyms/symbols.c > @@ -6,11 +6,43 @@ > #include "gendwarfksyms.h" > > #define SYMBOL_HASH_BITS 15 > + > +/* struct symbol_addr -> struct symbol */ > +static DEFINE_HASHTABLE(symbol_addrs, SYMBOL_HASH_BITS); > +/* name -> struct symbol */ > static DEFINE_HASHTABLE(symbol_names, SYMBOL_HASH_BITS); > > +static inline u32 symbol_addr_hash(const struct symbol_addr *addr) > +{ > + return jhash(addr, sizeof(struct symbol_addr), 0); > +} > + > typedef int (*symbol_callback_t)(struct symbol *, void *arg); > > -static int for_each(const char *name, symbol_callback_t func, void *data) > +static int __for_each_addr(struct symbol *sym, symbol_callback_t func, > + void *data) > +{ > + struct hlist_node *tmp; > + struct symbol *match = NULL; > + int processed = 0; > + > + hash_for_each_possible_safe(symbol_addrs, match, tmp, addr_hash, > + symbol_addr_hash(&sym->addr)) { > + if (match == sym) > + continue; /* Already processed */ > + > + if (match->addr.section == sym->addr.section && > + match->addr.address == sym->addr.address) { > + check(func(match, data)); > + ++processed; > + } > + } > + > + return processed; > +} > + > +static int for_each(const char *name, bool name_only, symbol_callback_t func, > + void *data) > { > struct hlist_node *tmp; > struct symbol *match; > @@ -23,9 +55,13 @@ static int for_each(const char *name, symbol_callback_t func, void *data) > if (strcmp(match->name, name)) > continue; > > + /* Call func for the match, and all address matches */ > if (func) > check(func(match, data)); > > + if (!name_only && match->addr.section != SHN_UNDEF) > + return checkp(__for_each_addr(match, func, data)) + 1; > + > return 1; > } > > @@ -34,7 +70,7 @@ static int for_each(const char *name, symbol_callback_t func, void *data) > > static bool is_exported(const char *name) > { > - return checkp(for_each(name, NULL, NULL)) > 0; > + return checkp(for_each(name, true, NULL, NULL)) > 0; > } > > int symbol_read_exports(FILE *file) > @@ -57,13 +93,14 @@ int symbol_read_exports(FILE *file) > if (is_exported(name)) > continue; /* Ignore duplicates */ > > - sym = malloc(sizeof(struct symbol)); > + sym = calloc(1, sizeof(struct symbol)); I am tired of noise changes when reviewing this patch set. 2/19 added malloc(), which is immediately replaced with calloc() by 3/19. -- Best Regards Masahiro Yamada