[PATCH v2 1/2] elf: Extract rtld_setup_phdr function from dl_main

Adhemerval Zanella Netto adhemerval.zanella@linaro.org
Tue Jul 29 15:57:59 GMT 2025



On 25/07/25 08:10, Florian Weimer wrote:
> Remove historic binutils reference from comment and update
> how this data is used by applications.

LGTM, thanks.

Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>

> ---
>  elf/rtld.c | 59 +++++++++++++++++++++++++++++-------------------------
>  1 file changed, 32 insertions(+), 27 deletions(-)
> 
> diff --git a/elf/rtld.c b/elf/rtld.c
> index 493f9696ea..6fb900fb31 100644
> --- a/elf/rtld.c
> +++ b/elf/rtld.c
> @@ -1239,6 +1239,37 @@ rtld_setup_main_map (struct link_map *main_map)
>    return has_interp;
>  }
>  
> +/* Set up the program header information for the dynamic linker
> +   itself.  It can be accessed via _r_debug and dl_iterate_phdr
> +   callbacks.  */
> +static void
> +rtld_setup_phdr (void)
> +{
> +  /* Starting from binutils-2.23, the linker will define the magic
> +     symbol __ehdr_start to point to our own ELF header if it is
> +     visible in a segment that also includes the phdrs.  */
> +
> +  const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
> +  assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
> +  assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
> +
> +  const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff;
> +
> +  _dl_rtld_map.l_phdr = rtld_phdr;
> +  _dl_rtld_map.l_phnum = rtld_ehdr->e_phnum;
> +
> +
> +  /* PT_GNU_RELRO is usually the last phdr.  */
> +  size_t cnt = rtld_ehdr->e_phnum;
> +  while (cnt-- > 0)
> +    if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
> +      {
> +	_dl_rtld_map.l_relro_addr = rtld_phdr[cnt].p_vaddr;
> +	_dl_rtld_map.l_relro_size = rtld_phdr[cnt].p_memsz;
> +	break;
> +      }
> +}
> +
>  /* Adjusts the contents of the stack and related globals for the user
>     entry point.  The ld.so processed skip_args arguments and bumped
>     _dl_argv and _dl_argc accordingly.  Those arguments are removed from
> @@ -1705,33 +1736,7 @@ dl_main (const ElfW(Phdr) *phdr,
>    ++GL(dl_ns)[LM_ID_BASE]._ns_nloaded;
>    ++GL(dl_load_adds);
>  
> -  /* Starting from binutils-2.23, the linker will define the magic symbol
> -     __ehdr_start to point to our own ELF header if it is visible in a
> -     segment that also includes the phdrs.  If that's not available, we use
> -     the old method that assumes the beginning of the file is part of the
> -     lowest-addressed PT_LOAD segment.  */
> -
> -  /* Set up the program header information for the dynamic linker
> -     itself.  It is needed in the dl_iterate_phdr callbacks.  */
> -  const ElfW(Ehdr) *rtld_ehdr = &__ehdr_start;
> -  assert (rtld_ehdr->e_ehsize == sizeof *rtld_ehdr);
> -  assert (rtld_ehdr->e_phentsize == sizeof (ElfW(Phdr)));
> -
> -  const ElfW(Phdr) *rtld_phdr = (const void *) rtld_ehdr + rtld_ehdr->e_phoff;
> -
> -  _dl_rtld_map.l_phdr = rtld_phdr;
> -  _dl_rtld_map.l_phnum = rtld_ehdr->e_phnum;
> -
> -
> -  /* PT_GNU_RELRO is usually the last phdr.  */
> -  size_t cnt = rtld_ehdr->e_phnum;
> -  while (cnt-- > 0)
> -    if (rtld_phdr[cnt].p_type == PT_GNU_RELRO)
> -      {
> -	_dl_rtld_map.l_relro_addr = rtld_phdr[cnt].p_vaddr;
> -	_dl_rtld_map.l_relro_size = rtld_phdr[cnt].p_memsz;
> -	break;
> -      }
> +  rtld_setup_phdr ();
>  
>    /* Add the dynamic linker to the TLS list if it also uses TLS.  */
>    if (_dl_rtld_map.l_tls_blocksize != 0)



More information about the Libc-alpha mailing list