Re: [PATCH v2 2/2] elf: Use the effective lazy mode for the deferred IRELATIVE pass

Sam James <[email protected]>
Newsgroups gmane.comp.lib.glibc.alpha
Organization Gentoo
Message-ID <[email protected]>
Adhemerval Zanella <[email protected]> writes:

> The 63b31c05a8a split relocation processing must agree for the lazy
> flag, a mistamatch would change the .rel.plt handling.

mismatch

>
> This is not an issue for any port currently, but on hppa it may return
> a different value: if hppa implements IFUNC support, the second pass would
> route PLT entries to its empty lazy handler and leave the descriptors
> unrelocated, silently.
>
> Make ELF_DYNAMIC_RELOCATE_PASS take lazy as an int lvalue and store the
> effective mode back into it, so the DL_RELOC_IRELATIVE call reuses the
> same variable instead of a separately threaded copy.  The two passes can no
> longer disagree about the partitioning.  elf_machine_runtime_setup has side
> effects, so it must stay a single call.
>
> Checked on x86_64-linux-gnu, and built for all supported architectures.

Reviewed-by: Sam James <[email protected]>

> ---
>  elf/dl-reloc-static-pie.c | 12 +++++++++---
>  elf/dl-reloc.c            |  5 +++--
>  elf/dynamic-link.h        | 34 ++++++++++++++++++++++------------
>  3 files changed, 34 insertions(+), 17 deletions(-)
>
> diff --git a/elf/dl-reloc-static-pie.c b/elf/dl-reloc-static-pie.c
> index 5dc5a545a8d..a3d984f6020 100644
> --- a/elf/dl-reloc-static-pie.c
> +++ b/elf/dl-reloc-static-pie.c
> @@ -79,8 +79,12 @@ _dl_relocate_static_pie (void)
>  # endif
>  
>    /* Relocate ourselves so we can do normal function calls and data access
> -     using the global offset table.  IRELATIVE entries are deferred.  */
> -  ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_NORMAL, main_map, NULL, 0, 0, 0);
> +     using the global offset table.  IRELATIVE entries are deferred.
> +     Lazy binding is never used here, so edr_lazy comes back as 0 and the
> +     deferred pass can hardcode the same value.  */
> +  int edr_lazy = 0;
> +  ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_NORMAL, main_map, NULL, edr_lazy,
> +			     0, 0);
>  
>    /* Initialize _r_debug_extended.  */
>    struct r_debug *r = _dl_debug_initialize (0, LM_ID_BASE);
> @@ -98,7 +102,9 @@ void
>  _dl_relocate_static_pie_ifunc (void)
>  {
>    struct link_map *main_map = _dl_get_dl_main_map ();
> -  ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_IRELATIVE, main_map, NULL, 0, 0, 0);
> +  int edr_lazy = 0;
> +  ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_IRELATIVE, main_map, NULL, edr_lazy,
> +			     0, 0);
>    main_map->l_relocated = 1;
>  }
>  #endif
> diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
> index fa2f41ac445..bed0c4f844a 100644
> --- a/elf/dl-reloc.c
> +++ b/elf/dl-reloc.c
> @@ -278,7 +278,8 @@ _dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[],
>         IFUNC resolvers.  Without this, a resolver would see the unrelocated
>         initialiser bytes that were placed into the slot by the early
>         _dl_allocate_tls_init.  */
> -    ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_NORMAL, l, scope, lazy,
> +    int edr_lazy = lazy;
> +    ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_NORMAL, l, scope, edr_lazy,
>  			       consider_profiling, skip_ifunc);
>  
>  #ifdef SHARED
> @@ -292,7 +293,7 @@ _dl_relocate_object_no_relro (struct link_map *l, struct r_scope_elem *scope[],
>        _dl_init_static_tls (l);
>  #endif
>  
> -    ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_IRELATIVE, l, scope, lazy,
> +    ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_IRELATIVE, l, scope, edr_lazy,
>  			       0, skip_ifunc);
>  
>      if ((consider_profiling || consider_symbind)
> diff --git a/elf/dynamic-link.h b/elf/dynamic-link.h
> index 0130c63feb1..81a3f0856e0 100644
> --- a/elf/dynamic-link.h
> +++ b/elf/dynamic-link.h
> @@ -235,29 +235,39 @@ enum elf_dynamic_reloc_pass
>     processed.  It is orthogonal to SKIP_IFUNC, which suppresses running IFUNC
>     resolvers in whichever pass is selected.
>  
> -   Unless PASS is DL_RELOC_IRELATIVE, this also performs the machine-specific
> -   PLT/GOT setup, the DT_RELR relocations, and the ELF_DYNAMIC_AFTER_RELOC
> -   hook.  */
> +   Unless PASS is DL_RELOC_IRELATIVE, this also performs the
> +   machine-specific PLT/GOT setup, the DT_RELR relocations, and the
> +   ELF_DYNAMIC_AFTER_RELOC hook.
> +
> +   LAZY must be an int lvalue.  elf_machine_runtime_setup may downgrade the
> +   requested mode (currently only hppa, when it cannot install the lazy
> +   trampoline) and it has side effects, so it must run exactly once (the
> +   effective mode is stored back into LAZY).  A later DL_RELOC_IRELATIVE
> +   call must be handed that same lvalue, so that both passes partition the
> +   relocation ranges identically.  */
>  # define ELF_DYNAMIC_RELOCATE_PASS(pass, map, scope, lazy, consider_profile,  \
>  				   skip_ifunc)				      \
>    do {									      \
> -    int edr_lazy = (lazy);						      \
>      if ((pass) != DL_RELOC_IRELATIVE)					      \
>        {									      \
> -	edr_lazy = elf_machine_runtime_setup ((map), (scope), (lazy),	      \
> -					      (consider_profile));	      \
> +	(lazy) = elf_machine_runtime_setup ((map), (scope), (lazy),	      \
> +					    (consider_profile));	      \
>  	if (!is_rtld_link_map (map) || DO_RTLD_BOOTSTRAP)		      \
>  	  ELF_DYNAMIC_DO_RELR (map);					      \
>        }									      \
> -    ELF_DYNAMIC_DO_REL ((map), (scope), edr_lazy, skip_ifunc, (pass));	      \
> -    ELF_DYNAMIC_DO_RELA ((map), (scope), edr_lazy, skip_ifunc, (pass));	      \
> +    ELF_DYNAMIC_DO_REL ((map), (scope), (lazy), skip_ifunc, (pass));	      \
> +    ELF_DYNAMIC_DO_RELA ((map), (scope), (lazy), skip_ifunc, (pass));	      \
>      if ((pass) != DL_RELOC_IRELATIVE)					      \
> -      ELF_DYNAMIC_AFTER_RELOC ((map), edr_lazy);			      \
> +      ELF_DYNAMIC_AFTER_RELOC ((map), (lazy));				      \
>    } while (0)
>  
> -/* Run both passes back to back, for callers with nothing to interleave.  */
> +/* Run both passes back to back, for callers with nothing to interleave.
> +   Unlike ELF_DYNAMIC_RELOCATE_PASS, LAZY need not be an lvalue.  */
>  # define ELF_DYNAMIC_RELOCATE(map, scope, lazy, consider_profile, skip_ifunc) \
> -  ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_ALL, (map), (scope), (lazy),	      \
> -			     (consider_profile), skip_ifunc)
> +  do {									      \
> +    int edr_lazy = (lazy);						      \
> +    ELF_DYNAMIC_RELOCATE_PASS (DL_RELOC_ALL, (map), (scope), edr_lazy,	      \
> +			       (consider_profile), skip_ifunc);		      \
> +  } while (0)
>  
>  #endif
signature.asc (application/pgp-signature, 418 B)
-----BEGIN PGP SIGNATURE-----

iQEBBAEWCgCpFiEEJaa7iN2bdkxrVUHCc4QJ9SDfkZAFAmp2i8YbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMiwyXxSAAAAAAC4AKGlzc3Vlci1mcHJAbm90YXRpb25z
Lm9wZW5wZ3AuZmlmdGhob3JzZW1hbi5uZXQyNUE2QkI4OEREOUI3NjRDNkI1NTQx
QzI3Mzg0MDlGNTIwREY5MTkwDxxzYW1AZ2VudG9vLm9yZwAKCRBzhAn1IN+RkHpo
AP9HQvaz6PJfIFPq9gHeP69yF0Qsz+FVC+LzBJI1IC46pAD+PIqBqrwJe8hSayXQ
DU21PmkgRk4EQPUtcwlbuYzyxgQ=
=c+Vt
-----END PGP SIGNATURE-----
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.