This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils 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]

mips4/32-el BFD breakage


Dear binutils developers,

Having dug into a particularly nasty problem of crashing applications that use huge shared libraries (>40000 symbols) under a MIPS4, little-endian target (I think the problem is MIPS generic, so it affects MIPS3 as well) with Linux 2.4 kernel and GLIBC 2.3.2, I came up with the
attached two patches (one for 2.15, another one for the CVS MAIN).


It seems that a change to BFD broke GLIBC's dynamic loader, which just gets a SIGSEGV whenever an application tries to link to huge shared libraries in _dl_map_object_deps.

I have traced the problem to this change:

2003-11-17 Daniel Jacobowitz <drow@mvista.com>



* elf.c (_bfd_elf_link_hash_copy_indirect): Copy

ELF_LINK_HASH_NEEDS_PLT.

  It apparently introduces ELF_LINK_HASH_NEEDS_PLT handling in
_bfd_elf_link_hash_copy_indirect which is bogus on (at least) my MIPS
with huge shared objects.

As a workaround, I've reverted this particular change by copying the
_bfd_elf_link_hash_copy_indirect implementation from elf.c to elfxx-mips.c (suffixing it with "_mips") and disabling copying of the ELF_LINK_HASH_NEEDS_PLT flag.


  As I am not a MIPS binutils expert, could one of you shed light on why
this change was required?

Thanks in advance,

Pjotr Kourzanov


--- ../../Binutils/binutils-2.15.cvs/bfd/elfxx-mips.c	2005-01-28 17:01:27.000000000 +0100
+++ bfd/elfxx-mips.c	2005-03-07 11:42:36.000000000 +0100
@@ -7595,6 +7594,62 @@
   return TRUE;
 }
 
+/* Copy data from an indirect symbol to its direct symbol, hiding the
+   old indirect symbol.  Also used for copying flags to a weakdef.  */
+
+void
+_bfd_elf_link_hash_copy_indirect_mips (const struct elf_backend_data *bed,
+				  struct elf_link_hash_entry *dir,
+				  struct elf_link_hash_entry *ind)
+{
+  bfd_signed_vma tmp;
+  bfd_signed_vma lowest_valid = bed->can_refcount;
+
+  /* Copy down any references that we may have already seen to the
+     symbol which just became indirect.  */
+
+  dir->elf_link_hash_flags
+    |= ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
+				   | ELF_LINK_HASH_REF_REGULAR
+				   | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+				   | ELF_LINK_NON_GOT_REF
+				   | 0/*ELF_LINK_HASH_NEEDS_PLT*/
+				   | ELF_LINK_POINTER_EQUALITY_NEEDED);
+
+  if (ind->root.type != bfd_link_hash_indirect)
+    return;
+
+  /* Copy over the global and procedure linkage table refcount entries.
+     These may have been already set up by a check_relocs routine.  */
+  tmp = dir->got.refcount;
+  if (tmp < lowest_valid)
+    {
+      dir->got.refcount = ind->got.refcount;
+      ind->got.refcount = tmp;
+    }
+  else
+    BFD_ASSERT (ind->got.refcount < lowest_valid);
+
+  tmp = dir->plt.refcount;
+  if (tmp < lowest_valid)
+    {
+      dir->plt.refcount = ind->plt.refcount;
+      ind->plt.refcount = tmp;
+    }
+  else
+    BFD_ASSERT (ind->plt.refcount < lowest_valid);
+
+  if (dir->dynindx == -1)
+    {
+      dir->dynindx = ind->dynindx;
+      dir->dynstr_index = ind->dynstr_index;
+      ind->dynindx = -1;
+      ind->dynstr_index = 0;
+    }
+  else
+    BFD_ASSERT (ind->dynindx == -1);
+}
+
 /* Copy data from a MIPS ELF indirect symbol to its direct symbol,
    hiding the old indirect symbol.  Process additional relocation
    information.  Also called for weakdefs, in which case we just let
@@ -7607,7 +7662,7 @@
 {
   struct mips_elf_link_hash_entry *dirmips, *indmips;
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect_mips (bed, dir, ind);
 
   if (ind->root.type != bfd_link_hash_indirect)
     return;
--- bfd/elfxx-mips.c.old	2005-03-07 11:48:21.000000000 +0100
+++ bfd/elfxx-mips.c	2005-03-06 17:26:40.000000000 +0100
@@ -8307,6 +7563,60 @@
   return TRUE;
 }
 
+/* Copy data from an indirect symbol to its direct symbol, hiding the
+   old indirect symbol.  Also used for copying flags to a weakdef.  */
+
+void
+_bfd_elf_link_hash_copy_indirect_mips (const struct elf_backend_data *bed,
+				  struct elf_link_hash_entry *dir,
+				  struct elf_link_hash_entry *ind)
+{
+  bfd_signed_vma tmp;
+  bfd_signed_vma lowest_valid = bed->can_refcount;
+
+  /* Copy down any references that we may have already seen to the
+     symbol which just became indirect.  */
+
+  dir->ref_dynamic |= ind->ref_dynamic;
+  dir->ref_regular |= ind->ref_regular;
+  dir->ref_regular_nonweak |= ind->ref_regular_nonweak;
+  dir->non_got_ref |= ind->non_got_ref;
+/*  dir->needs_plt |= ind->needs_plt; */
+  dir->pointer_equality_needed |= ind->pointer_equality_needed;
+
+  if (ind->root.type != bfd_link_hash_indirect)
+    return;
+
+  /* Copy over the global and procedure linkage table refcount entries.
+     These may have been already set up by a check_relocs routine.  */
+  tmp = dir->got.refcount;
+  if (tmp < lowest_valid)
+    {
+      dir->got.refcount = ind->got.refcount;
+      ind->got.refcount = tmp;
+    }
+  else
+    BFD_ASSERT (ind->got.refcount < lowest_valid);
+
+  tmp = dir->plt.refcount;
+  if (tmp < lowest_valid)
+    {
+      dir->plt.refcount = ind->plt.refcount;
+      ind->plt.refcount = tmp;
+    }
+  else
+    BFD_ASSERT (ind->plt.refcount < lowest_valid);
+
+  if (dir->dynindx == -1)
+    {
+      dir->dynindx = ind->dynindx;
+      dir->dynstr_index = ind->dynstr_index;
+      ind->dynindx = -1;
+      ind->dynstr_index = 0;
+    }
+  else
+    BFD_ASSERT (ind->dynindx == -1);
+}
 /* Copy data from a MIPS ELF indirect symbol to its direct symbol,
    hiding the old indirect symbol.  Process additional relocation
    information.  Also called for weakdefs, in which case we just let
@@ -8319,7 +7629,7 @@
 {
   struct mips_elf_link_hash_entry *dirmips, *indmips;
 
-  _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+  _bfd_elf_link_hash_copy_indirect_mips (bed, dir, ind);
 
   if (ind->root.type != bfd_link_hash_indirect)
     return;

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