This is the mail archive of the binutils@sourceware.cygnus.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]

MIPS*/ELF symbol versioning resolved


Hi,

 I believe the attached patch fixes the problems with versioned symbols on
MIPS*/ELF platforms.  I am now able to compile glibc-2.1.2 for
mipsel-linux, at least.  Looking at binaries, it seems both symbols and
relocations are getting set right.  I cannot test runtime behaviour,
though, as I do not have an environment yet. 

 Any comments are welcomed.

  Maciej

-- 
+  Maciej W. Rozycki, Technical University of Gdansk, Poland   +
+--------------------------------------------------------------+
+        e-mail: macro@ds2.pg.gda.pl, PGP key available        +

diff -u --recursive --new-file binutils.macro/bfd/elf32-mips.c binutils/bfd/elf32-mips.c
--- binutils.macro/bfd/elf32-mips.c	Fri Oct  8 16:41:22 1999
+++ binutils/bfd/elf32-mips.c	Wed Nov 10 00:37:02 1999
@@ -179,7 +179,7 @@
 static struct mips_got_info *mips_elf_got_info 
   PARAMS ((bfd *, asection **));
 static boolean mips_elf_local_relocation_p
-  PARAMS ((bfd *, const Elf_Internal_Rela *, asection **));
+  PARAMS ((bfd *, const Elf_Internal_Rela *, asection **, boolean));
 static bfd_vma mips_elf_create_local_got_entry 
   PARAMS ((bfd *, struct mips_got_info *, asection *, bfd_vma));
 static bfd_vma mips_elf_got16_entry 
@@ -5042,24 +5042,42 @@
 /* Return whether a relocation is against a local symbol.  */
 
 static boolean
-mips_elf_local_relocation_p (input_bfd, relocation, local_sections)
+mips_elf_local_relocation_p (input_bfd, relocation, local_sections,
+			     check_forced)
      bfd *input_bfd;
      const Elf_Internal_Rela *relocation;
      asection **local_sections;
+     boolean check_forced;
 {
   unsigned long r_symndx;
   Elf_Internal_Shdr *symtab_hdr;
+  struct mips_elf_link_hash_entry* h;
+  size_t extsymoff;
 
   r_symndx = ELF32_R_SYM (relocation->r_info);
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
-  if (! elf_bad_symtab (input_bfd))
-    return r_symndx < symtab_hdr->sh_info;
-  else
+  extsymoff = (elf_bad_symtab (input_bfd)) ? 0 : symtab_hdr->sh_info;
+
+  if (r_symndx < extsymoff)
+    return true;
+  if (elf_bad_symtab (input_bfd) && local_sections[r_symndx] != NULL)
+    return true;
+
+  if (check_forced)
     {
-      /* The symbol table does not follow the rule that local symbols
-	 must come before globals.  */
-      return local_sections[r_symndx] != NULL;
+      /* Look up the hash table to check whether the symbol
+	 was forced local.  */
+      h = (struct mips_elf_link_hash_entry *)
+	  elf_sym_hashes (input_bfd) [r_symndx - extsymoff];
+      /* Find the real hash-table entry for this symbol.  */
+      while (h->root.type == bfd_link_hash_indirect
+	     || h->root.type == bfd_link_hash_warning)
+        h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
+      if ((h->root.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)
+        return true;
     }
+
+  return false;
 }
 
 /* Sign-extend VALUE, which has the indicated number of BITS.  */
@@ -5541,7 +5559,10 @@
 				   & ELF_LINK_HASH_DEF_REGULAR) == 0))
 	{
 	  indx = h->root.dynindx;
-	  BFD_ASSERT (indx != -1);
+	  /* h->root.dynindx may be -1 if this symbol was marked to
+	     become local.  */
+	  if (indx == -1)
+		indx = 0;
 	}
       else
 	{
@@ -5739,7 +5760,7 @@
      used in the array of hash table entries.  */
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   local_p = mips_elf_local_relocation_p (input_bfd, relocation,
-					 local_sections);
+					 local_sections, false);
   if (! elf_bad_symtab (input_bfd))
     extsymoff = symtab_hdr->sh_info;
   else
@@ -5780,8 +5801,8 @@
       h = ((struct mips_elf_link_hash_entry *) 
 	   elf_sym_hashes (input_bfd) [r_symndx - extsymoff]);
       /* Find the real hash-table entry for this symbol.  */
-      while (h->root.type == bfd_link_hash_indirect
-	     || h->root.type == bfd_link_hash_warning)
+      while (h->root.root.type == bfd_link_hash_indirect
+	     || h->root.root.type == bfd_link_hash_warning)
 	h = (struct mips_elf_link_hash_entry *) h->root.root.u.i.link;
       
       /* Record the name of this symbol, for our caller.  */
@@ -5907,6 +5928,9 @@
   *require_jalxp = (!info->relocateable
 		    && ((r_type == R_MIPS16_26) != target_is_16_bit_code_p));
 
+  local_p = mips_elf_local_relocation_p (input_bfd, relocation,
+					 local_sections, true);
+
   /* If we haven't already determined the GOT offset, or the GP value,
      and we're going to need it, get it now.  */
   switch (r_type)
@@ -6481,7 +6505,7 @@
 	      if (r_type == R_MIPS_HI16
 		  || (r_type == R_MIPS_GOT16
 		      && mips_elf_local_relocation_p (input_bfd, rel,
-						      local_sections)))
+						      local_sections, false)))
 		{
 		  bfd_vma l;
 		  const Elf_Internal_Rela *lo16_relocation;
@@ -6539,7 +6563,8 @@
 	     relative in which case we need to adjust by the amount
 	     that we're adjusting GP in this relocateable object.  */
 
-	  if (!mips_elf_local_relocation_p (input_bfd, rel, local_sections))
+	  if (!mips_elf_local_relocation_p (input_bfd, rel, local_sections,
+					    false))
 	    /* There's nothing to do for non-local relocations.  */
 	    continue;
 
@@ -8165,7 +8190,8 @@
       sym->st_value = gval;
     }
 
-  BFD_ASSERT (h->dynindx != -1);
+  BFD_ASSERT (h->dynindx != -1
+	      || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0);
 
   sgot = mips_elf_got_section (dynobj);
   BFD_ASSERT (sgot != NULL);
diff -u --recursive --new-file binutils.macro/bfd/elflink.h binutils/bfd/elflink.h
--- binutils.macro/bfd/elflink.h	Fri Oct  8 16:41:22 1999
+++ binutils/bfd/elflink.h	Thu Oct 28 21:52:36 1999
@@ -3597,6 +3597,7 @@
 			      h->elf_link_hash_flags &=~
 				ELF_LINK_HASH_NEEDS_PLT;
 			      h->dynindx = -1;
+			      --elf_hash_table (info)->dynsymcount;
 			      h->plt.offset = (bfd_vma) -1;
 			      /* FIXME: The name of the symbol has
 				 already been recorded in the dynamic
@@ -3711,6 +3712,7 @@
 			  h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
 			  h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
 			  h->dynindx = -1;
+			  --elf_hash_table (info)->dynsymcount;
 			  h->plt.offset = (bfd_vma) -1;
 			  /* FIXME: The name of the symbol has already
 			     been recorded in the dynamic string table
@@ -3735,6 +3737,7 @@
 	      h->elf_link_hash_flags |= ELF_LINK_FORCED_LOCAL;
 	      h->elf_link_hash_flags &=~ ELF_LINK_HASH_NEEDS_PLT;
 	      h->dynindx = -1;
+	      --elf_hash_table (info)->dynsymcount;
 	      h->plt.offset = (bfd_vma) -1;
 	      /* FIXME: The name of the symbol has already been
 		 recorded in the dynamic string table section.  */


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