This is the mail archive of the
binutils@sourceware.cygnus.com
mailing list for the binutils project.
PATCH for 64-bit MIPS ELF relocations
- To: binutils@sourceware.cygnus.com
- Subject: PATCH for 64-bit MIPS ELF relocations
- From: Mark Mitchell <mark@codesourcery.com>
- Date: Sat, 03 Jul 1999 18:29:07 -0700
- Organization: CodeSourcery, LLC
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);
}
}
}