This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
RFA: R_MIPS_NONEs in .rel.dyn
- From: Richard Sandiford <rsandifo at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Mon, 15 Nov 2004 21:53:21 +0000
- Subject: RFA: R_MIPS_NONEs in .rel.dyn
This is a small tweak to the way we handle discarded dynamic relocations
for MIPS. It should speed up static and dynamic linking slightly (_very_
slightly, I expect) and IMO it makes the relocation dumps easier to read.
At the moment, if mips_elf_create_dynamic_relocation finds that
a relocation is no longer needed, it will install an R_MIPS_NONE
placeholder instead, but otherwise count it just like a normal
relocation. This means that:
(a) the relocation will be included in the sort performed by
_bfd_mips_elf_finish_dynamic_sections.
(b) the relocation will be included in the range described by
DT_REL/DT_RELSZ, meaning that it gets processed by the
dynamic linker.
I think we'd still get a correct .rel.dyn, if instead of adding an
R_MIPS_NONE, mips_elf_create_dynamic_relocation added nothing at all.
The final relocation count will then be smaller than the number of
entries in .rel.dyn, but that's OK, since .rel.dyn is initialised with
zeros anyway. We'd effectively be replacing an R_MIPS_NONE in the
middle of the section with an R_MIPS_NONE at the end.
If we do things this way, the R_MIPS_NONE won't be sorted by
_bfd_mips_elf_finish_dynamic_sections. It won't be included in
DT_REL/DT_RELSZ either, because of the following code (which I had
to add to work around an IRIX "feature"):
case DT_RELSZ:
/* Reduce DT_RELSZ to account for any relocations we
decided not to make. This is for the n64 irix rld,
which doesn't seem to apply any relocations if there
are trailing null entries. */
s = mips_elf_rel_dyn_section (dynobj, FALSE);
dyn.d_un.d_val = (s->reloc_count
* (ABI_64_P (output_bfd)
? sizeof (Elf64_Mips_External_Rel)
: sizeof (Elf32_External_Rel)));
break;
As a datapoint, I compared the DT_RELSZ of two IRIX DSOs built from
gcc HEAD. The baseline sizes were obtained with the .eh_frame patch
I posted earlier. The new sizes were obtained with the patch below
applied as well.
libgcc_s.so: 248 -> 32
libstdc++.so: 22456 -> 14382
Also, as I said at the beginning, I think this makes it easier to
read the reloc dumps. There are no more R_MIPS_NONEs in the main
body of .rel.dyn.
Tested by boostrapping & regression testing gcc on mips-sgi-irix6.5.
Also tested against the binutils testsuite on mips64-linux-gnu.
OK to install?
Richard
PS. this is a -w diff because of large reindentation.
bfd/
* elfxx-mips.c (mips_elf_create_dynamic_relocation): Return early
for discard relocations; don't add an R_MIPS_NONE to the main body
of .rel.dyn.
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.112
diff -u -p -F^\([(a-zA-Z0-9_]\|#define\) -w -r1.112 elfxx-mips.c
--- bfd/elfxx-mips.c 21 Oct 2004 15:28:29 -0000 1.112
+++ bfd/elfxx-mips.c 15 Nov 2004 21:40:54 -0000
@@ -3783,10 +3783,11 @@ mips_elf_create_dynamic_relocation (bfd
bfd_vma *addendp, asection *input_section)
{
Elf_Internal_Rela outrel[3];
- bfd_boolean skip;
asection *sreloc;
bfd *dynobj;
int r_type;
+ long indx;
+ bfd_boolean defined_p;
r_type = ELF_R_TYPE (output_bfd, rel->r_info);
dynobj = elf_hash_table (info)->dynobj;
@@ -3796,7 +3797,6 @@ mips_elf_create_dynamic_relocation (bfd
BFD_ASSERT (sreloc->reloc_count * MIPS_ELF_REL_SIZE (output_bfd)
< sreloc->size);
- skip = FALSE;
outrel[0].r_offset =
_bfd_elf_section_offset (output_bfd, info, input_section, rel[0].r_offset);
outrel[1].r_offset =
@@ -3830,26 +3830,17 @@ mips_elf_create_dynamic_relocation (bfd
if (outrel[0].r_offset == MINUS_ONE)
/* The relocation field has been deleted. */
- skip = TRUE;
- else if (outrel[0].r_offset == MINUS_TWO)
+ return TRUE;
+
+ if (outrel[0].r_offset == MINUS_TWO)
{
/* The relocation field has been converted into a relative value of
some sort. Functions like _bfd_elf_write_section_eh_frame expect
the field to be fully relocated, so add in the symbol's value. */
- skip = TRUE;
*addendp += symbol;
+ return TRUE;
}
- /* If we've decided to skip this relocation, just output an empty
- record. Note that R_MIPS_NONE == 0, so that this call to memset
- is a way of setting R_TYPE to R_MIPS_NONE. */
- if (skip)
- memset (outrel, 0, sizeof (Elf_Internal_Rela) * 3);
- else
- {
- long indx;
- bfd_boolean defined_p;
-
/* We must now calculate the dynamic symbol table index to use
in the relocation. */
if (h != NULL
@@ -3941,7 +3932,6 @@ mips_elf_create_dynamic_relocation (bfd
+ input_section->output_offset);
outrel[2].r_offset += (input_section->output_section->vma
+ input_section->output_offset);
- }
/* Put the relocation back out. We have to use the special
relocation outputter in the 64-bit case since the 64-bit
@@ -3967,7 +3957,7 @@ mips_elf_create_dynamic_relocation (bfd
|= SHF_WRITE;
/* On IRIX5, make an entry of compact relocation info. */
- if (! skip && IRIX_COMPAT (output_bfd) == ict_irix5)
+ if (IRIX_COMPAT (output_bfd) == ict_irix5)
{
asection *scpt = bfd_get_section_by_name (dynobj, ".compact_rel");
bfd_byte *cr;