diff options
Diffstat (limited to 'bfd/elfn32-mips.c')
-rw-r--r-- | bfd/elfn32-mips.c | 109 |
1 files changed, 75 insertions, 34 deletions
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c index b1211f0c65e5..e0994a0dd068 100644 --- a/bfd/elfn32-mips.c +++ b/bfd/elfn32-mips.c @@ -1,6 +1,6 @@ /* MIPS-specific support for 32-bit ELF Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - 2003, 2004, 2005 Free Software Foundation, Inc. + 2003, 2004, 2005, 2007 Free Software Foundation, Inc. Most of the information added by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>. @@ -29,8 +29,8 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. different MIPS ELF from other targets. This matters when linking. This file supports both, switching at runtime. */ -#include "bfd.h" #include "sysdep.h" +#include "bfd.h" #include "libbfd.h" #include "bfdlink.h" #include "genlink.h" @@ -61,8 +61,6 @@ static bfd_reloc_status_type gprel32_with_gp (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma); static bfd_reloc_status_type mips_elf_shift6_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); -static bfd_reloc_status_type mips16_jump_reloc - (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_reloc_status_type mips16_gprel_reloc (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup @@ -756,6 +754,21 @@ static reloc_howto_type elf_mips_howto_table_rel[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; /* The relocation table used for SHT_RELA sections. */ @@ -1429,6 +1442,21 @@ static reloc_howto_type elf_mips_howto_table_rela[] = 0x0000ffff, /* src_mask */ 0x0000ffff, /* dst_mask */ FALSE), /* pcrel_offset */ + + /* 32 bit relocation with no addend. */ + HOWTO (R_MIPS_GLOB_DAT, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 32, /* bitsize */ + FALSE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont, /* complain_on_overflow */ + _bfd_mips_elf_generic_reloc, /* special_function */ + "R_MIPS_GLOB_DAT", /* name */ + FALSE, /* partial_inplace */ + 0x0, /* src_mask */ + 0xffffffff, /* dst_mask */ + FALSE), /* pcrel_offset */ }; static reloc_howto_type elf_mips16_howto_table_rel[] = @@ -1444,7 +1472,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] = /* This needs complex overflow detection, because the upper four bits must match the PC. */ - mips16_jump_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS16_26", /* name */ TRUE, /* partial_inplace */ 0x3ffffff, /* src_mask */ @@ -1516,7 +1544,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] = /* This needs complex overflow detection, because the upper four bits must match the PC. */ - mips16_jump_reloc, /* special_function */ + _bfd_mips_elf_generic_reloc, /* special_function */ "R_MIPS16_26", /* name */ FALSE, /* partial_inplace */ 0x3ffffff, /* src_mask */ @@ -1901,28 +1929,6 @@ mips_elf_shift6_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol, error_message); } -/* Handle a mips16 jump. */ - -static bfd_reloc_status_type -mips16_jump_reloc (bfd *abfd ATTRIBUTE_UNUSED, - arelent *reloc_entry ATTRIBUTE_UNUSED, - asymbol *symbol ATTRIBUTE_UNUSED, - void *data ATTRIBUTE_UNUSED, - asection *input_section, bfd *output_bfd ATTRIBUTE_UNUSED, - char **error_message ATTRIBUTE_UNUSED) -{ - static bfd_boolean warned = FALSE; - - /* FIXME. */ - if (! warned) - (*_bfd_error_handler) - (_("Linking mips16 objects into %s format is not supported"), - bfd_get_target (input_section->output_section->owner)); - warned = TRUE; - - return bfd_reloc_undefined; -} - /* Handle a mips16 GP relative reloc. */ static bfd_reloc_status_type @@ -2075,6 +2081,40 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, } } +static reloc_howto_type * +bfd_elf32_bfd_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, + const char *r_name) +{ + unsigned int i; + + for (i = 0; + i < (sizeof (elf_mips_howto_table_rela) + / sizeof (elf_mips_howto_table_rela[0])); + i++) + if (elf_mips_howto_table_rela[i].name != NULL + && strcasecmp (elf_mips_howto_table_rela[i].name, r_name) == 0) + return &elf_mips_howto_table_rela[i]; + + for (i = 0; + i < (sizeof (elf_mips16_howto_table_rela) + / sizeof (elf_mips16_howto_table_rela[0])); + i++) + if (elf_mips16_howto_table_rela[i].name != NULL + && strcasecmp (elf_mips16_howto_table_rela[i].name, r_name) == 0) + return &elf_mips16_howto_table_rela[i]; + + if (strcasecmp (elf_mips_gnu_vtinherit_howto.name, r_name) == 0) + return &elf_mips_gnu_vtinherit_howto; + if (strcasecmp (elf_mips_gnu_vtentry_howto.name, r_name) == 0) + return &elf_mips_gnu_vtentry_howto; + if (strcasecmp (elf_mips_gnu_rel16_s2.name, r_name) == 0) + return &elf_mips_gnu_rel16_s2; + if (strcasecmp (elf_mips_gnu_rela16_s2.name, r_name) == 0) + return &elf_mips_gnu_rela16_s2; + + return NULL; +} + /* Given a MIPS Elf_Internal_Rel, fill in an arelent structure. */ static reloc_howto_type * @@ -2317,12 +2357,15 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define elf_backend_create_dynamic_sections \ _bfd_mips_elf_create_dynamic_sections #define elf_backend_check_relocs _bfd_mips_elf_check_relocs +#define elf_backend_merge_symbol_attribute \ + _bfd_mips_elf_merge_symbol_attribute #define elf_backend_adjust_dynamic_symbol \ _bfd_mips_elf_adjust_dynamic_symbol #define elf_backend_always_size_sections \ _bfd_mips_elf_always_size_sections #define elf_backend_size_dynamic_sections \ _bfd_mips_elf_size_dynamic_sections +#define elf_backend_init_index_section _bfd_elf_init_1_index_section #define elf_backend_relocate_section _bfd_mips_elf_relocate_section #define elf_backend_finish_dynamic_symbol \ _bfd_mips_elf_finish_dynamic_symbol @@ -2380,10 +2423,8 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #define TARGET_BIG_SYM bfd_elf32_nbigmips_vec #define TARGET_BIG_NAME "elf32-nbigmips" -/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses - a value of 0x1000, and we are compatible. - FIXME: How does this affect NewABI? */ -#define ELF_MAXPAGESIZE 0x1000 +#define ELF_MAXPAGESIZE 0x10000 +#define ELF_COMMONPAGESIZE 0x1000 #include "elf32-target.h" @@ -2394,15 +2435,15 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = { #undef TARGET_BIG_NAME #undef ELF_MAXPAGESIZE +#undef ELF_COMMONPAGESIZE #define TARGET_LITTLE_SYM bfd_elf32_ntradlittlemips_vec #define TARGET_LITTLE_NAME "elf32-ntradlittlemips" #define TARGET_BIG_SYM bfd_elf32_ntradbigmips_vec #define TARGET_BIG_NAME "elf32-ntradbigmips" -/* The SVR4 MIPS ABI says that this should be 0x10000, and Linux uses - page sizes of up to that limit, so we need to respect it. */ #define ELF_MAXPAGESIZE 0x10000 +#define ELF_COMMONPAGESIZE 0x1000 #define elf32_bed elf32_tradbed /* Include the target file again for this target. */ |