... and thus typically also a size. Using global vs local is undesirable in certain situations, e.g. when a "real" symbol is local and at the same address as a section start/end one (which are all global).
Note that for xen.efi the checking for "Function" is only forward- looking at this point: The function-ness of symbols (much like their size) is lost when linking PE/COFF binaries from ELF objects with GNU ld up to at least 2.44. Signed-off-by: Jan Beulich <jbeul...@suse.com> --- I didn't see much reason to also check for "Pointer" and "Array" or any of the basic types. While nm reports pointers and arrays (but not the basic types) for PE/COFF, making those up when linker input is ELF would be impossible without further auxiliary (and non-standard) data in the ELF symbol table. Transforming STT_FUNC, otoh, is in principle possible. Implicit from the above: Until GNU ld properly transforms STT_FUNC, symbol conflicts will be resolved differently for functions. Symbol conflicts will always be resolved differently for data. xen.efi stack traces may therefore be less informative than xen-syms ones. --- v2: New. --- a/xen/tools/symbols.c +++ b/xen/tools/symbols.c @@ -45,6 +45,7 @@ struct sym_entry { unsigned int addr_idx; unsigned int stream_offset; unsigned char type; + bool typed; }; #define SYMBOL_NAME(s) ((char *)(s)->sym + 1) @@ -180,6 +181,9 @@ static int read_symbol(FILE *in, struct s->type = stype; /* As s->sym[0] ends mangled. */ } s->sym[0] = stype; + s->typed = strcmp(type, "FUNC") == 0 || + strcmp(type, "OBJECT") == 0 || + strcmp(type, "Function") == 0; rc = 0; skip_tail: @@ -613,6 +617,13 @@ static int compare_value(const void *p1, return -1; if (sym1->addr > sym2->addr) return +1; + + /* Prefer symbols which have a type. */ + if (sym1->typed && !sym2->typed) + return -1; + if (sym2->typed && !sym1->typed) + return +1; + /* Prefer global symbols. */ if (isupper(*sym1->sym)) return -1;