On Wed, Oct 21, 2020 at 11:32:13AM +0200, Peter Zijlstra wrote: > On Wed, Oct 21, 2020 at 10:56:06AM +0200, Peter Zijlstra wrote: > > > I do not see these in particular, although I do see a lot of: > > > > "sibling call from callable instruction with modified stack frame" > > defconfig-build/vmlinux.o: warning: objtool: msr_write()+0x10a: sibling call from callable instruction with modified stack frame > defconfig-build/vmlinux.o: warning: objtool: msr_write()+0x99: (branch) > defconfig-build/vmlinux.o: warning: objtool: msr_write()+0x3e: (branch) > defconfig-build/vmlinux.o: warning: objtool: msr_write()+0x0: <=== (sym) > > $ nm defconfig-build/vmlinux.o | grep msr_write > 0000000000043250 t msr_write > 00000000004289c0 T msr_write > 0000000000003056 t msr_write.cold > > Below 'fixes' it. So this is also caused by duplicate symbols. There's a new linker flag for renaming duplicates: https://sourceware.org/bugzilla/show_bug.cgi?id=26391 But I guess that doesn't help us now. I don't have access to GCC 10 at the moment so I can't recreate it. Does this fix it? diff --git a/tools/objtool/elf.c b/tools/objtool/elf.c index 4e1d7460574b..aecdf25b2381 100644 --- a/tools/objtool/elf.c +++ b/tools/objtool/elf.c @@ -217,11 +217,14 @@ struct symbol *find_func_containing(struct section *sec, unsigned long offset) return NULL; } +#define for_each_possible_sym(elf, name, sym) \ + elf_hash_for_each_possible(elf->symbol_name_hash, sym, name_hash, str_hash(name)) + struct symbol *find_symbol_by_name(const struct elf *elf, const char *name) { struct symbol *sym; - elf_hash_for_each_possible(elf->symbol_name_hash, sym, name_hash, str_hash(name)) + for_each_possible_sym(elf, name, sym) if (!strcmp(sym->name, name)) return sym; @@ -432,6 +435,8 @@ static int read_symbols(struct elf *elf) list_for_each_entry(sym, &sec->symbol_list, list) { char pname[MAX_NAME_LEN + 1]; size_t pnamelen; + struct symbol *psym; + if (sym->type != STT_FUNC) continue; @@ -454,8 +459,14 @@ static int read_symbols(struct elf *elf) strncpy(pname, sym->name, pnamelen); pname[pnamelen] = '\0'; - pfunc = find_symbol_by_name(elf, pname); - + pfunc = NULL; + for_each_possible_sym(elf, pname, psym) { + if ((!psym->cfunc || psym->cfunc == psym) && + !strcmp(psym->name, pname)) { + pfunc = psym; + break; + } + } if (!pfunc) { WARN("%s(): can't find parent function", sym->name);