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]

Re: Another MIPS multigot patch


On Sat, Jan 31, 2004 at 09:13:57PM +0000, Richard Sandiford wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
> >> >> - Are the !h and h->root.dynindx checks still needed after this?
> >> >>   (Not sure off-hand.)
> >> >
> >> > The !h test is no longer necessary.  The dynindx check still is.
> >> > h->root.dynindx == -1 will be handled by SYMBOL_REFERENCES_LOCAL, but
> >> > otherwise (if info->shared) a low dynindx and a high dynindx will be
> >> > both return FALSE.
> >> 
> >> I don't know what you mean here.  Do you have an example?
> >
> > Well, at the basic level, for a symbol with dynindx > 0 and dynindx <
> > mips_elf_get_global_gotsym SYMBOL_REFERENCES_LOCAL will return false
> > (if info->shared).
> 
> That shouldn't happen.  mips_elf_get_global_gotsym_index is the value
> associated with DT_MIPS_GOTSYM, i.e., the index of the first global GOT
> entry.  Anything in the range [0,mips_elf_get_global_gotsym_index] is
> supposed to bind locally.

Considering that the relatively recent _bfd_elf_symbol_refs_local_p is
not used from the MIPS code, I would have been amazed if it agreed on
all counts.  Indeed it does not.  I did this:

+      /* If this symbol got a global GOT entry, we might have to decay
+        GOT_PAGE/GOT_OFST to GOT_DISP/addend.  We check whether we need
+        to decay, because if we don't need to it's possible that no GOT
+        entry was allocated in this input BFD's GOT for this reference
+        (it might be in some other GOT, and out of range).  */
+      if (h && (h->root.dynindx
+               < mips_elf_get_global_gotsym_index (elf_hash_table (info)
+                                                   ->dynobj)))
+       BFD_ASSERT (_bfd_elf_symbol_refs_local_p (h, info, 1));
+      local_p = local_p || _bfd_elf_symbol_refs_local_p (h, info, 1);

and built world; the assertion failed a number of times.  The related
assertion in mips_elf_global_got_index did also:

  BFD_ASSERT (h->dynindx >= global_got_dynindx);

The first example I checked was while building ranlib.  The symbol was
_xexit_cleanup, a global function pointer.  No visibility tricks
involved, although it resolves from the shared libbfd rather than the
included static libiberty.  It failed both assertions:

(gdb) p h->dynindx
$4 = 8
(gdb) p global_got_dynindx 
$5 = 14
(gdb) p _bfd_elf_symbol_refs_local_p (h, info, 1)
$6 = 0

I would prefer to investigate this problem separately from the original
patch, which was needed for large applications to link on n64.  But if
you prefer then we can keep digging - I don't have time to figure out
what the problem with _xexit_cleanup is right now.  I have long
suspected that MIPS's crazy unique GOT handling did not honor the
symbol pre-emption rules properly.

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer


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