Other then i386 code, x86-64 code asserted on unknown relocations (rather than issuing a diagnostic). This patch puts in place a similar scheme as used on i386 for dealing with unknown relocation types and gaps in the relocation type numbering. Built and tested on x86_64-unknown-linux-gnu. Jan bfd/ 2005-07-05 Jan Beulich * elf64-x86-64.c (R_X86_64_standard, R_X86_64_vt_offset, R_X86_64_vt): New. (elf64_x86_64_info_to_howto): Use them. Don't assert validity of relocation types, issue diagnostic instead. --- /home/jbeulich/src/binutils/mainline/2005-07-05/bfd/elf64-x86-64.c 2005-06-27 09:22:54.000000000 +0200 +++ 2005-07-05/bfd/elf64-x86-64.c 2005-07-05 14:26:46.736019136 +0200 @@ -113,6 +113,13 @@ static reloc_howto_type x86_64_elf_howto bfd_elf_generic_reloc, "R_X86_64_GOTPC32", FALSE, 0xffffffff, 0xffffffff, TRUE), + /* We have a gap in the reloc numbers here. + R_X86_64_standard counts the number up to this point, and + R_X86_64_vt_offset is the value to subtract from a reloc type of + R_X86_64_GNU_VT* to form an index into this table. */ +#define R_X86_64_standard (R_X86_64_GOTPC32 + 1) +#define R_X86_64_vt_offset (R_X86_64_GNU_VTINHERIT - R_X86_64_standard) + /* GNU extension to record C++ vtable hierarchy. */ HOWTO (R_X86_64_GNU_VTINHERIT, 0, 4, 0, FALSE, 0, complain_overflow_dont, NULL, "R_X86_64_GNU_VTINHERIT", FALSE, 0, 0, FALSE), @@ -121,6 +128,9 @@ static reloc_howto_type x86_64_elf_howto HOWTO (R_X86_64_GNU_VTENTRY, 0, 4, 0, FALSE, 0, complain_overflow_dont, _bfd_elf_rel_vtable_reloc_fn, "R_X86_64_GNU_VTENTRY", FALSE, 0, 0, FALSE) + +#define R_X86_64_vt (R_X86_64_GNU_VTENTRY + 1 - R_X86_64_vt_offset) + }; /* Map BFD relocs to the x86_64 elf relocs. */ @@ -189,15 +199,13 @@ elf64_x86_64_info_to_howto (bfd *abfd AT unsigned r_type, i; r_type = ELF64_R_TYPE (dst->r_info); - if (r_type < (unsigned int) R_X86_64_GNU_VTINHERIT) - { - BFD_ASSERT (r_type <= (unsigned int) R_X86_64_GOTPC32); - i = r_type; - } - else - { - BFD_ASSERT (r_type < (unsigned int) R_X86_64_max); - i = r_type - ((unsigned int) R_X86_64_GNU_VTINHERIT - R_X86_64_GOTPC32 - 1); + if ((i = r_type) >= R_X86_64_standard + && ((i = r_type - R_X86_64_vt_offset) - R_X86_64_standard + >= R_X86_64_vt - R_X86_64_standard)) + { + (*_bfd_error_handler) (_("%B: invalid relocation type %u"), + abfd, r_type); + i = r_type = R_X86_64_NONE; } cache_ptr->howto = &x86_64_elf_howto_table[i]; BFD_ASSERT (r_type == cache_ptr->howto->type);