This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH 2/4] elf: Extract _dl_sym_post, _dl_sym_find_caller_map from elf/dl-sym.c


On 2/8/20 2:01 PM, Florian Weimer wrote:
> The definitions are moved into a new file, elf/dl-sym-post.h, so that
> this code can be used by the dynamic loader as well.

OK for master. I like the cleanup.

Reviewed-by: Carlos O'Donell <carlos@redhat.com>

> ---
>  elf/dl-sym-post.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++
>  elf/dl-sym.c      |  86 ++-----------------------------------
>  2 files changed, 110 insertions(+), 82 deletions(-)
>  create mode 100644 elf/dl-sym-post.h
> 
> diff --git a/elf/dl-sym-post.h b/elf/dl-sym-post.h
> new file mode 100644
> index 0000000000..4c4f574633
> --- /dev/null
> +++ b/elf/dl-sym-post.h
> @@ -0,0 +1,106 @@
> +/* Post-processing of a symbol produced by dlsym, dlvsym.
> +   Copyright (C) 1999-2020 Free Software Foundation, Inc.
> +   This file is part of the GNU C Library.
> +
> +   The GNU C Library is free software; you can redistribute it and/or
> +   modify it under the terms of the GNU Lesser General Public
> +   License as published by the Free Software Foundation; either
> +   version 2.1 of the License, or (at your option) any later version.
> +
> +   The GNU C Library is distributed in the hope that it will be useful,
> +   but WITHOUT ANY WARRANTY; without even the implied warranty of
> +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> +   Lesser General Public License for more details.
> +
> +   You should have received a copy of the GNU Lesser General Public
> +   License along with the GNU C Library; if not, see
> +   <https://www.gnu.org/licenses/>.  */
> +
> +
> +/* Return the link map containing the caller address.  */
> +static struct link_map *
> +_dl_sym_find_caller_link_map (ElfW(Addr) caller)
> +{
> +  struct link_map *l = _dl_find_dso_for_object (caller);
> +  if (l != NULL)
> +    return l;
> +  else
> +    /* If the address is not recognized the call comes from the main
> +       program (we hope).  */
> +    return GL(dl_ns)[LM_ID_BASE]._ns_loaded;
> +}

OK.

> +
> +/* Translates RESULT, *REF, VALUE into a symbol address from the point
> +   of view of MATCH.  Performs IFUNC resolution and auditing if
> +   necessary.  If MATCH is NULL, CALLER is used to determine it.  */
> +static void *
> +_dl_sym_post (lookup_t result, const ElfW(Sym) *ref, void *value,
> +              ElfW(Addr) caller, struct link_map *match)
> +{
> +  /* Resolve indirect function address.  */
> +  if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC))
> +    {
> +      DL_FIXUP_VALUE_TYPE fixup
> +        = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value);
> +      fixup = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (fixup));
> +      value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup);
> +    }
> +
> +#ifdef SHARED
> +  /* Auditing checkpoint: we have a new binding.  Provide the
> +     auditing libraries the possibility to change the value and
> +     tell us whether further auditing is wanted.  */
> +  if (__glibc_unlikely (GLRO(dl_naudit) > 0))
> +    {
> +      const char *strtab = (const char *) D_PTR (result,
> +                                                 l_info[DT_STRTAB]);
> +      /* Compute index of the symbol entry in the symbol table of
> +         the DSO with the definition.  */
> +      unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
> +                                                     l_info[DT_SYMTAB]));
> +
> +      if (match == NULL)
> +        match = _dl_sym_find_caller_link_map (caller);
> +
> +      if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
> +        {
> +          unsigned int altvalue = 0;
> +          struct audit_ifaces *afct = GLRO(dl_audit);
> +          /* Synthesize a symbol record where the st_value field is
> +             the result.  */
> +          ElfW(Sym) sym = *ref;
> +          sym.st_value = (ElfW(Addr)) value;
> +
> +          for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
> +            {
> +              struct auditstate *match_audit
> +                = link_map_audit_state (match, cnt);
> +              struct auditstate *result_audit
> +                = link_map_audit_state (result, cnt);
> +              if (afct->symbind != NULL
> +                  && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
> +                      || ((result_audit->bindflags & LA_FLG_BINDTO)
> +                          != 0)))
> +                {
> +                  unsigned int flags = altvalue | LA_SYMB_DLSYM;
> +                  uintptr_t new_value
> +                    = afct->symbind (&sym, ndx,
> +                                     &match_audit->cookie,
> +                                     &result_audit->cookie,
> +                                     &flags, strtab + ref->st_name);
> +                  if (new_value != (uintptr_t) sym.st_value)
> +                    {
> +                      altvalue = LA_SYMB_ALTVALUE;
> +                      sym.st_value = new_value;
> +                    }
> +                }
> +
> +              afct = afct->next;
> +            }
> +
> +          value = (void *) sym.st_value;
> +        }
> +    }
> +#endif
> +  return value;
> +}

OK.

> diff --git a/elf/dl-sym.c b/elf/dl-sym.c
> index b43a50e544..361b926ea9 100644
> --- a/elf/dl-sym.c
> +++ b/elf/dl-sym.c
> @@ -28,6 +28,7 @@
>  #include <sysdep-cancel.h>
>  #include <dl-tls.h>
>  #include <dl-irel.h>
> +#include <dl-sym-post.h>
>  
>  
>  #ifdef SHARED
> @@ -80,19 +81,6 @@ call_dl_lookup (void *ptr)
>  					args->flags, NULL);
>  }
>  
> -/* Return the link map containing the caller address.  */
> -static inline struct link_map *
> -find_caller_link_map (ElfW(Addr) caller)
> -{
> -  struct link_map *l = _dl_find_dso_for_object (caller);
> -  if (l != NULL)
> -    return l;
> -  else
> -    /* If the address is not recognized the call comes from the main
> -       program (we hope).  */
> -    return GL(dl_ns)[LM_ID_BASE]._ns_loaded;
> -}
> -
>  static void *
>  do_sym (void *handle, const char *name, void *who,
>  	struct r_found_version *vers, int flags)
> @@ -106,7 +94,7 @@ do_sym (void *handle, const char *name, void *who,
>  
>    if (handle == RTLD_DEFAULT)
>      {
> -      match = find_caller_link_map (caller);
> +      match = _dl_sym_find_caller_link_map (caller);
>  
>        /* Search the global scope.  We have the simple case where
>  	 we look up in the scope of an object which was part of
> @@ -140,7 +128,7 @@ do_sym (void *handle, const char *name, void *who,
>      }
>    else if (handle == RTLD_NEXT)
>      {
> -      match = find_caller_link_map (caller);
> +      match = _dl_sym_find_caller_link_map (caller);
>  
>        if (__glibc_unlikely (match == GL(dl_ns)[LM_ID_BASE]._ns_loaded))
>  	{
> @@ -179,73 +167,7 @@ RTLD_NEXT used in code not dynamically loaded"));
>  #endif
>  	value = DL_SYMBOL_ADDRESS (result, ref);
>  
> -      /* Resolve indirect function address.  */
> -      if (__glibc_unlikely (ELFW(ST_TYPE) (ref->st_info) == STT_GNU_IFUNC))
> -	{
> -	  DL_FIXUP_VALUE_TYPE fixup
> -	    = DL_FIXUP_MAKE_VALUE (result, (ElfW(Addr)) value);
> -	  fixup = elf_ifunc_invoke (DL_FIXUP_VALUE_ADDR (fixup));
> -	  value = (void *) DL_FIXUP_VALUE_CODE_ADDR (fixup);
> -	}
> -
> -#ifdef SHARED
> -      /* Auditing checkpoint: we have a new binding.  Provide the
> -	 auditing libraries the possibility to change the value and
> -	 tell us whether further auditing is wanted.  */
> -      if (__glibc_unlikely (GLRO(dl_naudit) > 0))
> -	{
> -	  const char *strtab = (const char *) D_PTR (result,
> -						     l_info[DT_STRTAB]);
> -	  /* Compute index of the symbol entry in the symbol table of
> -	     the DSO with the definition.  */
> -	  unsigned int ndx = (ref - (ElfW(Sym) *) D_PTR (result,
> -							 l_info[DT_SYMTAB]));
> -
> -	  if (match == NULL)
> -	    match = find_caller_link_map (caller);
> -
> -	  if ((match->l_audit_any_plt | result->l_audit_any_plt) != 0)
> -	    {
> -	      unsigned int altvalue = 0;
> -	      struct audit_ifaces *afct = GLRO(dl_audit);
> -	      /* Synthesize a symbol record where the st_value field is
> -		 the result.  */
> -	      ElfW(Sym) sym = *ref;
> -	      sym.st_value = (ElfW(Addr)) value;
> -
> -	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
> -		{
> -		  struct auditstate *match_audit
> -		    = link_map_audit_state (match, cnt);
> -		  struct auditstate *result_audit
> -		    = link_map_audit_state (result, cnt);
> -		  if (afct->symbind != NULL
> -		      && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
> -			  || ((result_audit->bindflags & LA_FLG_BINDTO)
> -			      != 0)))
> -		    {
> -		      unsigned int flags = altvalue | LA_SYMB_DLSYM;
> -		      uintptr_t new_value
> -			= afct->symbind (&sym, ndx,
> -					 &match_audit->cookie,
> -					 &result_audit->cookie,
> -					 &flags, strtab + ref->st_name);
> -		      if (new_value != (uintptr_t) sym.st_value)
> -			{
> -			  altvalue = LA_SYMB_ALTVALUE;
> -			  sym.st_value = new_value;
> -			}
> -		    }
> -
> -		  afct = afct->next;
> -		}
> -
> -	      value = (void *) sym.st_value;
> -	    }
> -	}
> -#endif
> -
> -      return value;
> +      return _dl_sym_post (result, ref, value, caller, match);
>      }
>  
>    return NULL;
> 


-- 
Cheers,
Carlos.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]