[PATCH v6 18/20] elf: Issue la_symbind() for bind-now (BZ #23734)

Florian Weimer fweimer@redhat.com
Mon Dec 20 19:18:39 GMT 2021


I believe this change needs to update elf/sotruss-lib.c:

uintptr_t
la_symbind (Elf_Sym *sym, unsigned int ndx, uintptr_t *refcook,
	    uintptr_t *defcook, unsigned int *flags, const char *symname)
{
  if (!do_exit)
    *flags = LA_SYMB_NOPLTEXIT;

  return sym->st_value;
}

* Adhemerval Zanella:

> diff --git a/elf/Makefile b/elf/Makefile
> index ee4daae0fc..acce163078 100644
> --- a/elf/Makefile
> +++ b/elf/Makefile

> +# The test check if a library without .gnu.version correctly calls the
> +# audit callbacks.  So it uses an explicit link rule to avoid linking
> +# against libc.so.
> +$(objpfx)tst-audit24bmod1.so: $(objpfx)tst-audit24bmod1.os
> +	$(CC) -nostdlib -nostartfiles -shared -o $@.new $(objpfx)tst-audit24bmod1.os \
> +	  -Wl,-z,now
> +	$(call after-link,$@.new)
> +	mv -f $@.new $@

I think you may have to update modules-names-nobuild as well.

>  # tst-sonamemove links against an older implementation of the library.
>  LDFLAGS-tst-sonamemove-linkmod1.so = \
>    -Wl,--version-script=tst-sonamemove-linkmod1.map \
> diff --git a/elf/dl-audit.c b/elf/dl-audit.c
> index c3569cb357..f080591596 100644
> --- a/elf/dl-audit.c
> +++ b/elf/dl-audit.c
> @@ -190,7 +190,7 @@ rtld_hidden_def (_dl_audit_symbind_alt)
>  void
>  _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>  		   const ElfW(Sym) *defsym, DL_FIXUP_VALUE_TYPE *value,
> -		   lookup_t result)
> +		   lookup_t result, bool bindnow)
>  {

Should “bindow“ be called “for_jmp_slot”?

> @@ -229,16 +230,16 @@ _dl_audit_symbind (struct link_map *l, struct reloc_result *reloc_result,
>  	{
>  	  if (afct->symbind != NULL)
>  	    {
> -	      uintptr_t new_value = afct->symbind (&sym,
> -						   reloc_result->boundndx,
> -						   &l_state->cookie,
> -						   &result_state->cookie,
> -						   &flags,
> -						   strtab2 + defsym->st_name);
> +	      flags |= bindnow ? LA_SYMB_NOPLTENTER | LA_SYMB_NOPLTEXIT : 0;
> +	      new_value = afct->symbind (&sym, reloc_result->boundndx,
> +					 &l_state->cookie,
> +					 &result_state->cookie, &flags,
> +					 strtab2 + defsym->st_name);
>  	      if (new_value != (uintptr_t) sym.st_value)
>  		{
>  		  flags |= LA_SYMB_ALTVALUE;
> -		  sym.st_value = new_value;
> +		  sym.st_value = bindnow
> +		    ? DL_FIXUP_BINDNOW_ADDR_VALUE (new_value) : new_value;
>  		}
>  	    }

We could error out if the audit callback clears the LA_SYMB_NOPLT* flags
we've set (after fixing sotruss).

And then we'll have to make this change conditional on the la_version
return value, I think.

> --- a/elf/dl-reloc.c
> +++ b/elf/dl-reloc.c
> @@ -234,9 +234,7 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
>  
>    /* If DT_BIND_NOW is set relocate all references in this object.  We
>       do not do this if we are profiling, of course.  */
> -  // XXX Correct for auditing?
> -  if (!consider_profiling
> -      && __builtin_expect (l->l_info[DT_BIND_NOW] != NULL, 0))
> +  if (!consider_profiling && l->l_info[DT_BIND_NOW] != NULL)
>      lazy = 0;
>  
>    if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_RELOC))
> @@ -285,8 +283,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
>    {
>      /* Do the actual relocation of the object's GOT and other data.  */
>  
> -    ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
> -
>  #ifndef PROF
>      if (consider_profiling | consider_symbind
>  	&& l->l_info[DT_PLTRELSZ] != NULL)
> @@ -309,6 +305,8 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
>  	  }
>        }
>  #endif
> +
> +    ELF_DYNAMIC_RELOCATE (l, scope, lazy, consider_profiling, skip_ifunc);
>    }

I don't understand why this is needed.  Can we indeed use the profiling
trampoline with a BIND_NOW binding?  If not, then we shouldn't need the
allocation of l_reloc_result, either.  We should patch in the changed
symbol variable directly, not going through l_reloc_result.

Thanks,
Florian



More information about the Libc-alpha mailing list