Hi Aaron, On Fri, 2026-10-30 at 01:16 -0400, Aaron Merey wrote: > Move cache_sections' reloc_info initialization code into new function > cache_sections_locked, which cache_sections calls while holding > dwfl->load_lock. > > Atomics are used to acquire intitialized reloc_info without needing to > obtain the load_lock.
Looks correct to me. cache_sections_locked now doesn't manupulate the Dwfl_Module reloc_info structure directly. Thanks, Mark > Signed-off-by: Aaron Merey <[email protected]> > --- > libdwfl/derelocate.c | 53 ++++++++++++++++++++++++++++++++------------ > 1 file changed, 39 insertions(+), 14 deletions(-) > > diff --git a/libdwfl/derelocate.c b/libdwfl/derelocate.c > index 2f80b20f..f9dbbe55 100644 > --- a/libdwfl/derelocate.c > +++ b/libdwfl/derelocate.c > @@ -77,13 +77,11 @@ compare_secrefs (const void *a, const void *b) > } > > static int > -cache_sections (Dwfl_Module *mod) > +cache_sections_locked (Dwfl_Module *mod, struct dwfl_relocation **result) > { > - if (likely (mod->reloc_info != NULL)) > - return mod->reloc_info->count; > - > struct secref *refs = NULL; > size_t nrefs = 0; > + struct dwfl_relocation *reloc_info = NULL; > > size_t shstrndx; > if (unlikely (elf_getshdrstrndx (mod->main.elf, &shstrndx) < 0)) > @@ -165,8 +163,8 @@ cache_sections (Dwfl_Module *mod) > } > } > > - mod->reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs])); > - if (unlikely (mod->reloc_info == NULL)) > + reloc_info = malloc (offsetof (struct dwfl_relocation, refs[nrefs])); > + if (unlikely (reloc_info == NULL)) > goto nomem; > > struct secref **sortrefs = malloc (nrefs * sizeof sortrefs[0]); > @@ -179,14 +177,14 @@ cache_sections (Dwfl_Module *mod) > > qsort (sortrefs, nrefs, sizeof sortrefs[0], &compare_secrefs); > > - mod->reloc_info->count = nrefs; > + reloc_info->count = nrefs; > for (size_t i = 0; i < nrefs; ++i) > { > - mod->reloc_info->refs[i].name = sortrefs[i]->name; > - mod->reloc_info->refs[i].scn = sortrefs[i]->scn; > - mod->reloc_info->refs[i].relocs = sortrefs[i]->relocs; > - mod->reloc_info->refs[i].start = sortrefs[i]->start; > - mod->reloc_info->refs[i].end = sortrefs[i]->end; > + reloc_info->refs[i].name = sortrefs[i]->name; > + reloc_info->refs[i].scn = sortrefs[i]->scn; > + reloc_info->refs[i].relocs = sortrefs[i]->relocs; > + reloc_info->refs[i].start = sortrefs[i]->start; > + reloc_info->refs[i].end = sortrefs[i]->end; > free (sortrefs[i]); > } > > @@ -212,16 +210,20 @@ cache_sections (Dwfl_Module *mod) > Elf_Scn *tscn = elf_getscn (mod->main.elf, shdr->sh_info); > if (likely (tscn != NULL)) > for (size_t i = 0; i < nrefs; ++i) > - if (mod->reloc_info->refs[i].scn == tscn) > + if (reloc_info->refs[i].scn == tscn) > { > - mod->reloc_info->refs[i].relocs = scn; > + reloc_info->refs[i].relocs = scn; > break; > } > } > } > } > > + *result = reloc_info; > + reloc_info = NULL; > + > free_refs: > + free (reloc_info); > while (refs != NULL) > { > struct secref *ref = refs; > @@ -232,6 +234,29 @@ free_refs: > return nrefs; > } > > +static int > +cache_sections (Dwfl_Module *mod) > +{ > + if (likely (atomic_load_acquire (&mod->reloc_info) != NULL)) > + return mod->reloc_info->count; > + > + int count; > + mutex_lock (mod->dwfl->load_lock); > + > + if (mod->reloc_info == NULL) > + { > + struct dwfl_relocation *reloc_info = NULL; > + count = cache_sections_locked (mod, &reloc_info); > + if (count >= 0) > + atomic_store_release (&mod->reloc_info, reloc_info); > + } > + else > + count = mod->reloc_info->count; > + > + mutex_unlock (mod->dwfl->load_lock); > + return count; > +} > + > > int > dwfl_module_relocations (Dwfl_Module *mod)
