dl-runtime: reloc_{offset, index} now functions arch overide'able

Message ID 20200528194345.9829-1-vgupta@synopsys.com
State Superseded
Headers
Series dl-runtime: reloc_{offset, index} now functions arch overide'able |

Commit Message

Vineet Gupta May 28, 2020, 7:43 p.m. UTC
  The existing macros are fragile and expect local variables with a
certain name. Fix this by defining them as functions with defaul
timplementation in a new header dl-runtime.h which arches can overrid
eif need be.

This came up during ARC port review.

This patch potentially only affects hppa/x86 ports,
build tested for both those configs and a few more.

Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
---
 elf/dl-runtime.c                              | 24 +++++++-------
 elf/dl-runtime.h                              | 30 ++++++++++++++++++
 sysdeps/hppa/dl-runtime.c                     |  4 ---
 sysdeps/hppa/dl-runtime.h                     | 31 +++++++++++++++++++
 sysdeps/x86_64/{dl-runtime.c => dl-runtime.h} | 13 ++++++--
 5 files changed, 84 insertions(+), 18 deletions(-)
 create mode 100644 elf/dl-runtime.h
 create mode 100644 sysdeps/hppa/dl-runtime.h
 rename sysdeps/x86_64/{dl-runtime.c => dl-runtime.h} (60%)
  

Comments

Adhemerval Zanella May 29, 2020, 12:58 p.m. UTC | #1
On 28/05/2020 16:43, Vineet Gupta wrote:
> The existing macros are fragile and expect local variables with a
> certain name. Fix this by defining them as functions with defaul
> timplementation in a new header dl-runtime.h which arches can overrid
> eif need be.
> 
> This came up during ARC port review.
> 
> This patch potentially only affects hppa/x86 ports,
> build tested for both those configs and a few more.
> 
> Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

LGTM, thanks.

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

> ---
>  elf/dl-runtime.c                              | 24 +++++++-------
>  elf/dl-runtime.h                              | 30 ++++++++++++++++++
>  sysdeps/hppa/dl-runtime.c                     |  4 ---
>  sysdeps/hppa/dl-runtime.h                     | 31 +++++++++++++++++++
>  sysdeps/x86_64/{dl-runtime.c => dl-runtime.h} | 13 ++++++--
>  5 files changed, 84 insertions(+), 18 deletions(-)
>  create mode 100644 elf/dl-runtime.h
>  create mode 100644 sysdeps/hppa/dl-runtime.h
>  rename sysdeps/x86_64/{dl-runtime.c => dl-runtime.h} (60%)
> 
> diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
> index cf5f1d3e82e1..62f90579370b 100644
> --- a/elf/dl-runtime.c
> +++ b/elf/dl-runtime.c
> @@ -27,6 +27,7 @@
>  #include "dynamic-link.h"
>  #include <tls.h>
>  #include <dl-irel.h>
> +#include <dl-runtime.h>
>  
>  
>  #if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
> @@ -42,13 +43,6 @@
>  # define ARCH_FIXUP_ATTRIBUTE
>  #endif
>  
> -#ifndef reloc_offset
> -# define reloc_offset reloc_arg
> -# define reloc_index  reloc_arg / sizeof (PLTREL)
> -#endif
> -
> -
> -
>  /* This function is called through a special trampoline from the PLT the
>     first time each PLT entry is called.  We must perform the relocation
>     specified in the PLT of the given shared object, and return the resolved
> @@ -68,8 +62,11 @@ _dl_fixup (
>      = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
>    const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
>  
> +  const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
> +
>    const PLTREL *const reloc
> -    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
> +    = (const void *) (D_PTR (l, l_info[DT_JMPREL])
> +		      + reloc_offset (pltgot, reloc_arg));
>    const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
>    const ElfW(Sym) *refsym = sym;
>    void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);

Ok (it should be dead code eliminated by compiler if reloc_offset does not
use the pltgot field, as for default implementation).

> @@ -182,7 +179,8 @@ _dl_profile_fixup (
>  
>    /* This is the address in the array where we store the result of previous
>       relocations.  */
> -  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
> +  struct reloc_result *reloc_result
> +    = &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
>  
>   /* CONCURRENCY NOTES:
>  
> @@ -219,8 +217,11 @@ _dl_profile_fixup (
>  	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
>        const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
>  
> +      const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
> +
>        const PLTREL *const reloc
> -	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
> +	= (const void *) (D_PTR (l, l_info[DT_JMPREL])
> +			  + reloc_offset (pltgot, reloc_arg));
>        const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
>        const ElfW(Sym) *defsym = refsym;
>        lookup_t result;
> @@ -489,7 +490,8 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
>       relocations.  */
>    // XXX Maybe the bound information must be stored on the stack since
>    // XXX with bind_not a new value could have been stored in the meantime.
> -  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
> +  struct reloc_result *reloc_result =
> +    &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
>    ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
>  					    l_info[DT_SYMTAB])
>  		       + reloc_result->boundndx);

Ok.

> diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
> new file mode 100644
> index 000000000000..ed5db3ba51b7
> --- /dev/null
> +++ b/elf/dl-runtime.h
> @@ -0,0 +1,30 @@
> +/* Helpers for On-demand PLT fixup for shared objects, Generic version.

Maybe period here?

> +   Copyright (C) 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, write to the Free
> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> +   02111-1307 USA.  */
> +
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn;
> +}
> +
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return pltn / size;
> +}

Ok.

> diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
> index 885a3f1837cb..2d061b150f06 100644
> --- a/sysdeps/hppa/dl-runtime.c
> +++ b/sysdeps/hppa/dl-runtime.c
> @@ -17,10 +17,6 @@
>     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
>     02111-1307 USA.  */
>  
> -/* Clear PA_GP_RELOC bit in relocation offset.  */
> -#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
> -#define reloc_index  (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
> -
>  #include <elf/dl-runtime.c>
>  
>  /* The caller has encountered a partially relocated function descriptor.

Ok.

> diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
> new file mode 100644
> index 000000000000..cfde0ec991e3
> --- /dev/null
> +++ b/sysdeps/hppa/dl-runtime.h
> @@ -0,0 +1,31 @@
> +/* Helpers for On-demand PLT fixup for shared objects, HPAA version.

Maybe period instead of comma here?

> +   Copyright (C) 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, write to the Free
> +   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
> +   02111-1307 USA.  */
> +
> +/* Clear PA_GP_RELOC bit in relocation offset.  */
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn & ~PA_GP_RELOC;
> +}
> +
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return (pltn & ~PA_GP_RELOC )/ size;
> +}

Ok.

> diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.h
> similarity index 60%
> rename from sysdeps/x86_64/dl-runtime.c
> rename to sysdeps/x86_64/dl-runtime.h
> index b625d1e88257..494ff47b7091 100644
> --- a/sysdeps/x86_64/dl-runtime.c
> +++ b/sysdeps/x86_64/dl-runtime.h
> @@ -3,7 +3,14 @@
>     also use the index.  Therefore it is wasteful to compute the offset
>     in the trampoline just to reverse the operation immediately
>     afterwards.  */
> -#define reloc_offset reloc_arg * sizeof (PLTREL)
> -#define reloc_index  reloc_arg
> +static inline uintptr_t
> +reloc_offset (uintptr_t plt0, uintptr_t pltn)
> +{
> +  return pltn * sizeof (ElfW(Rela));
> +}
>  
> -#include <elf/dl-runtime.c>
> +static inline uintptr_t
> +reloc_index (uintptr_t pltn, size_t size)
> +{
> +  return pltn;
> +}
> 

Ok.
  
Vineet Gupta May 29, 2020, 5:39 p.m. UTC | #2
On 5/29/20 5:58 AM, Adhemerval Zanella via Libc-alpha wrote:
> 
> 
> On 28/05/2020 16:43, Vineet Gupta wrote:
>> The existing macros are fragile and expect local variables with a
>> certain name. Fix this by defining them as functions with defaul
>> timplementation in a new header dl-runtime.h which arches can overrid
>> eif need be.
>>
>> This came up during ARC port review.
>>
>> This patch potentially only affects hppa/x86 ports,
>> build tested for both those configs and a few more.
>>
>> Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> 
> LGTM, thanks.
> 
> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>

Sorry I didn't think through this before, but ARC port needs pltgot arg (runtime
address of plt0) in reloc_index not reloc_offset. I'll swap them and repost.

>>  /* This function is called through a special trampoline from the PLT the
>>     first time each PLT entry is called.  We must perform the relocation
>>     specified in the PLT of the given shared object, and return the resolved
>> @@ -68,8 +62,11 @@ _dl_fixup (
>>      = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
>>    const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
>>  
>> +  const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
>> +
>>    const PLTREL *const reloc
>> -    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
>> +    = (const void *) (D_PTR (l, l_info[DT_JMPREL])
>> +		      + reloc_offset (pltgot, reloc_arg));
>>    const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
>>    const ElfW(Sym) *refsym = sym;
>>    void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
> 
> Ok (it should be dead code eliminated by compiler if reloc_offset does not
> use the pltgot field, as for default implementation).

Yep.

> 
>> diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
>> new file mode 100644
>> index 000000000000..ed5db3ba51b7
>> --- /dev/null
>> +++ b/elf/dl-runtime.h
>> @@ -0,0 +1,30 @@
>> +/* Helpers for On-demand PLT fixup for shared objects, Generic version.
> 
> Maybe period here?

OK


>> diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
>> new file mode 100644
>> index 000000000000..cfde0ec991e3
>> --- /dev/null
>> +++ b/sysdeps/hppa/dl-runtime.h
>> @@ -0,0 +1,31 @@
>> +/* Helpers for On-demand PLT fixup for shared objects, HPAA version.
> 
> Maybe period instead of comma here?

OK.
  
Adhemerval Zanella May 29, 2020, 8:54 p.m. UTC | #3
On 29/05/2020 14:39, Vineet Gupta wrote:
> On 5/29/20 5:58 AM, Adhemerval Zanella via Libc-alpha wrote:
>>
>>
>> On 28/05/2020 16:43, Vineet Gupta wrote:
>>> The existing macros are fragile and expect local variables with a
>>> certain name. Fix this by defining them as functions with defaul
>>> timplementation in a new header dl-runtime.h which arches can overrid
>>> eif need be.
>>>
>>> This came up during ARC port review.
>>>
>>> This patch potentially only affects hppa/x86 ports,
>>> build tested for both those configs and a few more.
>>>
>>> Suggested-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
>>
>> LGTM, thanks.
>>
>> Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> 
> Sorry I didn't think through this before, but ARC port needs pltgot arg (runtime
> address of plt0) in reloc_index not reloc_offset. I'll swap them and repost.

Hum I though I had it covered on my suggestion, but it seems I mixed them
up. Ok, I will review the new version.
  

Patch

diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
index cf5f1d3e82e1..62f90579370b 100644
--- a/elf/dl-runtime.c
+++ b/elf/dl-runtime.c
@@ -27,6 +27,7 @@ 
 #include "dynamic-link.h"
 #include <tls.h>
 #include <dl-irel.h>
+#include <dl-runtime.h>
 
 
 #if (!ELF_MACHINE_NO_RELA && !defined ELF_MACHINE_PLT_REL) \
@@ -42,13 +43,6 @@ 
 # define ARCH_FIXUP_ATTRIBUTE
 #endif
 
-#ifndef reloc_offset
-# define reloc_offset reloc_arg
-# define reloc_index  reloc_arg / sizeof (PLTREL)
-#endif
-
-
-
 /* This function is called through a special trampoline from the PLT the
    first time each PLT entry is called.  We must perform the relocation
    specified in the PLT of the given shared object, and return the resolved
@@ -68,8 +62,11 @@  _dl_fixup (
     = (const void *) D_PTR (l, l_info[DT_SYMTAB]);
   const char *strtab = (const void *) D_PTR (l, l_info[DT_STRTAB]);
 
+  const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
   const PLTREL *const reloc
-    = (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+    = (const void *) (D_PTR (l, l_info[DT_JMPREL])
+		      + reloc_offset (pltgot, reloc_arg));
   const ElfW(Sym) *sym = &symtab[ELFW(R_SYM) (reloc->r_info)];
   const ElfW(Sym) *refsym = sym;
   void *const rel_addr = (void *)(l->l_addr + reloc->r_offset);
@@ -182,7 +179,8 @@  _dl_profile_fixup (
 
   /* This is the address in the array where we store the result of previous
      relocations.  */
-  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+  struct reloc_result *reloc_result
+    = &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
 
  /* CONCURRENCY NOTES:
 
@@ -219,8 +217,11 @@  _dl_profile_fixup (
 	= (const void *) D_PTR (l, l_info[DT_SYMTAB]);
       const char *strtab = (const char *) D_PTR (l, l_info[DT_STRTAB]);
 
+      const uintptr_t pltgot = (uintptr_t) D_PTR (l, l_info[DT_PLTGOT]);
+
       const PLTREL *const reloc
-	= (const void *) (D_PTR (l, l_info[DT_JMPREL]) + reloc_offset);
+	= (const void *) (D_PTR (l, l_info[DT_JMPREL])
+			  + reloc_offset (pltgot, reloc_arg));
       const ElfW(Sym) *refsym = &symtab[ELFW(R_SYM) (reloc->r_info)];
       const ElfW(Sym) *defsym = refsym;
       lookup_t result;
@@ -489,7 +490,8 @@  _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
      relocations.  */
   // XXX Maybe the bound information must be stored on the stack since
   // XXX with bind_not a new value could have been stored in the meantime.
-  struct reloc_result *reloc_result = &l->l_reloc_result[reloc_index];
+  struct reloc_result *reloc_result =
+    &l->l_reloc_result[reloc_index (reloc_arg, sizeof (PLTREL))];
   ElfW(Sym) *defsym = ((ElfW(Sym) *) D_PTR (reloc_result->bound,
 					    l_info[DT_SYMTAB])
 		       + reloc_result->boundndx);
diff --git a/elf/dl-runtime.h b/elf/dl-runtime.h
new file mode 100644
index 000000000000..ed5db3ba51b7
--- /dev/null
+++ b/elf/dl-runtime.h
@@ -0,0 +1,30 @@ 
+/* Helpers for On-demand PLT fixup for shared objects, Generic version.
+   Copyright (C) 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn;
+}
+
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return pltn / size;
+}
diff --git a/sysdeps/hppa/dl-runtime.c b/sysdeps/hppa/dl-runtime.c
index 885a3f1837cb..2d061b150f06 100644
--- a/sysdeps/hppa/dl-runtime.c
+++ b/sysdeps/hppa/dl-runtime.c
@@ -17,10 +17,6 @@ 
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-/* Clear PA_GP_RELOC bit in relocation offset.  */
-#define reloc_offset (reloc_arg & ~PA_GP_RELOC)
-#define reloc_index  (reloc_arg & ~PA_GP_RELOC) / sizeof (PLTREL)
-
 #include <elf/dl-runtime.c>
 
 /* The caller has encountered a partially relocated function descriptor.
diff --git a/sysdeps/hppa/dl-runtime.h b/sysdeps/hppa/dl-runtime.h
new file mode 100644
index 000000000000..cfde0ec991e3
--- /dev/null
+++ b/sysdeps/hppa/dl-runtime.h
@@ -0,0 +1,31 @@ 
+/* Helpers for On-demand PLT fixup for shared objects, HPAA version.
+   Copyright (C) 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, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* Clear PA_GP_RELOC bit in relocation offset.  */
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn & ~PA_GP_RELOC;
+}
+
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return (pltn & ~PA_GP_RELOC )/ size;
+}
diff --git a/sysdeps/x86_64/dl-runtime.c b/sysdeps/x86_64/dl-runtime.h
similarity index 60%
rename from sysdeps/x86_64/dl-runtime.c
rename to sysdeps/x86_64/dl-runtime.h
index b625d1e88257..494ff47b7091 100644
--- a/sysdeps/x86_64/dl-runtime.c
+++ b/sysdeps/x86_64/dl-runtime.h
@@ -3,7 +3,14 @@ 
    also use the index.  Therefore it is wasteful to compute the offset
    in the trampoline just to reverse the operation immediately
    afterwards.  */
-#define reloc_offset reloc_arg * sizeof (PLTREL)
-#define reloc_index  reloc_arg
+static inline uintptr_t
+reloc_offset (uintptr_t plt0, uintptr_t pltn)
+{
+  return pltn * sizeof (ElfW(Rela));
+}
 
-#include <elf/dl-runtime.c>
+static inline uintptr_t
+reloc_index (uintptr_t pltn, size_t size)
+{
+  return pltn;
+}