This is the mail archive of the binutils@sourceware.cygnus.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]

PATCH for 64-bit MIPS ELF relocations



The 64-bit MIPS ELF ABI does not use the standard 64-bit ELF
reocations.  Instead, it uses the special structure given by
Elf64_External_Rel[a].  These structures allow the encoding of up to
three relocations per physical relocation.

Fortunately, they happen to be the same size as the standard 64-bit
ELF relocations.  It appears that no part of BFD except the back-end
actually looks to see what's in these structures, with the exception
of elf_swap_reloc[a]_{in,out}.  We don't want the usual byte-swapping
operations when using the MIPS variants; the fields lie in different
places.

This patch provides hooks for an ELF back-end to tweak the relocation
swapping.  I've verified that with the appropriate changes to the
64-bit ELF MIPS back-end the right things happen.  (Those patches are
not included here; I'm working on other things there as well.)

OK to check in?

--
Mark Mitchell                   mark@codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com

1999-07-03  Mark Mitchell  <mark@codesourcery.com>

	* elf-bfd.h (elf_backend_data): New member functions
	elf_backend_swap_reloc_in, elf_backend_swap_reloc_out,
	elf_backend_swap_reloca_in, elf_backend_swap_reloca_out.
	* elflink.h (elf_link_read_relocs_from_section): Use them.
	* elfcode.h (write_relocs): Likewise.
	* elfxx-target.h: Provide defaults for them.

Index: elf-bfd.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf-bfd.h,v
retrieving revision 1.7
diff -u -p -r1.7 elf-bfd.h
--- elf-bfd.h	1999/07/01 23:20:04	1.7
+++ elf-bfd.h	1999/07/04 01:11:35
@@ -517,6 +517,33 @@ struct elf_backend_data
   void (*elf_backend_post_process_headers)
     PARAMS ((bfd *, struct bfd_link_info *));
 
+  /* Some back-ends, like 64-bit MIPS ELF, do not use the standard 
+     relocation format.  Those back-ends should define these functions
+     to override the defaults.  Code that use these hooks still
+     expects that the size of the relocations is the same as the
+     standard.  The `bfd_byte *' parameters are treated as
+     Elf32_Exteranl_Rel[a] or Elf64_External_Rel[a] as appropriate.  */
+
+  /* This function, if defined, is called to swap in a REL
+     relocation.  */
+  void (*elf_backend_swap_reloc_in)
+    PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
+
+  /* This function, if defined, is called to swap out a REL
+     relocation.  */
+  void (*elf_backend_swap_reloc_out)
+    PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
+
+  /* This function, if defined, is called to swap in a RELA
+     relocation.  */
+  void (*elf_backend_swap_reloca_in)
+    PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
+
+  /* This function, if defined, is called to swap out a RELA
+     relocation.  */
+  void (*elf_backend_swap_reloca_out)
+    PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
+
   /* The swapping table to use when dealing with ECOFF information.
      Used for the MIPS ELF .mdebug section.  */
   const struct ecoff_debug_swap *elf_backend_ecoff_debug_swap;
Index: elflink.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elflink.h,v
retrieving revision 1.9
diff -u -p -r1.9 elflink.h
--- elflink.h	1999/07/01 23:20:07	1.9
+++ elflink.h	1999/07/04 01:11:45
@@ -2016,6 +2016,8 @@ elf_link_read_relocs_from_section (abfd,
      PTR external_relocs;
      Elf_Internal_Rela *internal_relocs;
 {
+  struct elf_backend_data *bed;
+
   /* If there aren't any relocations, that's OK.  */
   if (!shdr)
     return true;
@@ -2029,6 +2031,8 @@ elf_link_read_relocs_from_section (abfd,
       != shdr->sh_size)
     return false;
 
+  bed = get_elf_backend_data (abfd);
+
   /* Convert the external relocations to the internal format.  */
   if (shdr->sh_entsize == sizeof (Elf_External_Rel))
     {
@@ -2041,11 +2045,12 @@ elf_link_read_relocs_from_section (abfd,
       irela = internal_relocs;
       for (; erel < erelend; erel++, irela++)
 	{
-	  Elf_Internal_Rel irel;
-
-	  elf_swap_reloc_in (abfd, erel, &irel);
-	  irela->r_offset = irel.r_offset;
-	  irela->r_info = irel.r_info;
+	  if (bed->elf_backend_swap_reloc_in)
+	    (*bed->elf_backend_swap_reloc_in) (abfd, 
+					       (bfd_byte *) erel,
+					       (Elf_Internal_Rel*) irela);
+	  else
+	    elf_swap_reloc_in (abfd, erel, (Elf_Internal_Rel*) irela);
 	  irela->r_addend = 0;
 	}
     }
@@ -2061,7 +2066,14 @@ elf_link_read_relocs_from_section (abfd,
       erelaend = erela + shdr->sh_size / shdr->sh_entsize;
       irela = internal_relocs;
       for (; erela < erelaend; erela++, irela++)
-	elf_swap_reloca_in (abfd, erela, irela);
+	{
+	  if (bed->elf_backend_swap_reloca_in)
+	    (*bed->elf_backend_swap_reloca_in) (abfd, 
+						(bfd_byte *) erela, 
+						irela);
+	  else
+	    elf_swap_reloca_in (abfd, erela, irela);
+	}
     }
 
   return true;
Index: elfxx-target.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elfxx-target.h,v
retrieving revision 1.5
diff -u -p -r1.5 elfxx-target.h
--- elfxx-target.h	1999/06/04 12:45:07	1.5
+++ elfxx-target.h	1999/07/04 01:11:45
@@ -294,6 +294,18 @@ Foundation, Inc., 59 Temple Place - Suit
 #ifndef elf_backend_post_process_headers
 #define elf_backend_post_process_headers	NULL
 #endif
+#ifndef elf_backend_swap_reloc_in 
+#define elf_backend_swap_reloc_in NULL
+#endif
+#ifndef elf_backend_swap_reloc_out 
+#define elf_backend_swap_reloc_out NULL
+#endif
+#ifndef elf_backend_swap_reloca_in 
+#define elf_backend_swap_reloca_in NULL
+#endif
+#ifndef elf_backend_swap_reloca_out 
+#define elf_backend_swap_reloca_out NULL
+#endif
 
 /* Previously, backends could only use SHT_REL or SHT_RELA relocation
    sections, but not both.  They defined USE_REL to indicate SHT_REL
@@ -366,6 +378,10 @@ static CONST struct elf_backend_data elf
   elf_backend_gc_mark_hook,
   elf_backend_gc_sweep_hook,
   elf_backend_post_process_headers,
+  elf_backend_swap_reloc_in,
+  elf_backend_swap_reloc_out,
+  elf_backend_swap_reloca_in,
+  elf_backend_swap_reloca_out,
   elf_backend_ecoff_debug_swap,
   ELF_MACHINE_ALT1,
   ELF_MACHINE_ALT2,
Index: elfcode.h
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elfcode.h,v
retrieving revision 1.4
diff -u -p -r1.4 elfcode.h
--- elfcode.h	1999/06/12 17:56:25	1.4
+++ elfcode.h	1999/07/04 01:20:11
@@ -736,6 +736,7 @@ write_relocs (abfd, sec, data)
   int use_rela_p;
   asymbol *last_sym = 0;
   int last_sym_idx = 0;
+  struct elf_backend_data *bed;
 
   /* If we have already failed, don't do anything.  */
   if (*failedp)
@@ -771,6 +772,8 @@ write_relocs (abfd, sec, data)
        SHT_REL section.  */
     abort ();
 
+  bed = get_elf_backend_data (abfd);
+
   /* orelocation has the data, reloc_count has the count... */
   if (use_rela_p)
     {
@@ -823,7 +826,12 @@ write_relocs (abfd, sec, data)
 	  dst_rela.r_info = ELF_R_INFO (n, ptr->howto->type);
 
 	  dst_rela.r_addend = ptr->addend;
-	  elf_swap_reloca_out (abfd, &dst_rela, src_rela);
+	  if (bed->elf_backend_swap_reloca_out)
+	    (*bed->elf_backend_swap_reloca_out) (abfd,
+						 &dst_rela,
+						 (bfd_byte *) src_rela);
+	  else
+	    elf_swap_reloca_out (abfd, &dst_rela, src_rela);
 	}
     }
   else
@@ -874,7 +882,12 @@ write_relocs (abfd, sec, data)
 
 	  dst_rel.r_info = ELF_R_INFO (n, ptr->howto->type);
 
-	  elf_swap_reloc_out (abfd, &dst_rel, src_rel);
+	  if (bed->elf_backend_swap_reloc_out)
+	    (*bed->elf_backend_swap_reloc_out) (abfd,
+						&dst_rel,
+						(bfd_byte *) &src_rel);
+	  else
+	    elf_swap_reloc_out (abfd, &dst_rel, src_rel);
 	}
     }
 }

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