This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 5/5] Defer allocation of R_MIPS_REL32 GOT slots
- From: Richard Sandiford <rdsandiford at googlemail dot com>
- To: binutils at sourceware dot org
- Date: Sat, 28 Jun 2008 17:59:36 +0100
- Subject: [PATCH 5/5] Defer allocation of R_MIPS_REL32 GOT slots
The MIPS backend creates a GOT entry for a symbol S when it first sees
an input relocation that _might_ be turned into a dynamic R_MIPS_REL32
against S. However, the code defers the allocation of the relocations
themselves.
This patch defers both decisions, only allocating the GOT entry when
we allocate the associated relocations. It is only safe to do this
after the previous patches.
Tested on mips64-linux-gnu and mips64el-linux-gnu. OK to install?
That's the end of the GOT-improvement sequence. FWIW, the patches
should make it easier to divide the GGA_NORMAL are up into two:
- symbols that are referenced by 16-bit GOT offsets like
R_MIPS_GOT16
- symbols that are only referenced by 32-bit GOT offsets like
R_MIPS_GOT_HI16/R_MIPS_GOT_LO16.
This should avoid the traditional problem with -mxgot: if the whole
object doesn't use 32-bit offsets, the 16-bit accesses might still be
out of range. I think this is the reason Debian compile crtstuff.c
& co. with -mxgot.
I don't plan to implement that in the near future though. ;)
Richard
bfd/
* elfxx-mips.c (mips_elf_record_relocs): Defer allocation of a
global GOT entry when deferring allocation of dynamic relocations.
(_bfd_mips_elf_adjust_dynamic_symbol): When allocating deferred
dynamic relocations, also do the deferred allocation of a GOT entry.
Index: bfd/elfxx-mips.c
===================================================================
--- bfd/elfxx-mips.c 2008-06-28 17:14:46.000000000 +0100
+++ bfd/elfxx-mips.c 2008-06-28 17:14:50.000000000 +0100
@@ -7255,6 +7255,21 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
/* We tell the dynamic linker that there are
relocations against the text segment. */
info->flags |= DF_TEXTREL;
+
+ /* Even though we don't directly need a GOT entry for
+ this symbol, a symbol must have a dynamic symbol
+ table index greater that DT_MIPS_GOTSYM if there are
+ dynamic relocations against it. This does not apply
+ to VxWorks, which does not have the usual coupling
+ between global GOT entries and .dynsym entries. */
+ if (h != NULL && !htab->is_vxworks)
+ {
+ struct mips_elf_link_hash_entry *hmips;
+
+ hmips = (struct mips_elf_link_hash_entry *) h;
+ if (hmips->global_got_area > GGA_RELOC_ONLY)
+ hmips->global_got_area = GGA_RELOC_ONLY;
+ }
}
else
{
@@ -7269,21 +7284,6 @@ _bfd_mips_elf_check_relocs (bfd *abfd, s
are relocations against the text segment. */
hmips->readonly_reloc = TRUE;
}
-
- /* Even though we don't directly need a GOT entry for
- this symbol, a symbol must have a dynamic symbol
- table index greater that DT_MIPS_GOTSYM if there are
- dynamic relocations against it. This does not apply
- to VxWorks, which does not have the usual coupling
- between global GOT entries and .dynsym entries. */
- if (h != NULL && !htab->is_vxworks)
- {
- struct mips_elf_link_hash_entry *hmips;
-
- hmips = (struct mips_elf_link_hash_entry *) h;
- if (hmips->global_got_area > GGA_RELOC_ONLY)
- hmips->global_got_area = GGA_RELOC_ONLY;
- }
}
if (SGI_COMPAT (abfd))
@@ -7560,6 +7560,12 @@ _bfd_mips_elf_adjust_dynamic_symbol (str
&& (h->root.type == bfd_link_hash_defweak
|| !h->def_regular))
{
+ /* Even though we don't directly need a GOT entry for this symbol,
+ a symbol must have a dynamic symbol table index greater that
+ DT_MIPS_GOTSYM if there are dynamic relocations against it. */
+ if (hmips->global_got_area > GGA_RELOC_ONLY)
+ hmips->global_got_area = GGA_RELOC_ONLY;
+
mips_elf_allocate_dynamic_relocations
(dynobj, info, hmips->possibly_dynamic_relocs);
if (hmips->readonly_reloc)