This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: Another MIPS multigot patch
On Sat, Nov 22, 2003 at 07:14:06PM +0000, Richard Sandiford wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
> > I'm using GCC 3.3.1, FYI. So it may be fixed in HEAD which I'm not
> > really set up to try at the moment. The relocation comes from:
> > lw $2,flag_dump_unnumbered
>
> Ah, never mind then. ;) I assumed this was gcc explicit-reloc output.
>
> > We're in mips_elf_global_got_index, looking at this symbol. It has
> > h->dynindx of around 3500, and global_got_dynindx is 5. g->local_gotno
> > is about 5000. So we have an overflow; that's more than 8K 8-byte
> > entries. Are you saying that the fact that there are R_MIPS_GOT_PAGE
> > entries against flag_dump_unnumbered using the primary GOT means it
> > should have a lower dynindx?
>
> Well, there are two ways we can handle the relocation:
>
> 1. Decay to R_MIPS_GOT_DISP. In that case, yes, the index
> should be lower.
>
> 2. Use a local page entry.
>
> (2) should be possible in this case, and looking at the code,
> it does seem like we try to support it.
>
> It's difficult to be sure without access to the test case, so this is
> probably completely wrong. But I'm guessing the problem is:
I can package up the testcase if you want. It's a bit large. In the
mean time, I'll look at this more tomorrow or Monday but:
> (a) _bfd_mips_elf_check_relocs assumes print-rtl.c can use a local
> page entry for GOT_PAGE/GOT_OFST accesses to flag_dump_unnumbered.
> f_d_u is therefore not entered into print-rtl's got_entries.
>
> (b) toplev uses GOT_DISP, so we end up needing a global GOT
> entry for f_d_u.
000000001028 00a900000012 R_MIPS_64 0000000000000000 flag_dump_unnumbered + 0
Type2: R_MIPS_NONE
Type3: R_MIPS_NONE
So, close enough for our purposes.
> (c) Because of (a), no bfd that uses the primary GOT seems to need
> an entry for f_d_u. We therefore give it a higher index than
> symbols that _do_ need an entry.
>
> (d) Because of (c), mips_elf_calculate_relocation assumes that f_d_u
> is !local_p, and it therefore decays the GOT_PAGE reloc into a
> GOT_DISP. So print-rtl uses f_d_u's GOT entry after all.
>
> If so, then IMO the bug is with (d). We can still use local pages
> for print-rtl, despite the entry in .dynsym.
This all makes sense to me. I'll think about what the local_p
condition really ought to be. This:
case R_MIPS_GOT_PAGE:
case R_MIPS_GOT_OFST:
/* If this symbol got a global GOT entry, we have to decay
GOT_PAGE/GOT_OFST to GOT_DISP/addend. */
local_p = local_p || ! h
|| (h->root.dynindx
< mips_elf_get_global_gotsym_index (elf_hash_table (info)
needs to become... I'm not quite sure what. Is it reasonable to use
SYMBOL_REFERENCES_LOCAL here?
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer