From c92684faecd3d11e4096ab2b045e8e95d243bb6b Mon Sep 17 00:00:00 2001 From: "liang.huang" Date: Sat, 25 Jul 2026 13:30:13 +0800 Subject: [PATCH] libs/libc/symtab: fix bogus symbol size under SYMTAB_ORDEREDBYNAME allsyms_lookup() derived a symbol's size from the physically next table entry, assuming address order. Under CONFIG_SYMTAB_ORDEREDBYNAME the table is sorted by name instead, producing a huge bogus size in %pS/backtrace output. Scan for the closest larger address instead of relying on table order. Signed-off-by: liang.huang Assisted-by: Claude Code:claude-sonnet-5 --- libs/libc/symtab/symtab_allsyms.c | 34 ++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/libs/libc/symtab/symtab_allsyms.c b/libs/libc/symtab/symtab_allsyms.c index 7e66533bf63..5cd856929f3 100644 --- a/libs/libc/symtab/symtab_allsyms.c +++ b/libs/libc/symtab/symtab_allsyms.c @@ -75,7 +75,38 @@ allsyms_lookup(FAR const char *name, FAR void *value, } } - if (symbol && symbol != &g_allsyms[g_nallsyms - 1]) + if (symbol == NULL) + { + *size = 0; + return NULL; + } + +#ifdef CONFIG_SYMTAB_ORDEREDBYNAME + /* g_allsyms is sorted by name here, not by value, so the physically + * next table entry is not necessarily the next symbol by address. + * Scan the real symbols (index 1..g_nallsyms - 2; 0 and g_nallsyms - 1 + * are the boundary sentinels) for the smallest address greater than + * this symbol's, falling back to the high sentinel's now-meaningful + * value if none is closer. + */ + + { + FAR const struct symtab_s *next = &g_allsyms[g_nallsyms - 1]; + int i; + + for (i = 1; i < g_nallsyms - 1; i++) + { + if (g_allsyms[i].sym_value > symbol->sym_value && + g_allsyms[i].sym_value < next->sym_value) + { + next = &g_allsyms[i]; + } + } + + *size = next->sym_value - symbol->sym_value; + } +#else + if (symbol != &g_allsyms[g_nallsyms - 1]) { *size = (symbol + 1)->sym_value - symbol->sym_value; } @@ -83,6 +114,7 @@ allsyms_lookup(FAR const char *name, FAR void *value, { *size = 0; } +#endif return symbol; }