[BZ,#19178] ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA conflict

Message ID CAMe9rOrJ71FK_x0mXtzas_pYM3x9rjsbrT_0FFNcjrocSboBDQ@mail.gmail.com
State New, archived
Headers

Commit Message

H.J. Lu Oct. 28, 2015, 11:18 p.m. UTC
  On Wed, Oct 28, 2015 at 3:04 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Wed, Oct 28, 2015 at 6:42 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Wed, Oct 28, 2015 at 4:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> _dl_debug_bindings updates relocation type class with 4 and 8.  But
>>> ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA may be defined to 4.  This patch
>>> adds ELF_RTYPE_CLASS_TLS/ELF_RTYPE_CLASS_IFUNC and use them in
>>> _dl_debug_bindings.
>>>
>>> Tested on i686 and x86-64.  OK for master and 2.22 branch?
>>>
>>>
>>> H.J.
>>> --
>>>         [BZ #19178]
>>>         * dl-lookup.c (_dl_debug_bindings): Replace 4 and 8 with
>>>         ELF_RTYPE_CLASS_TLS and ELF_RTYPE_CLASS_IFUNC.
>>>         * sysdeps/generic/ldsodefs.h (ELF_RTYPE_CLASS_TLS): New.
>>>         (ELF_RTYPE_CLASS_IFUNC): Likewise.
>>
>>
>> It doesn't work with prelink.
>>
>
> Here is the correct patch.  Verified with prelink.  OK for master
> and 2.22 branch?

Here is the updated patch to keep only ELF_RTYPE_CLASS_PLT and
ELF_RTYPE_CLASS_COPY bits for prelink.

Mark, can you verify it with prelink?

Thanks.
  

Comments

Mark Hatle Oct. 28, 2015, 11:33 p.m. UTC | #1
I have verified the attached patch works with the prelinker.

Also the output of the ld.so when performing LD_TRACE_PRELINKING is now that
same as glibc-2.21.

Tested-by: Mark Hatle <mark.hatle@windriver.com>

On 10/28/15 6:18 PM, H.J. Lu wrote:
> On Wed, Oct 28, 2015 at 3:04 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> > On Wed, Oct 28, 2015 at 6:42 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> >> On Wed, Oct 28, 2015 at 4:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> >>> _dl_debug_bindings updates relocation type class with 4 and 8.  But
>>>> >>> ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA may be defined to 4.  This patch
>>>> >>> adds ELF_RTYPE_CLASS_TLS/ELF_RTYPE_CLASS_IFUNC and use them in
>>>> >>> _dl_debug_bindings.
>>>> >>>
>>>> >>> Tested on i686 and x86-64.  OK for master and 2.22 branch?
>>>> >>>
>>>> >>>
>>>> >>> H.J.
>>>> >>> --
>>>> >>>         [BZ #19178]
>>>> >>>         * dl-lookup.c (_dl_debug_bindings): Replace 4 and 8 with
>>>> >>>         ELF_RTYPE_CLASS_TLS and ELF_RTYPE_CLASS_IFUNC.
>>>> >>>         * sysdeps/generic/ldsodefs.h (ELF_RTYPE_CLASS_TLS): New.
>>>> >>>         (ELF_RTYPE_CLASS_IFUNC): Likewise.
>>> >>
>>> >>
>>> >> It doesn't work with prelink.
>>> >>
>> >
>> > Here is the correct patch.  Verified with prelink.  OK for master
>> > and 2.22 branch?
> Here is the updated patch to keep only ELF_RTYPE_CLASS_PLT and
> ELF_RTYPE_CLASS_COPY bits for prelink.
> 
> Mark, can you verify it with prelink?
> 
> Thanks.
> 
> 
> -- H.J.
> 
> 
> 0001-Keep-only-ELF_RTYPE_CLASS_-PLT-COPY-bits-for-prelink.patch
> 
> 
> From 7f16bc353495e6c2ec101abeee4ba26525e6c725 Mon Sep 17 00:00:00 2001
> From: "H.J. Lu" <hjl.tools@gmail.com>
> Date: Wed, 28 Oct 2015 07:49:44 -0700
> Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink
> 
> prelink runs ld.so with the environment variable LD_TRACE_PRELINKING
> set to dump the relocation type class from _dl_debug_bindings.  prelink
> has the following relocation type classes:
> 
>  #define RTYPE_CLASS_VALID       8
>  #define RTYPE_CLASS_PLT         (8|1)
>  #define RTYPE_CLASS_COPY        (8|2)
>  #define RTYPE_CLASS_TLS         (8|4)
> 
> where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with
> RTYPE_CLASS_TLS.
> 
> Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
> bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is
> set.
> 
> 	[BZ #19178]
> 	* elf/dl-lookup.c (RTYPE_CLASS_VALID): New.
> 	(RTYPE_CLASS_PLT): Likewise.
> 	(RTYPE_CLASS_COPY): Likewise.
> 	(RTYPE_CLASS_TLS): Likewise.
> 	(_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID
> 	to set relocation type class for DL_DEBUG_PRELINK.  Keep only
> 	ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for
> 	DL_DEBUG_PRELINK.
> ---
>  elf/dl-lookup.c | 21 +++++++++++++++++++--
>  1 file changed, 19 insertions(+), 2 deletions(-)
> 
> diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
> index 581fb20..6ae6cc3 100644
> --- a/elf/dl-lookup.c
> +++ b/elf/dl-lookup.c
> @@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
>  #ifdef SHARED
>    if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
>      {
> +/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
> +   LD_TRACE_PRELINKING.  */
> +#define RTYPE_CLASS_VALID	8
> +#define RTYPE_CLASS_PLT		(8|1)
> +#define RTYPE_CLASS_COPY	(8|2)
> +#define RTYPE_CLASS_TLS		(8|4)
> +#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
> +# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
> +#endif
> +#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
> +# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
> +#endif
>        int conflict = 0;
>        struct sym_val val = { NULL, NULL };
>  
> @@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
>  
>        if (value->s)
>  	{
> +	  /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
> +	     bits since since prelink only uses them.  */
> +	  type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
>  	  if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
>  				== STT_TLS))
> -	    type_class = 4;
> +	    /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS.  */
> +	    type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
>  	  else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
>  				     == STT_GNU_IFUNC))
> -	    type_class |= 8;
> +	    /* Set the RTYPE_CLASS_VALID bit.  */
> +	    type_class |= RTYPE_CLASS_VALID;
>  	}
>  
>        if (conflict
> -- 2.4.3
>
  
H.J. Lu Nov. 6, 2015, 10:09 p.m. UTC | #2
On Wed, Oct 28, 2015 at 4:33 PM, Mark Hatle <mark.hatle@windriver.com> wrote:
> I have verified the attached patch works with the prelinker.
>
> Also the output of the ld.so when performing LD_TRACE_PRELINKING is now that
> same as glibc-2.21.
>
> Tested-by: Mark Hatle <mark.hatle@windriver.com>
>
> On 10/28/15 6:18 PM, H.J. Lu wrote:
>> On Wed, Oct 28, 2015 at 3:04 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>> > On Wed, Oct 28, 2015 at 6:42 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>> >> On Wed, Oct 28, 2015 at 4:49 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
>>>>> >>> _dl_debug_bindings updates relocation type class with 4 and 8.  But
>>>>> >>> ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA may be defined to 4.  This patch
>>>>> >>> adds ELF_RTYPE_CLASS_TLS/ELF_RTYPE_CLASS_IFUNC and use them in
>>>>> >>> _dl_debug_bindings.
>>>>> >>>
>>>>> >>> Tested on i686 and x86-64.  OK for master and 2.22 branch?
>>>>> >>>
>>>>> >>>
>>>>> >>> H.J.
>>>>> >>> --
>>>>> >>>         [BZ #19178]
>>>>> >>>         * dl-lookup.c (_dl_debug_bindings): Replace 4 and 8 with
>>>>> >>>         ELF_RTYPE_CLASS_TLS and ELF_RTYPE_CLASS_IFUNC.
>>>>> >>>         * sysdeps/generic/ldsodefs.h (ELF_RTYPE_CLASS_TLS): New.
>>>>> >>>         (ELF_RTYPE_CLASS_IFUNC): Likewise.
>>>> >>
>>>> >>
>>>> >> It doesn't work with prelink.
>>>> >>
>>> >
>>> > Here is the correct patch.  Verified with prelink.  OK for master
>>> > and 2.22 branch?
>> Here is the updated patch to keep only ELF_RTYPE_CLASS_PLT and
>> ELF_RTYPE_CLASS_COPY bits for prelink.
>>
>> Mark, can you verify it with prelink?
>>
>> Thanks.
>>
>>
>> -- H.J.
>>
>>
>> 0001-Keep-only-ELF_RTYPE_CLASS_-PLT-COPY-bits-for-prelink.patch
>>
>>
>> From 7f16bc353495e6c2ec101abeee4ba26525e6c725 Mon Sep 17 00:00:00 2001
>> From: "H.J. Lu" <hjl.tools@gmail.com>
>> Date: Wed, 28 Oct 2015 07:49:44 -0700
>> Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink
>>
>> prelink runs ld.so with the environment variable LD_TRACE_PRELINKING
>> set to dump the relocation type class from _dl_debug_bindings.  prelink
>> has the following relocation type classes:
>>
>>  #define RTYPE_CLASS_VALID       8
>>  #define RTYPE_CLASS_PLT         (8|1)
>>  #define RTYPE_CLASS_COPY        (8|2)
>>  #define RTYPE_CLASS_TLS         (8|4)
>>
>> where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with
>> RTYPE_CLASS_TLS.
>>
>> Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
>> bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is
>> set.
>>
>>       [BZ #19178]
>>       * elf/dl-lookup.c (RTYPE_CLASS_VALID): New.
>>       (RTYPE_CLASS_PLT): Likewise.
>>       (RTYPE_CLASS_COPY): Likewise.
>>       (RTYPE_CLASS_TLS): Likewise.
>>       (_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID
>>       to set relocation type class for DL_DEBUG_PRELINK.  Keep only
>>       ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for
>>       DL_DEBUG_PRELINK.
>> ---
>>  elf/dl-lookup.c | 21 +++++++++++++++++++--
>>  1 file changed, 19 insertions(+), 2 deletions(-)
>>
>> diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
>> index 581fb20..6ae6cc3 100644
>> --- a/elf/dl-lookup.c
>> +++ b/elf/dl-lookup.c
>> @@ -1016,6 +1016,18 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
>>  #ifdef SHARED
>>    if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
>>      {
>> +/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
>> +   LD_TRACE_PRELINKING.  */
>> +#define RTYPE_CLASS_VALID    8
>> +#define RTYPE_CLASS_PLT              (8|1)
>> +#define RTYPE_CLASS_COPY     (8|2)
>> +#define RTYPE_CLASS_TLS              (8|4)
>> +#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
>> +# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
>> +#endif
>> +#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
>> +# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
>> +#endif
>>        int conflict = 0;
>>        struct sym_val val = { NULL, NULL };
>>
>> @@ -1071,12 +1083,17 @@ _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
>>
>>        if (value->s)
>>       {
>> +       /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
>> +          bits since since prelink only uses them.  */
>> +       type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
>>         if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
>>                               == STT_TLS))
>> -         type_class = 4;
>> +         /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS.  */
>> +         type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
>>         else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
>>                                    == STT_GNU_IFUNC))
>> -         type_class |= 8;
>> +         /* Set the RTYPE_CLASS_VALID bit.  */
>> +         type_class |= RTYPE_CLASS_VALID;
>>       }
>>
>>        if (conflict
>> -- 2.4.3
>>
>

This patch only impacts debug output for prelink and we have verified
that it fixes
prelink.  I am checking it into master as an obvious fix and will
backport it to 2.22
branch later.
  

Patch

From 7f16bc353495e6c2ec101abeee4ba26525e6c725 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Wed, 28 Oct 2015 07:49:44 -0700
Subject: [PATCH] Keep only ELF_RTYPE_CLASS_{PLT|COPY} bits for prelink

prelink runs ld.so with the environment variable LD_TRACE_PRELINKING
set to dump the relocation type class from _dl_debug_bindings.  prelink
has the following relocation type classes:

 #define RTYPE_CLASS_VALID       8
 #define RTYPE_CLASS_PLT         (8|1)
 #define RTYPE_CLASS_COPY        (8|2)
 #define RTYPE_CLASS_TLS         (8|4)

where ELF_RTYPE_CLASS_EXTERN_PROTECTED_DATA has a conflict with
RTYPE_CLASS_TLS.

Since prelink only uses ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
bits, we should clear the other bits when the DL_DEBUG_PRELINK bit is
set.

	[BZ #19178]
	* elf/dl-lookup.c (RTYPE_CLASS_VALID): New.
	(RTYPE_CLASS_PLT): Likewise.
	(RTYPE_CLASS_COPY): Likewise.
	(RTYPE_CLASS_TLS): Likewise.
	(_dl_debug_bindings): Use RTYPE_CLASS_TLS and RTYPE_CLASS_VALID
	to set relocation type class for DL_DEBUG_PRELINK.  Keep only
	ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY bits for
	DL_DEBUG_PRELINK.
---
 elf/dl-lookup.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

diff --git a/elf/dl-lookup.c b/elf/dl-lookup.c
index 581fb20..6ae6cc3 100644
--- a/elf/dl-lookup.c
+++ b/elf/dl-lookup.c
@@ -1016,6 +1016,18 @@  _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 #ifdef SHARED
   if (GLRO(dl_debug_mask) & DL_DEBUG_PRELINK)
     {
+/* ELF_RTYPE_CLASS_XXX must match RTYPE_CLASS_XXX used by prelink with
+   LD_TRACE_PRELINKING.  */
+#define RTYPE_CLASS_VALID	8
+#define RTYPE_CLASS_PLT		(8|1)
+#define RTYPE_CLASS_COPY	(8|2)
+#define RTYPE_CLASS_TLS		(8|4)
+#if ELF_RTYPE_CLASS_PLT != 0 && ELF_RTYPE_CLASS_PLT != 1
+# error ELF_RTYPE_CLASS_PLT must be 0 or 1!
+#endif
+#if ELF_RTYPE_CLASS_COPY != 0 && ELF_RTYPE_CLASS_COPY != 2
+# error ELF_RTYPE_CLASS_COPY must be 0 or 2!
+#endif
       int conflict = 0;
       struct sym_val val = { NULL, NULL };
 
@@ -1071,12 +1083,17 @@  _dl_debug_bindings (const char *undef_name, struct link_map *undef_map,
 
       if (value->s)
 	{
+	  /* Keep only ELF_RTYPE_CLASS_PLT and ELF_RTYPE_CLASS_COPY
+	     bits since since prelink only uses them.  */
+	  type_class &= ELF_RTYPE_CLASS_PLT | ELF_RTYPE_CLASS_COPY;
 	  if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
 				== STT_TLS))
-	    type_class = 4;
+	    /* Clear the RTYPE_CLASS_VALID bit in RTYPE_CLASS_TLS.  */
+	    type_class = RTYPE_CLASS_TLS & ~RTYPE_CLASS_VALID;
 	  else if (__glibc_unlikely (ELFW(ST_TYPE) (value->s->st_info)
 				     == STT_GNU_IFUNC))
-	    type_class |= 8;
+	    /* Set the RTYPE_CLASS_VALID bit.  */
+	    type_class |= RTYPE_CLASS_VALID;
 	}
 
       if (conflict
-- 
2.4.3