From cdd5bf9071b78676982f1f3d3870163963d7a535 Mon Sep 17 00:00:00 2001 From: Fabian Rast Date: Sat, 21 Mar 2026 18:55:55 +0100 Subject: [PATCH v2] ldso: skip repeated symbol lookups for sorted relocations When relocations are sorted by symbol index (-z combreloc), only do symbol lookup for the first relocation against a given symbol. Following relocations against the same symbol reuse the result. Exceptions are copy and plt relocations because they have unique lookup behavior. --- ldso/dynlink.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/ldso/dynlink.c b/ldso/dynlink.c index 715948f4..c79ba834 100644 --- a/ldso/dynlink.c +++ b/ldso/dynlink.c @@ -385,7 +385,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri const char *name; void *ctx; int type; - int sym_index; + int sym_index, prev_sym_index = 0; struct symdef def; size_t *reloc_addr; size_t sym_val; @@ -425,11 +425,15 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri if (sym_index) { sym = syms + sym_index; name = strings + sym->st_name; + int cache_lookup = type!=REL_COPY && type!=REL_PLT; 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 (!def.sym) def = get_lfs64(name); + if (prev_sym_index != sym_index || !cache_lookup) { + def = (sym->st_info>>4) == STB_LOCAL + ? (struct symdef){ .dso = dso, .sym = sym } + : find_sym(ctx, name, type==REL_PLT); + if (!def.sym) def = get_lfs64(name); + prev_sym_index = cache_lookup ? sym_index : 0; + } if (!def.sym && (sym->st_shndx != SHN_UNDEF || sym->st_info>>4 != STB_WEAK)) { if (dso->lazy && (type==REL_PLT || type==REL_GOT)) { @@ -448,6 +452,7 @@ static void do_relocs(struct dso *dso, size_t *rel, size_t rel_size, size_t stri sym = 0; def.sym = 0; def.dso = dso; + prev_sym_index = 0; } sym_val = def.sym ? (size_t)laddr(def.dso, def.sym->st_value) : 0; -- 2.53.0