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


>From struct mips_elf_link_hash_entry:

  /* Are we forced local?  This will only be set if we have converted
     the initial global GOT entry to a local GOT entry.  */
  bfd_boolean forced_local;

Current binutils is not really doing that conversion.  We allocate a
local GOT entry, but never use it.  When _bfd_mips_elf_hide_symbol
is called for PROVIDE_HIDDEN (__init_array_start), it increments
local_gotno.  But dynsymcount includes forced local symbols, and they
are placed above dynindx by mips_elf_sort_hash_table_f, so they
end up with entries on the global side.

mips_elf_sort_hash_table_f gave it a symbol index above dynindx
because it had got.offset == 1.  Joseph earlier established that
this happens in two places: initially in
mips_elf_record_global_got_symbol, and later to 2 and then to 1
in mips_elf_set_global_got_offset.

I see two solutions.  One is to avoid setting got.offset for forced
local symbols, and set it back to MINUS_ONE when hiding symbols.
The other is to set got.offset but still not put such symbols in the
global GOT when the time comes.

The second is easier, since we use got.offset != MINUS_ONE in
mips_elf_record_global_got_symbol to detect symbols with already
allocated GOT entries.  This patch implements that.  It fixes
Joseph's two new testcases, which should be committed along
with it.  I'm going to start more intensive testing now.

Anyone have comments on this patch?

-- 
Daniel Jacobowitz
CodeSourcery

2007-10-08  Daniel Jacobowitz  <dan@codesourcery.com>

	* elfxx-mips.c (mips_elf_sort_hash_table_f): Handle forced
	local symbols specially.
	(mips_elf_set_global_got_offset): Skip forced local symbols.

--- elfxx-mips.c.pre	2007-10-08 05:44:21.000000000 -0700
+++ elfxx-mips.c	2007-10-08 06:20:14.000000000 -0700
@@ -2842,7 +2842,8 @@ mips_elf_sort_hash_table_f (struct mips_
   /* 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
-     -1.  */
+     -1.  Forced local symbols may also be marked with got offset 1,
+     but are never given global GOT entries.  */
   if (h->root.got.offset == 2)
     {
       BFD_ASSERT (h->tls_type == GOT_NORMAL);
@@ -2851,7 +2852,7 @@ mips_elf_sort_hash_table_f (struct mips_
 	hsd->low = (struct elf_link_hash_entry *) h;
       h->root.dynindx = hsd->max_unref_got_dynindx++;
     }
-  else if (h->root.got.offset != 1)
+  else if (h->root.got.offset != 1 || h->root.forced_local)
     h->root.dynindx = hsd->max_non_got_dynindx++;
   else
     {
@@ -3459,6 +3460,7 @@ mips_elf_set_global_got_offset (void **e
 
   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)


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