diff options
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 8 | ||||
-rw-r--r-- | bfd/cpu-mips.c | 24 | ||||
-rw-r--r-- | bfd/elflink.h | 29 |
3 files changed, 54 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index d4e3a3b..6e0fe05 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2002-03-14 Alan Modra <amodra@bigpond.net.au> + + * cpu-mips.c (mips_compatible): New. Don't check bits_per_word. + (N): Use the above. + * elflink.h (elf_bfd_final_link): Revert last change. Instead, + ensure reloc size matches before calling elf_link_input_bfd. + Add an assert to check reloc size when counting output relocs. + 2002-03-14 Nick Clifton <nickc@cambridge.redhat.com> * mmo.c (mmo_get_loc): Return NULL rather than false. diff --git a/bfd/cpu-mips.c b/bfd/cpu-mips.c index 888d863..10dd0b7 100644 --- a/bfd/cpu-mips.c +++ b/bfd/cpu-mips.c @@ -1,5 +1,5 @@ /* bfd back-end for mips support - Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 2000 + Copyright 1990, 1991, 1993, 1994, 1995, 1996, 1997, 1998, 2000, 2002 Free Software Foundation, Inc. Written by Steve Chamberlain of Cygnus Support. @@ -23,6 +23,26 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "sysdep.h" #include "libbfd.h" +/* The default routine tests bits_per_word, which is wrong on mips as + mips word size doesn't correlate with reloc size. */ + +const bfd_arch_info_type * +mips_compatible (a, b) + const bfd_arch_info_type *a; + const bfd_arch_info_type *b; +{ + if (a->arch != b->arch) + return NULL; + + if (a->mach > b->mach) + return a; + + if (b->mach > a->mach) + return b; + + return a; +} + #define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \ { \ BITS_WORD, /* bits in a word */ \ @@ -34,7 +54,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ PRINT, \ 3, \ DEFAULT, \ - bfd_default_compatible, \ + mips_compatible, \ bfd_default_scan, \ NEXT, \ } diff --git a/bfd/elflink.h b/bfd/elflink.h index 3e8551f..6cb128a 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -5086,10 +5086,20 @@ elf_bfd_final_link (abfd, info) = elf_section_data (output_section); unsigned int *rel_count; unsigned int *rel_count2; + bfd_size_type entsize; + bfd_size_type entsize2; - /* We must be careful to add the relocation froms the + /* We must be careful to add the relocations from the input section to the right output count. */ - if (esdi->rel_hdr.sh_entsize == esdo->rel_hdr.sh_entsize) + entsize = esdi->rel_hdr.sh_entsize; + entsize2 = esdi->rel_hdr2 ? esdi->rel_hdr2->sh_entsize : 0; + BFD_ASSERT ((entsize == sizeof (Elf_External_Rel) + || entsize == sizeof (Elf_External_Rela)) + && entsize2 != entsize + && (entsize2 == 0 + || entsize2 == sizeof (Elf_External_Rel) + || entsize2 == sizeof (Elf_External_Rela))); + if (entsize == esdo->rel_hdr.sh_entsize) { rel_count = &esdo->rel_count; rel_count2 = &esdo->rel_count2; @@ -5319,12 +5329,21 @@ elf_bfd_final_link (abfd, info) { for (p = o->link_order_head; p != NULL; p = p->next) { + Elf_Internal_Shdr *rhdr; + if (p->type == bfd_indirect_link_order - && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) + && (bfd_get_flavour (p->u.indirect.section->owner) == bfd_target_elf_flavour) - && (sub->arch_info->bits_per_word - == abfd->arch_info->bits_per_word)) + && (((rhdr = &elf_section_data (p->u.indirect.section)->rel_hdr) + ->sh_entsize == 0) + || rhdr->sh_entsize == sizeof (Elf_External_Rel) + || rhdr->sh_entsize == sizeof (Elf_External_Rela)) + && (((rhdr = elf_section_data (p->u.indirect.section)->rel_hdr2) + == NULL) + || rhdr->sh_entsize == sizeof (Elf_External_Rel) + || rhdr->sh_entsize == sizeof (Elf_External_Rela))) { + sub = p->u.indirect.section->owner; if (! sub->output_has_begun) { if (! elf_link_input_bfd (&finfo, sub)) |