>From 21faaf1a1d342f02d2528453470eb0c15aaa2cbe Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Mon, 8 Dec 2025 19:03:18 +0000 Subject: [PATCH] reloc sym lookup stats --- ldso/dynlink.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 715948f4..6bbaa850 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -157,6 +157,19 @@ static struct dso **main_ctor_queue; static struct fdpic_loadmap *app_loadmap; static struct fdpic_dummy_loadmap app_dummy_loadmap; +struct rstat { + unsigned long n; // sum find_sym calls + unsigned long symlen; // sum strlen of refd syms + unsigned long lookup; // sum visited dsos in find_sym iter + unsigned long bloomfail; // sum bloom filter check fails + unsigned long hashchain; // sum visited hash chain + unsigned long nstrcmp; // sum strcmp calls +}; +static struct rstat rsc; // current rs, until reloc is resolved +static struct rstat rs[6]; // resolved counts under various cases +static unsigned long sysvonly; +static int prev_sym_index; + struct debug *_dl_debug_addr = &debug; extern weak hidden char __ehdr_start[]; @@ -172,6 +185,7 @@ weak_alias(__fini_array_start, __fini_array_end); static int dl_strcmp(const char *l, const char *r) { + rsc.nstrcmp++; for (; *l==*r && *l; l++, r++); return *(unsigned char *)l - *(unsigned char *)r; } @@ -279,6 +293,7 @@ static Sym *gnu_lookup(uint32_t h1, uint32_t *hashtab, struct dso *dso, const ch uint32_t *hashval = buckets + nbuckets + (i - hashtab[1]); for (h1 |= 1; ; i++) { + rsc.hashchain++; uint32_t h2 = *hashval++; if ((h1 == (h2|1)) && (!dso->versym || dso->versym[i] >= 0) && !strcmp(s, dso->strings + dso->syms[i].st_name)) @@ -298,7 +313,9 @@ static Sym *gnu_lookup_filtered(uint32_t h1, uint32_t *hashtab, struct dso *dso, f >>= (h1 >> hashtab[3]) % (8 * sizeof f); if (!(f & 1)) return 0; - return gnu_lookup(h1, hashtab, dso, s); + void *p = gnu_lookup(h1, hashtab, dso, s); + if (!p) rsc.bloomfail++; + return p; } #define OK_TYPES (1<deps : 0; for (; dso; dso=use_deps ? *deps++ : dso->syms_next) { Sym *sym; + rsc.lookup++; if ((ght = dso->ghashtab)) { sym = gnu_lookup_filtered(gh, ght, dso, s, gho, ghm); } else { + sysvonly++; if (!h) h = sysv_hash(s); sym = sysv_lookup(s, h, dso); } @@ -400,6 +421,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri skip_relative = 1; } + prev_sym_index = 0; for (; rel_size; rel+=stride, rel_size-=stride*sizeof(size_t)) { if (skip_relative && IS_RELATIVE(rel[1], dso->syms)) continue; type = R_TYPE(rel[1]); @@ -426,9 +448,33 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri sym = syms + sym_index; name = strings + sym->st_name; ctx = type==REL_COPY ? head->syms_next : head; - def = (sym->st_info>>4) == STB_LOCAL - ? (struct symdef){ .dso = dso, .sym = sym } - : find_sym(ctx, name, type==REL_PLT); + if ((sym->st_info>>4) == STB_LOCAL) { + def = (struct symdef){ .dso = dso, .sym = sym }; + } else { +#define F(x) r->x += rsc.x + struct rstat *r = rs + 4; // lfs64, etc counts + F(n); + F(symlen); + F(lookup); + F(bloomfail); + F(hashchain); + F(nstrcmp); + rsc = (struct rstat){0}; + + def = find_sym(ctx, name, type==REL_PLT); + int rep = prev_sym_index == sym_index; + int loc = def.dso == dso; + prev_sym_index = sym_index; + r = rs + rep + loc*2; // repeat and local counts + F(n); + F(symlen); + F(lookup); + F(bloomfail); + F(hashchain); + F(nstrcmp); + rsc = (struct rstat){0}; +#undef F + } if (!def.sym) def = get_lfs64(name); if (!def.sym && (sym->st_shndx != SHN_UNDEF || sym->st_info>>4 != STB_WEAK)) { @@ -2043,6 +2089,43 @@ void __dls3(size_t *sp, size_t *auxv) libc.tls_size = tmp_tls_size; } + if (ldd_mode) { + const char *rcase[] = { + "!r !l:", + " r !l:", + "!r l:", + " r l:", + "other:", + "total:"}; + for (int i=0; i<5; i++) { +#define F(x) rs[5].x += rs[i].x + F(n); + F(symlen); + F(lookup); + F(bloomfail); + F(hashchain); + F(nstrcmp); +#undef F + } + dprintf(1,"total sysvonly lookups: %lu\n", sysvonly); + for (int i=0; i<6; i++) { + dprintf(1,"%s n %5lu %4.1f%% slen %4.2f %4.1f%% iter %.2f" + " ff %.2f hc %.2f cmp %.2f\n", + rcase[i], +#define F(x) ((double)rs[i].x/rs[i].n) +#define G(x) ((double)100*rs[i].x/rs[5].x) + rs[i].n, + G(n), + F(symlen), + G(symlen), + F(lookup), + F(bloomfail), + F(hashchain), + F(nstrcmp)); +#undef F +#undef G + } + } if (ldso_fail) _exit(127); if (ldd_mode) _exit(0); -- 2.47.2