This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: compatibility of (mips ELF) .o files between binutils versions?
Hi Chris,
> all of the tools used were built from fresh tarballs from
> ftp://ftp.gnu.org/pub/gnu/binutils/
Yup - as already reported this problem has been fixed in the mainline
sources (and hence the new 2.13 branch as well) but not on the 2.12
branch. The patch that catches the problem is this one:
2002-05-21 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
* elf-bfd.h (elf_backend_emit_relocs): Change prototype to return
an error value.
* elflink.h (elf_link_output_relocs): Likewise. Improve error message.
return with false on error.
(elf_link_input_bfd): Check reloc_emitter return value.
(diffs attached at the end of this email). I doubt if there is much
point in applying this patch to the 2_12 branch at this late date
however.
Of cource this does not resolve the underlying problem that the size
of the relocs emitted by the MIPS port have changed between 2.11 and
2.12. This does represent a binary incompatibility between releases
which is a Bad Thing (tm). Ideally the port ought to be able to
handle both the old sized relocs and the new sized ones.
Maybe someone would like to volunteer to do this ?
Cheers
Nick
Index: elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -c -3 -p -w -r1.70 -r1.71
*** elf-bfd.h 15 May 2002 00:18:55 -0000 1.70
--- elf-bfd.h 21 May 2002 16:03:46 -0000 1.71
*************** struct elf_backend_data
*** 706,712 ****
/* Emit relocations. Overrides default routine for emitting relocs,
except during a relocatable link, or if all relocs are being emitted. */
! void (*elf_backend_emit_relocs)
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
/* Count relocations. Not called for relocatable links
--- 706,712 ----
/* Emit relocations. Overrides default routine for emitting relocs,
except during a relocatable link, or if all relocs are being emitted. */
! boolean (*elf_backend_emit_relocs)
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
/* Count relocations. Not called for relocatable links
Index: elflink.h
===================================================================
RCS file: /cvs/src/src/bfd/elflink.h,v
retrieving revision 1.160
retrieving revision 1.161
diff -c -3 -p -w -r1.160 -r1.161
*** elflink.h 15 May 2002 00:18:56 -0000 1.160
--- elflink.h 21 May 2002 16:03:46 -0000 1.161
*************** static boolean elf_link_read_relocs_from
*** 65,71 ****
PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
static size_t compute_bucket_count
PARAMS ((struct bfd_link_info *));
! static void elf_link_output_relocs
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
static boolean elf_link_size_reloc_section
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
--- 65,71 ----
PARAMS ((bfd *, Elf_Internal_Shdr *, PTR, Elf_Internal_Rela *));
static size_t compute_bucket_count
PARAMS ((struct bfd_link_info *));
! static boolean elf_link_output_relocs
PARAMS ((bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *));
static boolean elf_link_size_reloc_section
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
*************** elf_link_output_extsym (h, data)
*** 6254,6260 ****
originated from the section given by INPUT_REL_HDR) to the
OUTPUT_BFD. */
! static void
elf_link_output_relocs (output_bfd, input_section, input_rel_hdr,
internal_relocs)
bfd *output_bfd;
--- 6254,6260 ----
originated from the section given by INPUT_REL_HDR) to the
OUTPUT_BFD. */
! static boolean
elf_link_output_relocs (output_bfd, input_section, input_rel_hdr,
internal_relocs)
bfd *output_bfd;
*************** elf_link_output_relocs (output_bfd, inpu
*** 6286,6293 ****
output_rel_hdr = elf_section_data (output_section)->rel_hdr2;
rel_countp = &elf_section_data (output_section)->rel_count2;
}
!
! BFD_ASSERT (output_rel_hdr != NULL);
bed = get_elf_backend_data (output_bfd);
irela = internal_relocs;
--- 6286,6301 ----
output_rel_hdr = elf_section_data (output_section)->rel_hdr2;
rel_countp = &elf_section_data (output_section)->rel_count2;
}
! else
! {
! (*_bfd_error_handler) (
! _("%s: relocation size mismatch in %s section %s"),
! bfd_get_filename (output_bfd),
! bfd_archive_filename (input_section->owner),
! input_section->name);
! bfd_set_error (bfd_error_wrong_object_format);
! return false;
! }
bed = get_elf_backend_data (output_bfd);
irela = internal_relocs;
*************** elf_link_output_relocs (output_bfd, inpu
*** 6344,6349 ****
--- 6352,6359 ----
/* Bump the counter, so that we know where to add the next set of
relocations. */
*rel_countp += NUM_SHDR_ENTRIES (input_rel_hdr);
+
+ return true;
}
/* Link an input file into the linker output file. This function
*************** elf_link_input_bfd (finfo, input_bfd)
*** 6754,6760 ****
struct elf_link_hash_entry **rel_hash;
Elf_Internal_Shdr *input_rel_hdr;
unsigned int next_erel;
! void (*reloc_emitter) PARAMS ((bfd *, asection *,
Elf_Internal_Shdr *,
Elf_Internal_Rela *));
boolean rela_normal;
--- 6764,6770 ----
struct elf_link_hash_entry **rel_hash;
Elf_Internal_Shdr *input_rel_hdr;
unsigned int next_erel;
! boolean (*reloc_emitter) PARAMS ((bfd *, asection *,
Elf_Internal_Shdr *,
Elf_Internal_Rela *));
boolean rela_normal;
*************** elf_link_input_bfd (finfo, input_bfd)
*** 6913,6927 ****
else
reloc_emitter = elf_link_output_relocs;
! (*reloc_emitter) (output_bfd, o, input_rel_hdr, internal_relocs);
input_rel_hdr = elf_section_data (o)->rel_hdr2;
if (input_rel_hdr)
{
internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel);
! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
! internal_relocs);
}
}
--- 6923,6940 ----
else
reloc_emitter = elf_link_output_relocs;
! if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
! internal_relocs))
! return false;
input_rel_hdr = elf_section_data (o)->rel_hdr2;
if (input_rel_hdr)
{
internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr)
* bed->s->int_rels_per_ext_rel);
! if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr,
! internal_relocs))
! return false;
}
}