On Thu, Feb 20, 2025 at 10:33 AM Song Liu <s...@kernel.org> wrote: > > > On Thu, Feb 20, 2025 at 10:22 AM Josh Poimboeuf <jpoim...@kernel.org> wrote: >> >> On Wed, Feb 19, 2025 at 08:50:09PM -0800, Song Liu wrote: >> > Indu, is this behavior (symbols with same name are not in >> > sorted order from readelf -s) expected? Or is this a bug? >> > I am using this gcc: >> > >> > $ gcc --version >> > gcc (GCC) 14.2.1 20240801 (Red Hat 14.2.1-1) >> > Copyright (C) 2024 Free Software Foundation, Inc. >> > This is free software; see the source for copying conditions. There is NO >> > warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. >> >> Are you using different binutils versions as well? > > > I am using binutil 2.41, for both gcc -11 and gcc-14. > >> >> It sounds like a linker "issue" to me. I'm not sure if it qualifies as >> a bug, the linker might be free to layout symbols how it wishes. > > > We can probably handle that in kpatch-build.
OK, something like the following gets the proper sympos for gcc-14 built kernel. Thanks, Song diff --git i/kpatch-build/lookup.c w/kpatch-build/lookup.c index bd2b732de910..87ac127184c5 100644 --- i/kpatch-build/lookup.c +++ w/kpatch-build/lookup.c @@ -479,13 +479,10 @@ static bool lookup_local_symbol(struct lookup_table *table, struct object_symbol *sym; unsigned long sympos = 0; int i, in_file = 0; + bool found = false; memset(result, 0, sizeof(*result)); for_each_obj_symbol(i, sym, table) { - if (sym->bind == STB_LOCAL && !strcmp(sym->name, - lookup_sym->name)) - sympos++; - if (lookup_sym->lookup_table_file_sym == sym) { in_file = 1; continue; @@ -499,20 +496,29 @@ static bool lookup_local_symbol(struct lookup_table *table, if (sym->bind == STB_LOCAL && !strcmp(sym->name, lookup_sym->name)) { - if (result->objname) + if (found) ERROR("duplicate local symbol found for %s", lookup_sym->name); result->objname = table->objname; result->addr = sym->addr; result->size = sym->size; - result->sympos = sympos; result->global = false; result->exported = false; + found = true; } } + if (!found) + return false; - return !!result->objname; + for_each_obj_symbol(i, sym, table) { + if (sym->bind == STB_LOCAL && + !strcmp(sym->name, lookup_sym->name) && + sym->addr < result->addr) + sympos++; + } + result->sympos = sympos; + return true; } static bool lookup_exported_symbol(struct lookup_table *table, char *name,