Hi Mark,

On Wed, Oct 28, 2026 at 11:22 AM Mark Wielaard <[email protected]> wrote:
>
> Hi Aaron,
>
> On Tue, 2026-10-27 at 20:34 -0400, Aaron Merey wrote:
> > Store a Dwfl_Module's ebl field atomically in __libdwfl_module_getebl
> > while holding the associated Dwfl load_lock.
> >
> > Change usage of the ebl field so that before using it's either been
> > atomically read or else it's used after __libdwfl_module_getebl returns
> > DWFL_E_NOERROR.
>
> Why not always use __libdwfl_module_getebl ?
>
> > Signed-off-by: Aaron Merey <[email protected]>
> > ---
> >  libdwfl/dwfl_module_getdwarf.c              | 24 +++++++++++++++------
> >  libdwfl/dwfl_module_getsym.c                |  3 ++-
> >  libdwfl/dwfl_module_register_names.c        | 11 ++++------
> >  libdwfl/dwfl_module_return_value_location.c | 11 ++++------
> >  4 files changed, 28 insertions(+), 21 deletions(-)
> >
> > diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
> > index 247fbbd2..cb11b1f3 100644
> > --- a/libdwfl/dwfl_module_getdwarf.c
> > +++ b/libdwfl/dwfl_module_getdwarf.c
> > @@ -1345,17 +1345,29 @@ Dwfl_Error
> >  internal_function
> >  __libdwfl_module_getebl (Dwfl_Module *mod)
> >  {
> > +  if (likely (atomic_load_acquire (&mod->ebl) != NULL))
> > +    return DWFL_E_NOERROR;
> > +
> > +  Dwfl_Error ret = DWFL_E_NOERROR;
> > +  mutex_lock (mod->dwfl->load_lock);
> > +
> >    if (mod->ebl == NULL)
> >      {
> >        __libdwfl_getelf (mod);
> > -      if (mod->elferr != DWFL_E_NOERROR)
> > -     return mod->elferr;
> > +      ret = mod->elferr;
> >
> > -      mod->ebl = ebl_openbackend (mod->main.elf);
> > -      if (mod->ebl == NULL)
> > -     return DWFL_E_LIBEBL;
> > +      if (ret == DWFL_E_NOERROR)
> > +     {
> > +       Ebl *ebl = ebl_openbackend (mod->main.elf);
> > +       if (ebl == NULL)
> > +         ret = DWFL_E_LIBEBL;
> > +       else
> > +         atomic_store_release (&mod->ebl, ebl);
> > +     }
> >      }
> > -  return DWFL_E_NOERROR;
> > +
> > +  mutex_unlock (mod->dwfl->load_lock);
> > +  return ret;
> >  }
> >
> >  /* Try to start up libdw on DEBUGFILE.  */
>
> OK, the usual dance.
>
> > diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
> > index 2bb07fd8..4905f019 100644
> > --- a/libdwfl/dwfl_module_getsym.c
> > +++ b/libdwfl/dwfl_module_getsym.c
> > @@ -124,7 +124,8 @@ __libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym 
> > *sym, GElf_Addr *addr,
> >       descriptors).  */
> >
> >    char *ident;
> > -  GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (mod->ebl);
> > +  Ebl *ebl = atomic_load_acquire (&mod->ebl);
> > +  GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (ebl);
> >    *resolved = false;
> >    if (! adjust_st_value && mod->e_type != ET_REL && alloc
> >        && (GELF_ST_TYPE (sym->st_info) == STT_FUNC
>
> So why not use __libdwfl_module_getebl here?

This preserves existing behaviour. If mod->ebl is NULL then the mask
from ebl_func_addr_mask leaves the symbol value unchanged. If we use
__libdwfl_module_getebl then the backend could get initialized early
resulting in a different mask.

Aaron

>
> > diff --git a/libdwfl/dwfl_module_register_names.c 
> > b/libdwfl/dwfl_module_register_names.c
> > index 9ea09371..a8aa8a65 100644
> > --- a/libdwfl/dwfl_module_register_names.c
> > +++ b/libdwfl/dwfl_module_register_names.c
> > @@ -43,14 +43,11 @@ dwfl_module_register_names (Dwfl_Module *mod,
> >    if (unlikely (mod == NULL))
> >      return -1;
> >
> > -  if (unlikely (mod->ebl == NULL))
> > +  Dwfl_Error error = __libdwfl_module_getebl (mod);
> > +  if (unlikely (error != DWFL_E_NOERROR))
> >      {
> > -      Dwfl_Error error = __libdwfl_module_getebl (mod);
> > -      if (error != DWFL_E_NOERROR)
> > -     {
> > -       __libdwfl_seterrno (error);
> > -       return -1;
> > -     }
> > +      __libdwfl_seterrno (error);
> > +      return -1;
> >      }
> >
> >    int nregs = ebl_register_info (mod->ebl, -1, NULL, 0,
>
> OK, __libdwfl_module_getebl simplifies things here.
>
> > diff --git a/libdwfl/dwfl_module_return_value_location.c 
> > b/libdwfl/dwfl_module_return_value_location.c
> > index ff6f56f8..8a3e63a9 100644
> > --- a/libdwfl/dwfl_module_return_value_location.c
> > +++ b/libdwfl/dwfl_module_return_value_location.c
> > @@ -40,14 +40,11 @@ dwfl_module_return_value_location (Dwfl_Module *mod, 
> > Dwarf_Die *functypedie,
> >    if (mod == NULL)
> >      return -1;
> >
> > -  if (mod->ebl == NULL)
> > +  Dwfl_Error error = __libdwfl_module_getebl (mod);
> > +  if (error != DWFL_E_NOERROR)
> >      {
> > -      Dwfl_Error error = __libdwfl_module_getebl (mod);
> > -      if (error != DWFL_E_NOERROR)
> > -     {
> > -       __libdwfl_seterrno (error);
> > -       return -1;
> > -     }
> > +      __libdwfl_seterrno (error);
> > +      return -1;
> >      }
> >
> >    int nops = ebl_return_value_location (mod->ebl, functypedie, locops);
>
> OK, likewise.
>
> Looks ok, except I might be missing something about not using
> __libdwfl_module_getebl in __libdwfl_getsym.
>
> Cheers,
>
> Mark
>

Reply via email to