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, Nov 22, 2003 at 04:31:10PM +0000, Richard Sandiford wrote:
> Daniel Jacobowitz <drow@mvista.com> writes:
> > Currently I can't build an n64 GCC (with my other patches applied to the
> > linker).  The error is an R_MIPS_GOT_PAGE overflow for a common variable
> > (flag_dump_unnumbered?).
> 
> Ouch.  An R_MIPS_GOT_PAGE against a global symbol?  OK, so it's supposed
> to work, but gcc shouldn't really be generating that.  Can you send me
> the .i file?

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

Let me know if you want the .i anyway.

> > Here's the problem:
> > 
> >   if (1)
> >     {
> >       gg->assigned_gotno = gg->global_gotno - g->global_gotno;
> >       g->global_gotno = gg->global_gotno;
> >       set_got_offset_arg.value = 2;
> >     }
> > 
> > With this, global_gotno increases by a substantial amount.  If the primary
> > GOT was full, then the odds are good that there is now a 16-bit relocation
> > in the primary GOT that can no longer be resolved.
> 
> Not sure I understand.  We're supposed to order the master GOT so that
> the symbols in the primary GOT come first.  Is that not happening for
> some reason?

I'm not sure I understand this code either - the fact that the *_gotno
fields change meaning halfway through compilation is really confusing,
since the comments do not clearly explain both meanings.  Let me sketch
what goes wrong.

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?  I see that dynindx's are set in
mips_elf_sort_hash_table_f, which is called after the GOT is formed.

Hmm, and I see that at the time of the relocation overflow,
h->root.got.offset is 2, suggesting that it is unreferenced.  That's
peculiar and suggests I had the wrong problem - why isn't it marked?
print-rtl.o is definitely mapped to the primary GOT according to
bfd2got.

It looks like the problem is one of common symbols. 
flag_dump_unnumbered occurs in toplev.o and print-rtl.o.  These two
functions end up in different GOTs.  The hash table for the master got
(gg) contains a GOT entry for this symbol, but it's pointing to
toplev.o.  The primary got is used for print-rtl.o.  And the symbol for
flag_dump_unnumbered ends up being associated with print-rtl.o in its
link hash (h->root.u.def.sec.owner).

It's hard to grub through the hash table to find out but it seems that
print-rtl.o's got_entries hash has nothing about flag_dump_unnumbered.
So I guess that's the real problem.  I'm guessing the two references
were somehow coalesced earlier?

-- 
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]