public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH for 64-bit MIPS ELF relocations
@ 1999-07-03 18:24 Mark Mitchell
  1999-07-06 17:59 ` Ian Lance Taylor
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Mitchell @ 1999-07-03 18:24 UTC (permalink / raw)
  To: binutils

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);
 	}
     }
 }

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH for 64-bit MIPS ELF relocations
  1999-07-03 18:24 PATCH for 64-bit MIPS ELF relocations Mark Mitchell
@ 1999-07-06 17:59 ` Ian Lance Taylor
  1999-07-07 11:42   ` Mark Mitchell
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Lance Taylor @ 1999-07-06 17:59 UTC (permalink / raw)
  To: mark; +Cc: binutils

   From: Mark Mitchell <mark@codesourcery.com>
   Date: Sat, 03 Jul 1999 18:29:07 -0700

   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.)

Sorry it took a while to respond to this.

   @@ -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;
	   }
	}

This code appears to be a type pun which relies on the fact that a
pointer to Elf_Internal_Rela can be safely cast to a pointer to
Elf_Internal_Rel, because the fields in Elf_Internal_Rel happen to be
the initial fields in Elf_Internal_Rela.  I don't like those sorts of
puns in general, and I consider this one to be unsafe because it
assumes that nobody will ever add a field to Elf_Internal_Rel.  This
is of course unlikely, but note that somebody did add a field to
Elf_Internal_Shdr, so it is not impossible.

I think that better than this would be to change elf_swap_reloc_in to
accept a pointer to Elf_Internal_Rela, along with an appropriate
comment about this oddity.


I also don't see what the MIPS specific function reloc swap function
is going to do.  Assuming that Elf64_Mips_Internal_Rel is the same
size as Elf_Internal_Rel is not merely risky, it is actually certain
to be false on systems with a 64 bit long, such as the Alpha.  You can
make assumptions about the size of the external structs--those have
known formats.  However, you can not make assumptions about the size
of the internal structs.

Ian

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: PATCH for 64-bit MIPS ELF relocations
  1999-07-06 17:59 ` Ian Lance Taylor
@ 1999-07-07 11:42   ` Mark Mitchell
  0 siblings, 0 replies; 3+ messages in thread
From: Mark Mitchell @ 1999-07-07 11:42 UTC (permalink / raw)
  To: ian; +Cc: binutils

   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.

OK, let's try this a different way.  This patch handles this situation
in a type-safe manner.  If you look closely at this patch, you'll see
a new field (hash_entry_size) in elf_size_info not used for anything
just yet.  The next patch, immediately following this, uses this
field.  (I just didn't take the time to generate two separate patches
for the one or two hunks, both touching elf_size_info).  If, however,
you approve this patch, and not the other, then I will remove the
extraneous hash_entry_size bits before check-in.

How about this version?

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

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

	* elf-bfd.h (elf_size_info): Add hash_entry_size,
	int_rels_per_ext_rel, swap_dyn_out, swap_reloc_in, swap_reloc_out,
	wap_reloca_in, and swap_reloca_out. 
	* elflink.h (elf_link_read_relocs_from_section): Adjust to handle
	multiple internal relocations per external relocation.
	(link_read_relocs): Likewise.
	(elf_bfd_final_link): Likewise.
	(elf_link_input_bfd): Likewise.
	(elf_gc_mark): Likewise.
	(elf_gc_smash_unused_vtentry_relocs): Likewise.
	* elfcode.h (elf_swap_dyn_out): Adjust type to match
	elf_swap_dyn_in.
	(size_info): Add entries for new fields.
	* elf64-mips.c (mips_elf64_swap_reloc_out): Enable.
	(mips_elf64_be_swap_reloc_in): New function.
	(mips_elf64_be_swap_reloc_out): Likewise.
	(mips_elf64_be_swap_reloca_in): Likewise.
	(mips_elf64_be_swap_reloca_out): Likewise.
	(mips_elf64_size_info): Add entries for new fields.
	
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/07 18:16:41
@@ -236,6 +236,13 @@ struct elf_size_info {
   unsigned char sizeof_ehdr, sizeof_phdr, sizeof_shdr;
   unsigned char sizeof_rel, sizeof_rela, sizeof_sym, sizeof_dyn, sizeof_note;
 
+  /* The size of entries in the .hash section.  */
+  unsigned char sizeof_hash_entry;
+
+  /* The number of internal relocations to allocate per external
+     relocation entry.  */
+  unsigned char int_rels_per_ext_rel;
+
   unsigned char arch_size, file_align;
   unsigned char elfclass, ev_current;
   int (*write_out_phdrs) PARAMS ((bfd *, const Elf_Internal_Phdr *, int));
@@ -246,6 +253,32 @@ struct elf_size_info {
     PARAMS ((bfd *, asection *, asymbol **, boolean));
   long (*slurp_symbol_table) PARAMS ((bfd *, asymbol **, boolean));
   void (*swap_dyn_in) PARAMS ((bfd *, const PTR, Elf_Internal_Dyn *));
+  void (*swap_dyn_out) PARAMS ((bfd *, const Elf_Internal_Dyn *, PTR));
+
+  /* This function, if defined, is called to swap in a REL
+     relocation.  If an external relocation corresponds to more than
+     one internal relocation, then all relocations are swapped in at
+     once.  */
+  void (*swap_reloc_in)
+    PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
+
+  /* This function, if defined, is called to swap out a REL
+     relocation.  */
+  void (*swap_reloc_out)
+    PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
+
+  /* This function, if defined, is called to swap in a RELA
+     relocation.  If an external relocation corresponds to more than
+     one internal relocation, then all relocations are swapped in at
+     once.  */
+  void (*swap_reloca_in)
+    PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
+
+  /* This function, if defined, is called to swap out a RELA
+     relocation.  */
+  void (*swap_reloca_out)
+    PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
+
 };
 
 #define elf_symbol_from(ABFD,S) \
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/07 18:16:50
@@ -2016,6 +2018,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,24 +2033,36 @@ 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))
     {
       Elf_External_Rel *erel;
       Elf_External_Rel *erelend;
       Elf_Internal_Rela *irela;
+      Elf_Internal_Rel *irel;
 
       erel = (Elf_External_Rel *) external_relocs;
       erelend = erel + shdr->sh_size / shdr->sh_entsize;
       irela = internal_relocs;
-      for (; erel < erelend; erel++, irela++)
+      irel = bfd_alloc (abfd, (bed->s->int_rels_per_ext_rel
+			       * sizeof (Elf_Internal_Rel)));
+      for (; erel < erelend; erel++, irela += bed->s->int_rels_per_ext_rel)
 	{
-	  Elf_Internal_Rel irel;
+	  int i;
+
+	  if (bed->s->swap_reloc_in)
+	    (*bed->s->swap_reloc_in) (abfd, (bfd_byte *) erel, irel);
+	  else
+	    elf_swap_reloc_in (abfd, erel, irel);
 
-	  elf_swap_reloc_in (abfd, erel, &irel);
-	  irela->r_offset = irel.r_offset;
-	  irela->r_info = irel.r_info;
-	  irela->r_addend = 0;
+	  for (i = 0; i < bed->s->int_rels_per_ext_rel; ++i)
+	    {
+	      irela[i].r_offset = irel[i].r_offset;
+	      irela[i].r_info = irel[i].r_info;
+	      irela[i].r_addend = 0;
+	    }
 	}
     }
   else
@@ -2060,8 +2076,13 @@ elf_link_read_relocs_from_section (abfd,
       erela = (Elf_External_Rela *) external_relocs;
       erelaend = erela + shdr->sh_size / shdr->sh_entsize;
       irela = internal_relocs;
-      for (; erela < erelaend; erela++, irela++)
-	elf_swap_reloca_in (abfd, erela, irela);
+      for (; erela < erelaend; erela++, irela += bed->s->int_rels_per_ext_rel)
+	{
+	  if (bed->s->swap_reloca_in)
+	    (*bed->s->swap_reloca_in) (abfd, (bfd_byte *) erela, irela);
+	  else
+	    elf_swap_reloca_in (abfd, erela, irela);
+	}
     }
 
   return true;
@@ -2089,6 +2110,7 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o
   Elf_Internal_Shdr *rel_hdr;
   PTR alloc1 = NULL;
   Elf_Internal_Rela *alloc2 = NULL;
+  struct elf_backend_data *bed = get_elf_backend_data (abfd);
 
   if (elf_section_data (o)->relocs != NULL)
     return elf_section_data (o)->relocs;
@@ -2102,7 +2124,8 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o
     {
       size_t size;
 
-      size = o->reloc_count * sizeof (Elf_Internal_Rela);
+      size = (o->reloc_count * bed->s->int_rels_per_ext_rel 
+	      * sizeof (Elf_Internal_Rela));
       if (keep_memory)
 	internal_relocs = (Elf_Internal_Rela *) bfd_alloc (abfd, size);
       else
@@ -2131,7 +2154,8 @@ NAME(_bfd_elf,link_read_relocs) (abfd, o
       (abfd, 
        elf_section_data (o)->rel_hdr2,
        ((bfd_byte *) external_relocs) + rel_hdr->sh_size,
-       internal_relocs + rel_hdr->sh_size / rel_hdr->sh_entsize))
+       internal_relocs + (rel_hdr->sh_size / rel_hdr->sh_entsize
+			  * bed->s->int_rels_per_ext_rel)))
     goto error_return;
 
   /* Cache the results for next time, if we can.  */
@@ -3991,7 +4018,8 @@ elf_bfd_final_link (abfd, info)
   finfo.external_relocs = (PTR) bfd_malloc (max_external_reloc_size);
   finfo.internal_relocs = ((Elf_Internal_Rela *)
 			   bfd_malloc (max_internal_reloc_count
-				       * sizeof (Elf_Internal_Rela)));
+				       * sizeof (Elf_Internal_Rela)
+				       * bed->s->int_rels_per_ext_rel));
   finfo.external_syms = ((Elf_External_Sym *)
 			 bfd_malloc (max_sym_count
 				     * sizeof (Elf_External_Sym)));
@@ -4845,10 +4876,11 @@ elf_link_input_bfd (finfo, input_bfd)
   long *pindex;
   asection **ppsection;
   asection *o;
+  struct elf_backend_data *bed;
 
   output_bfd = finfo->output_bfd;
-  relocate_section =
-    get_elf_backend_data (output_bfd)->elf_backend_relocate_section;
+  bed = get_elf_backend_data (output_bfd);
+  relocate_section = bed->elf_backend_relocate_section;
 
   /* If this is a dynamic object, we don't want to do anything here:
      we don't want the local symbols, and we don't want the section
@@ -5085,7 +5117,8 @@ elf_link_input_bfd (finfo, input_bfd)
 	      /* Adjust the reloc addresses and symbol indices.  */
 
 	      irela = internal_relocs;
-	      irelaend = irela + o->reloc_count;
+	      irelaend = 
+		irela + o->reloc_count * bed->s->int_rels_per_ext_rel;
 	      rel_hash = (elf_section_data (o->output_section)->rel_hashes
 			  + o->output_section->reloc_count);
 	      for (; irela < irelaend; irela++, rel_hash++)
@@ -5695,6 +5728,7 @@ elf_gc_mark (info, sec, gc_mark_hook)
       size_t extsymoff;
       Elf_External_Sym *locsyms, *freesyms = NULL;
       bfd *input_bfd = sec->owner;
+      struct elf_backend_data *bed = get_elf_backend_data (input_bfd);
 
       /* GCFIXME: how to arrange so that relocs and symbols are not
 	 reread continually?  */
@@ -5738,7 +5772,7 @@ elf_gc_mark (info, sec, gc_mark_hook)
 	  ret = false;
 	  goto out1;
 	}
-      relend = relstart + sec->reloc_count;
+      relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
 
       for (rel = relstart; rel < relend; rel++)
 	{
@@ -5944,6 +5978,7 @@ elf_gc_smash_unused_vtentry_relocs (h, o
   asection *sec;
   bfd_vma hstart, hend;
   Elf_Internal_Rela *relstart, *relend, *rel;
+  struct elf_backend_data *bed;
 
   /* Take care of both those symbols that do not describe vtables as
      well as those that are not loaded.  */
@@ -5961,7 +5996,8 @@ elf_gc_smash_unused_vtentry_relocs (h, o
 	      (sec->owner, sec, NULL, (Elf_Internal_Rela *) NULL, true));
   if (!relstart)
     return *(boolean *)okp = false;
-  relend = relstart + sec->reloc_count;
+  bed = get_elf_backend_data (sec->owner);
+  relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel;
 
   for (rel = relstart; rel < relend; ++rel)
     if (rel->r_offset >= hstart && rel->r_offset < hend)
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/07 18:16:47
@@ -423,11 +423,13 @@ elf_swap_dyn_in (abfd, p, dst)
 }
 
 INLINE void
-elf_swap_dyn_out (abfd, src, dst)
+elf_swap_dyn_out (abfd, src, p)
      bfd *abfd;
      const Elf_Internal_Dyn *src;
-     Elf_External_Dyn *dst;
+     PTR p;
 {
+  Elf_External_Dyn *dst = (Elf_External_Dyn *) p;
+
   put_word (abfd, src->d_tag, dst->d_tag);
   put_word (abfd, src->d_un.d_val, dst->d_un.d_val);
 }
@@ -1500,7 +1504,8 @@ const struct elf_size_info NAME(_bfd_elf
   sizeof (Elf_External_Sym),
   sizeof (Elf_External_Dyn),
   sizeof (Elf_External_Note),
-
+  ARCH_SIZE / 8,
+  1,
   ARCH_SIZE, FILE_ALIGN,
   ELFCLASS, EV_CURRENT,
   elf_write_out_phdrs,
@@ -1509,5 +1514,10 @@ const struct elf_size_info NAME(_bfd_elf
   elf_swap_symbol_out,
   elf_slurp_reloc_table,
   elf_slurp_symbol_table,
-  elf_swap_dyn_in
+  elf_swap_dyn_in,
+  elf_swap_dyn_out,
+  NULL,
+  NULL,
+  NULL,
+  NULL
 };
Index: elf64-mips.c
===================================================================
RCS file: /cvs/binutils/binutils/bfd/elf64-mips.c,v
retrieving revision 1.4
diff -u -p -r1.4 elf64-mips.c
--- elf64-mips.c	1999/06/02 18:17:59	1.4
+++ elf64-mips.c	1999/07/07 18:16:46
@@ -52,14 +54,20 @@ static void mips_elf64_swap_reloc_in
 static void mips_elf64_swap_reloca_in
   PARAMS ((bfd *, const Elf64_Mips_External_Rela *,
 	   Elf64_Mips_Internal_Rela *));
-#if 0
 static void mips_elf64_swap_reloc_out
   PARAMS ((bfd *, const Elf64_Mips_Internal_Rel *,
 	   Elf64_Mips_External_Rel *));
-#endif
 static void mips_elf64_swap_reloca_out
   PARAMS ((bfd *, const Elf64_Mips_Internal_Rela *,
 	   Elf64_Mips_External_Rela *));
+static void mips_elf64_be_swap_reloc_in
+  PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rel *));
+static void mips_elf64_be_swap_reloc_out
+  PARAMS ((bfd *, const Elf_Internal_Rel *, bfd_byte *));
+static void mips_elf64_be_swap_reloca_in
+  PARAMS ((bfd *, const bfd_byte *, Elf_Internal_Rela *));
+static void mips_elf64_be_swap_reloca_out
+  PARAMS ((bfd *, const Elf_Internal_Rela *, bfd_byte *));
 static reloc_howto_type *mips_elf64_reloc_type_lookup
   PARAMS ((bfd *, bfd_reloc_code_real_type));
 static long mips_elf64_get_reloc_upper_bound PARAMS ((bfd *, asection *));
@@ -1220,10 +1231,6 @@ mips_elf64_swap_reloca_in (abfd, src, ds
   dst->r_addend = bfd_h_get_signed_64 (abfd, (bfd_byte *) src->r_addend);
 }
 
-#if 0
-
-/* This is not currently used.  */
-
 /* Swap out a MIPS 64-bit Rel reloc.  */
 
 static void
@@ -1240,8 +1247,6 @@ mips_elf64_swap_reloc_out (abfd, src, ds
   bfd_h_put_8 (abfd, src->r_type, (bfd_byte *) dst->r_type);
 }
 
-#endif /* 0 */
-
 /* Swap out a MIPS 64-bit Rela reloc.  */
 
 static void
@@ -1259,6 +1264,96 @@ mips_elf64_swap_reloca_out (abfd, src, d
   bfd_h_put_64 (abfd, src->r_addend, (bfd_byte *) dst->r_addend);
 }
 
+/* Swap in a MIPS 64-bit Rel reloc.  */
+
+static void
+mips_elf64_be_swap_reloc_in (abfd, src, dst)
+     bfd *abfd;
+     const bfd_byte *src;
+     Elf_Internal_Rel *dst;
+{
+  Elf64_Mips_Internal_Rel mirel;
+
+  mips_elf64_swap_reloc_in (abfd, 
+			    (const Elf64_Mips_External_Rel *) src,
+			    &mirel);
+
+  dst[0].r_offset = mirel.r_offset;
+  dst[0].r_info = ELF32_R_INFO (mirel.r_sym, mirel.r_type);
+  dst[1].r_offset = mirel.r_offset;
+  dst[1].r_info = ELF32_R_INFO (mirel.r_ssym, mirel.r_type2);
+  dst[2].r_offset = mirel.r_offset;
+  dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirel.r_type3);
+}
+
+/* Swap in a MIPS 64-bit Rela reloc.  */
+
+static void
+mips_elf64_be_swap_reloca_in (abfd, src, dst)
+     bfd *abfd;
+     const bfd_byte *src;
+     Elf_Internal_Rela *dst;
+{
+  Elf64_Mips_Internal_Rela mirela;
+
+  mips_elf64_swap_reloca_in (abfd, 
+			     (const Elf64_Mips_External_Rela *) src,
+			     &mirela);
+
+  dst[0].r_offset = mirela.r_offset;
+  dst[0].r_info = ELF32_R_INFO (mirela.r_sym, mirela.r_type);
+  dst[0].r_addend = mirela.r_addend;
+  dst[1].r_offset = mirela.r_offset;
+  dst[1].r_info = ELF32_R_INFO (mirela.r_ssym, mirela.r_type2);
+  dst[1].r_addend = 0;
+  dst[2].r_offset = mirela.r_offset;
+  dst[2].r_info = ELF32_R_INFO (STN_UNDEF, mirela.r_type3);
+  dst[2].r_addend = 0;
+}
+
+/* Swap out a MIPS 64-bit Rel reloc.  */
+
+static void
+mips_elf64_be_swap_reloc_out (abfd, src, dst)
+     bfd *abfd;
+     const Elf_Internal_Rel *src;
+     bfd_byte *dst;
+{
+  Elf64_Mips_Internal_Rel mirel;
+
+  mirel.r_offset = src->r_offset;
+  mirel.r_type = ELF32_R_TYPE (src->r_info);
+  mirel.r_sym = ELF32_R_SYM (src->r_info);
+  mirel.r_type2 = R_MIPS_NONE;
+  mirel.r_ssym = STN_UNDEF;
+  mirel.r_type3 = R_MIPS_NONE;
+
+  mips_elf64_swap_reloc_out (abfd, &mirel, 
+			     (Elf64_Mips_External_Rel *) dst);
+}
+
+/* Swap out a MIPS 64-bit Rela reloc.  */
+
+static void
+mips_elf64_be_swap_reloca_out (abfd, src, dst)
+     bfd *abfd;
+     const Elf_Internal_Rela *src;
+     bfd_byte *dst;
+{
+  Elf64_Mips_Internal_Rela mirela;
+
+  mirela.r_offset = src->r_offset;
+  mirela.r_type = ELF32_R_TYPE (src->r_info);
+  mirela.r_addend = src->r_addend;
+  mirela.r_sym = ELF32_R_SYM (src->r_info);
+  mirela.r_type2 = R_MIPS_NONE;
+  mirela.r_ssym = STN_UNDEF;
+  mirela.r_type3 = R_MIPS_NONE;
+
+  mips_elf64_swap_reloca_out (abfd, &mirela, 
+			      (Elf64_Mips_External_Rela *) dst);
+}
+
 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
 
 struct elf_reloc_map
@@ -2099,6 +2144,8 @@ const struct elf_size_info mips_elf64_si
   sizeof (Elf64_External_Sym),
   sizeof (Elf64_External_Dyn),
   sizeof (Elf_External_Note),
+  4,            /* hash-table entry size */
+  3,            /* internal relocations per external relocations */
   64,		/* arch_size */
   8,		/* file_align */
   ELFCLASS64,
@@ -2109,7 +2156,12 @@ const struct elf_size_info mips_elf64_si
   bfd_elf64_swap_symbol_out,
   mips_elf64_slurp_reloc_table,
   bfd_elf64_slurp_symbol_table,
-  bfd_elf64_swap_dyn_in
+  bfd_elf64_swap_dyn_in,
+  bfd_elf64_swap_dyn_out,
+  mips_elf64_be_swap_reloc_in,
+  mips_elf64_be_swap_reloc_out,
+  mips_elf64_be_swap_reloca_in,
+  mips_elf64_be_swap_reloca_out
 };
 
 #define TARGET_LITTLE_SYM		bfd_elf64_littlemips_vec

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~1999-07-07 11:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1999-07-03 18:24 PATCH for 64-bit MIPS ELF relocations Mark Mitchell
1999-07-06 17:59 ` Ian Lance Taylor
1999-07-07 11:42   ` Mark Mitchell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).