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

Re: Ping Re: Patch for MIPS multi-got bug with forced-local symbols


Here is a revised version of this patch 
<http://sourceware.org/ml/binutils/2007-09/msg00266.html>.  I found a new 
related case of failure (with both unpatched binutils and binutils with my 
previous patch applied), as shown by the second new test added, and fixed 
by the

+      && !entry->d.h->forced_local

added to mips_elf_set_global_got_offset.

Tested with cross to mips-linux-gnu.  OK to commit?

bfd:
2007-09-28  Joseph Myers  <joseph@codesourcery.com>

	* elfxx-mips.c (struct mips_got_info): Add forced_local_count.
	(struct mips_elf_hash_sort_data): Add forced_local and
	prev_forced_local.
	(mips_elf_sort_hash_table): Subtract g->forced_local_count in
	computing hsd.min_got_dynindx.  Initialize hsd.forced_local and
	hsd.prev_forced_local.  Set g->forced_local_count after sorting.
	(mips_elf_sort_hash_table_f): Count forced-local symbols.  Handle
	them as unreferenced where allowed for in calculation of
	min_got_dynindx.
	(mips_elf_make_got_per_bfd, mips_elf_multi_got,
	mips_elf_create_got_section): Initialize forced_local_count.
	(_bfd_mips_elf_always_size_sections): Subtract forced_local_count
	in calculating global_gotno.
	(_bfd_mips_elf_final_link): Subtract forced_local_count in
	assertion.
	(mips_elf_set_global_got_offset): Check for forced-local symbols
	before assigning global GOT offsets.

ld/testsuite:
2007-09-28  Joseph Myers  <joseph@codesourcery.com>

	* ld-mips-elf/multi-got-hidden-1.d,
	ld-mips-elf/multi-got-hidden-1.s,
	ld-mips-elf/multi-got-hidden-2.d,
	ld-mips-elf/multi-got-hidden-2.s: New.
	* ld-mips-elf/mips-elf.exp: Run multi-got-hidden tests.

(To keep down the size of this patch, multi-got-hidden-2.s is omitted;
it's the result of "cat multi-got-1-2.s multi-got-hidden-1.s".)

Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.215
diff -u -r1.215 elfxx-mips.c
--- bfd/elfxx-mips.c	26 Sep 2007 13:45:32 -0000	1.215
+++ bfd/elfxx-mips.c	28 Sep 2007 22:40:43 -0000
@@ -143,6 +143,9 @@
      because a single-GOT link may have multiple hash table entries
      for the LDM.  It does not get initialized in multi-GOT mode.  */
   bfd_vma tls_ldm_offset;
+  /* The number of forced-local entries being counted as global found
+     during sorting.  */
+  unsigned int forced_local_count;
 };
 
 /* Map an input bfd to a got in a multi-got link.  */
@@ -234,6 +237,10 @@
   /* The greatest dynamic symbol table index not corresponding to a
      symbol without a GOT entry.  */
   long max_non_got_dynindx;
+  /* The number of forced-local entries being counted as global.  */
+  long forced_local;
+  /* The number of such entries found previously.  */
+  long prev_forced_local;
 };
 
 /* The MIPS ELF linker needs additional information for each symbol in
@@ -2757,8 +2764,10 @@
        referenced, we move them to the end of the GOT, so that they
        don't prevent other entries that are referenced from getting
        too large offsets.  */
-    - (g->next ? g->assigned_gotno : 0);
+    - (g->next ? g->assigned_gotno : 0) - g->forced_local_count;
   hsd.max_non_got_dynindx = max_local;
+  hsd.forced_local = 0;
+  hsd.prev_forced_local = g->forced_local_count;
   mips_elf_link_hash_traverse (((struct mips_elf_link_hash_table *)
 				elf_hash_table (info)),
 			       mips_elf_sort_hash_table_f,
@@ -2774,6 +2783,8 @@
      table index in the GOT.  */
   g->global_gotsym = hsd.low;
 
+  g->forced_local_count = hsd.forced_local;
+
   return TRUE;
 }
 
@@ -2794,6 +2805,9 @@
   if (h->root.dynindx == -1)
     return TRUE;
 
+  if (h->forced_local)
+    hsd->forced_local++;
+
   /* Global symbols that need GOT entries that are not explicitly
      referenced are marked with got offset 2.  Those that are
      referenced get a 1, and those that don't need GOT entries get
@@ -2812,8 +2826,13 @@
     {
       BFD_ASSERT (h->tls_type == GOT_NORMAL);
 
-      h->root.dynindx = --hsd->min_got_dynindx;
-      hsd->low = (struct elf_link_hash_entry *) h;
+      if (h->forced_local && hsd->forced_local <= hsd->prev_forced_local)
+	h->root.dynindx = hsd->max_unref_got_dynindx++;
+      else
+	{
+	  h->root.dynindx = --hsd->min_got_dynindx;
+	  hsd->low = (struct elf_link_hash_entry *) h;
+	}
     }
 
   return TRUE;
@@ -3044,6 +3063,7 @@
       g->tls_gotno = 0;
       g->tls_assigned_gotno = 0;
       g->tls_ldm_offset = MINUS_ONE;
+      g->forced_local_count = 0;
       g->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
 					mips_elf_multi_got_entry_eq, NULL);
       if (g->got_entries == NULL)
@@ -3269,6 +3289,7 @@
 
   if (entry->abfd != NULL && entry->symndx == -1
       && entry->d.h->root.dynindx != -1
+      && !entry->d.h->forced_local
       && entry->d.h->tls_type == GOT_NORMAL)
     {
       if (g)
@@ -3451,6 +3472,7 @@
       g->next->assigned_gotno = 0;
       g->next->tls_assigned_gotno = 0;
       g->next->tls_ldm_offset = MINUS_ONE;
+      g->next->forced_local_count = 0;
       g->next->got_entries = htab_try_create (1, mips_elf_multi_got_entry_hash,
 					      mips_elf_multi_got_entry_eq,
 					      NULL);
@@ -3816,6 +3838,7 @@
   g->bfd2got = NULL;
   g->next = NULL;
   g->tls_ldm_offset = MINUS_ONE;
+  g->forced_local_count = 0;
   g->got_entries = htab_try_create (1, mips_elf_got_entry_hash,
 				    mips_elf_got_entry_eq, NULL);
   if (g->got_entries == NULL)
@@ -7254,7 +7277,8 @@
     return FALSE;
 
   if (g->global_gotsym != NULL)
-    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx;
+    i = elf_hash_table (info)->dynsymcount - g->global_gotsym->dynindx
+	- g->forced_local_count;
   else
     /* If there are no global symbols, or none requiring
        relocations, then GLOBAL_GOTSYM will be NULL.  */
@@ -10309,7 +10333,8 @@
 
       if (g->global_gotsym != NULL)
 	BFD_ASSERT ((elf_hash_table (info)->dynsymcount
-		     - g->global_gotsym->dynindx)
+		     - g->global_gotsym->dynindx
+		     - g->forced_local_count)
 		    <= g->global_gotno);
     }
 
Index: ld/testsuite/ld-mips-elf/mips-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-mips-elf/mips-elf.exp,v
retrieving revision 1.47
diff -u -r1.47 mips-elf.exp
--- ld/testsuite/ld-mips-elf/mips-elf.exp	13 Aug 2007 21:16:39 -0000	1.47
+++ ld/testsuite/ld-mips-elf/mips-elf.exp	28 Sep 2007 22:40:44 -0000
@@ -68,6 +68,8 @@
 if { $linux_gnu } {
     run_dump_test "multi-got-1"
     run_dump_test "multi-got-no-shared"
+    run_dump_test "multi-got-hidden-1"
+    run_dump_test "multi-got-hidden-2"
 }
 
 if $has_newabi {
Index: ld/testsuite/ld-mips-elf/multi-got-hidden-1.d
===================================================================
RCS file: ld/testsuite/ld-mips-elf/multi-got-hidden-1.d
diff -N ld/testsuite/ld-mips-elf/multi-got-hidden-1.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/multi-got-hidden-1.d	28 Sep 2007 22:40:44 -0000
@@ -0,0 +1,8 @@
+#name: MIPS multi-got-hidden-1
+#as: -EB -32 -KPIC
+#source: multi-got-1-1.s
+#source: multi-got-1-2.s
+#source: multi-got-hidden-1.s
+#ld: -melf32btsmip -e 0
+#objdump: -dr
+#pass
Index: ld/testsuite/ld-mips-elf/multi-got-hidden-1.s
===================================================================
RCS file: ld/testsuite/ld-mips-elf/multi-got-hidden-1.s
diff -N ld/testsuite/ld-mips-elf/multi-got-hidden-1.s
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/multi-got-hidden-1.s	28 Sep 2007 22:40:44 -0000
@@ -0,0 +1,5 @@
+.hidden __init_array_end
+.hidden __init_array_start
+sym_3_1:
+la $2, __init_array_start
+la $2, __init_array_end
Index: ld/testsuite/ld-mips-elf/multi-got-hidden-2.d
===================================================================
RCS file: ld/testsuite/ld-mips-elf/multi-got-hidden-2.d
diff -N ld/testsuite/ld-mips-elf/multi-got-hidden-2.d
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ ld/testsuite/ld-mips-elf/multi-got-hidden-2.d	28 Sep 2007 22:40:44 -0000
@@ -0,0 +1,7 @@
+#name: MIPS multi-got-hidden-2
+#as: -EB -32 -KPIC
+#source: multi-got-1-1.s
+#source: multi-got-hidden-2.s
+#ld: -melf32btsmip -e 0
+#objdump: -dr
+#pass

-- 
Joseph S. Myers
joseph@codesourcery.com


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