PATCH: PR ld/16428: autoconf tests don't terminate on ix86-linux-gnu with -static -fPIE -pie on glibc-2.18 based systems

H.J. Lu hjl.tools@gmail.com
Wed Jan 15 00:47:00 GMT 2014


On Tue, Jan 14, 2014 at 4:39 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
> On Tue, Jan 14, 2014 at 4:14 PM, H.J. Lu <hjl.tools@gmail.com> wrote:
>> On Tue, Jan 14, 2014 at 3:55 PM, Alan Modra <amodra@gmail.com> wrote:
>>> On Tue, Jan 14, 2014 at 11:06:59AM -0800, H.J. Lu wrote:
>>>>         for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
>>>>           {
>>>> -           p->count -= p->pc_count;
>>>> -           p->pc_count = 0;
>>>> +           /* Don't update reloc count if there are any non
>>>> +              pc-relative relocs.  */
>>>> +           if (!h->pointer_equality_needed)
>>>
>>> This loop invariant ought to be taken outside the loop.
>>>
>>>> +             {
>>>> +               p->count -= p->pc_count;
>>>> +               p->pc_count = 0;
>>>> +             }
>>>>             if (p->count == 0)
>>>>               *pp = p->next;
>>>>             else
>>>
>>> Note also the comment:
>>>
>>>       /* Relocs that use pc_count are those that appear on a call
>>>          insn, or certain REL relocs that can generated via assembly.
>>>          We want calls to protected symbols to resolve directly to the
>>>          function rather than going via the plt.  If people want
>>>          function pointer comparisons to work as expected then they
>>>          should avoid writing weird assembly.  */
>>>       if (SYMBOL_CALLS_LOCAL (info, h))
>>>
>>> With your patch you've effectively chosen to break protected symbols
>>> to make function pointer comparisons work..  I'm not sure that is a
>>> good idea, but if that's the way you want to go, please correct the
>>> comment too.
>>>
>>
>> I will take another look.
>>
>
> I reverted my change.
>

We discard dynamic relocations against weak undef
__ehdr_start which is defined by
assign_file_positions_for_non_load_sections later.
Glibc 2.18 started using __ehdr_start and we
under allocate dynamic relocations.  I checked in
this patch to check __ehdr_start.

Alan, many backends have the same problem.

-- 
H.J.
--
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7d13a35..f4acda0 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,12 @@
 2014-01-14  H.J. Lu  <hongjiu.lu@intel.com>

+ PR ld/16428
+ * elf32-i386.c (elf_i386_allocate_dynrelocs): Don't discard relocs
+ against __ehdr_start.
+ * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
+
+2014-01-14  H.J. Lu  <hongjiu.lu@intel.com>
+
  * elf32-i386.c (elf_i386_allocate_dynrelocs): Revert the last
  change.
  * elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Likewise.
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 4d391e1..e834a5a 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2390,9 +2390,12 @@ elf_i386_allocate_dynrelocs (struct
elf_link_hash_entry *h, void *inf)
  }

       /* Also discard relocs on undefined weak syms with non-default
-     visibility.  */
+     visibility.   Don't discard relocs against __ehdr_start which
+ will be defined by assign_file_positions_for_non_load_sections
+ later.  */
       if (eh->dyn_relocs != NULL
-  && h->root.type == bfd_link_hash_undefweak)
+  && h->root.type == bfd_link_hash_undefweak
+  && strcmp (h->root.root.string, "__ehdr_start") != 0)
  {
   if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
     eh->dyn_relocs = NULL;
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index edee8ec..f364fe4 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2473,9 +2473,12 @@ elf_x86_64_allocate_dynrelocs (struct
elf_link_hash_entry *h, void * inf)
  }

       /* Also discard relocs on undefined weak syms with non-default
- visibility.  */
+     visibility.   Don't discard relocs against __ehdr_start which
+ will be defined by assign_file_positions_for_non_load_sections
+ later.  */
       if (eh->dyn_relocs != NULL
-  && h->root.type == bfd_link_hash_undefweak)
+  && h->root.type == bfd_link_hash_undefweak
+  && strcmp (h->root.root.string, "__ehdr_start") != 0)
  {
   if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
     eh->dyn_relocs = NULL;



More information about the Binutils mailing list