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]

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;


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