This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports 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] aarch64: Enable ifunc support.


On 11/26/2013 03:57 AM, Will Newton wrote:
> 
> Add support for handling the R_AARCH64_IRELATIVE relocation and
> STT_GNU_IFUNC symbols to the aarch64 port.

How did you test this?

> ports/ChangeLog.aarch64:
> 
> 2013-11-25  Will Newton  <will.newton@linaro.org>
> 
> 	* sysdeps/aarch64/dl-irel.h: Include ldsodefs.h.
> 	(ELF_MACHINE_IRELA): Define.  (elf_ifunc_invoke): Pass
> 	hwcap to ifunc resolver function.  (elf_irela): New function.
> 	* sysdeps/aarch64/dl-machine.h: Include dl-irel.h.
> 	(elf_machine_rela) Handle STT_GNU_IFUNC symbols and
> 	R_AARCH64_IRELATIVE relocations.  (elf_machine_lazy_rel):
> 	Handle R_AARCH64_IRELATIVE relocations.
> ---
>  ports/sysdeps/aarch64/dl-irel.h    | 22 +++++++++++++++++++---
>  ports/sysdeps/aarch64/dl-machine.h | 20 ++++++++++++++++++++
>  2 files changed, 39 insertions(+), 3 deletions(-)
> 
> diff --git a/ports/sysdeps/aarch64/dl-irel.h b/ports/sysdeps/aarch64/dl-irel.h
> index 1a3811e..f37ee39 100644
> --- a/ports/sysdeps/aarch64/dl-irel.h
> +++ b/ports/sysdeps/aarch64/dl-irel.h
> @@ -22,15 +22,31 @@
> 
>  #include <stdio.h>
>  #include <unistd.h>
> +#include <ldsodefs.h>
> 
> -/* AArch64 does not yet implement IFUNC support.  However since
> -   2011-06-20 provision of a elf_ifunc_invoke has been mandatory.  */
> +#define ELF_MACHINE_IRELA	1

OK.

> 
>  static inline ElfW(Addr)
>  __attribute ((always_inline))
>  elf_ifunc_invoke (ElfW(Addr) addr)
>  {
> -  return ((ElfW(Addr) (*) (void)) (addr)) ();
> +  return ((ElfW(Addr) (*) (unsigned long int)) (addr)) (GLRO(dl_hwcap));

OK.

> +}
> +
> +static inline void
> +__attribute ((always_inline))
> +elf_irela (const ElfW(Rela) *reloc)
> +{
> +  ElfW(Addr) *const reloc_addr = (void *) reloc->r_offset;
> +  const unsigned long int r_type = ELFW(R_TYPE) (reloc->r_info);
> +
> +  if (__glibc_likely (r_type == R_AARCH64_IRELATIVE))
> +    {
> +      ElfW(Addr) value = elf_ifunc_invoke (reloc->r_addend);
> +      *reloc_addr = value;
> +    }
> +  else
> +    __libc_fatal ("unexpected reloc type in static binary");
>  }

OK.

> 
>  #endif
> diff --git a/ports/sysdeps/aarch64/dl-machine.h b/ports/sysdeps/aarch64/dl-machine.h
> index 71dd6b3..01a214f 100644
> --- a/ports/sysdeps/aarch64/dl-machine.h
> +++ b/ports/sysdeps/aarch64/dl-machine.h
> @@ -23,6 +23,7 @@
> 
>  #include <tls.h>
>  #include <dl-tlsdesc.h>
> +#include <dl-irel.h>
> 
>  /* Return nonzero iff ELF header is compatible with the running host.  */
>  static inline int __attribute__ ((unused))
> @@ -243,6 +244,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>        struct link_map *sym_map = RESOLVE_MAP (&sym, version, r_type);
>        ElfW(Addr) value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
> 
> +      if (sym != NULL
> +	  && __glibc_unlikely (ELFW(ST_TYPE) (sym->st_info) == STT_GNU_IFUNC)
> +	  && __glibc_likely (sym->st_shndx != SHN_UNDEF)
> +	  && __glibc_likely (!skip_ifunc))
> +	value = elf_ifunc_invoke (value);

OK.

> +
>        switch (r_type)
>  	{
>  	case R_AARCH64_COPY:
> @@ -331,6 +338,12 @@ elf_machine_rela (struct link_map *map, const ElfW(Rela) *reloc,
>  	    }
>  	  break;
> 
> +	case R_AARCH64_IRELATIVE:
> +	  value = map->l_addr + reloc->r_addend;
> +	  value = elf_ifunc_invoke (value);
> +	  *reloc_addr = value;
> +	  break;

OK.

> +
>  	default:
>  	  _dl_reloc_bad_type (map, r_type, 0);
>  	  break;
> @@ -374,6 +387,13 @@ elf_machine_lazy_rel (struct link_map *map,
>        td->entry = (void*)(D_PTR (map, l_info[ADDRIDX (DT_TLSDESC_PLT)])
>  			  + map->l_addr);
>      }
> +  else if (__glibc_unlikely (r_type == R_AARCH64_IRELATIVE))
> +    {
> +      ElfW(Addr) value = map->l_addr + reloc->r_addend;
> +      if (__glibc_likely (!skip_ifunc))
> +	value = elf_ifunc_invoke (value);
> +      *reloc_addr = value;

OK.

> +    }
>    else
>      _dl_reloc_bad_type (map, r_type, 1);
>  }
> 

Looks good to me as long as your testing makes sense.

Cheers,
Carlos.


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