Hi Aaron,

On Fri, 2026-10-30 at 01:16 -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.
> 
> In __libdwfl_getsym also initialize the backend before calling
> ebl_func_addr_mask and return early if it fails.
> 
> Also fix a bug where ebl wasn't initialized before calling
> ebl_func_addr_mask.
> 
> Signed-off-by: Aaron Merey <[email protected]>
> ---
> v2 changes: Initialize the backend before calling ebl_func_addr_mask.

In __libdwfl_getsym. This makes the code cleaner/simpler. Looks good.

Thanks,

Mark

>  libdwfl/dwfl_module_getdwarf.c              | 24 +++++++++++++++------
>  libdwfl/dwfl_module_getsym.c                | 24 ++++++++++++---------
>  libdwfl/dwfl_module_register_names.c        | 11 ++++------
>  libdwfl/dwfl_module_return_value_location.c | 11 ++++------
>  4 files changed, 40 insertions(+), 30 deletions(-)
> 
> diff --git a/libdwfl/dwfl_module_getdwarf.c b/libdwfl/dwfl_module_getdwarf.c
> index 77af5189..8420ba20 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.  */
> diff --git a/libdwfl/dwfl_module_getsym.c b/libdwfl/dwfl_module_getsym.c
> index 2bb07fd8..3a364a76 100644
> --- a/libdwfl/dwfl_module_getsym.c
> +++ b/libdwfl/dwfl_module_getsym.c
> @@ -123,6 +123,13 @@ __libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym 
> *sym, GElf_Addr *addr,
>       might know where the real value is (e.g. for function
>       descriptors).  */
>  
> +  Dwfl_Error error = __libdwfl_module_getebl (mod);
> +  if (unlikely (error != DWFL_E_NOERROR))
> +    {
> +      __libdwfl_seterrno (error);
> +      return NULL;
> +    }
> +
>    char *ident;
>    GElf_Addr st_value = sym->st_value & ebl_func_addr_mask (mod->ebl);
>    *resolved = false;
> @@ -132,18 +139,15 @@ __libdwfl_getsym (Dwfl_Module *mod, int ndx, GElf_Sym 
> *sym, GElf_Addr *addr,
>             && (ident = elf_getident (elf, NULL)) != NULL
>             && ident[EI_OSABI] == ELFOSABI_LINUX)))
>      {
> -      if (likely (__libdwfl_module_getebl (mod) == DWFL_E_NOERROR))
> +      if (elf != mod->main.elf)
>       {
> -       if (elf != mod->main.elf)
> -         {
> -           st_value = dwfl_adjusted_st_value (mod, elf, st_value);
> -           st_value = dwfl_deadjust_st_value (mod, mod->main.elf, st_value);
> -         }
> -
> -       *resolved = ebl_resolve_sym_value (mod->ebl, &st_value);
> -       if (! *resolved)
> -         st_value = sym->st_value;
> +       st_value = dwfl_adjusted_st_value (mod, elf, st_value);
> +       st_value = dwfl_deadjust_st_value (mod, mod->main.elf, st_value);
>       }
> +
> +      *resolved = ebl_resolve_sym_value (mod->ebl, &st_value);
> +      if (! *resolved)
> +     st_value = sym->st_value;
>      }
>  
>    if (shndxp != NULL)
> 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,
> 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);

Reply via email to