]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - bfd/elf32-mips.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / bfd / elf32-mips.c
index 75acda6edb6f91de01e55535d75b07afa727e173..b9f90fdafe987613ccdeed805ccd7e0d2813ef0b 100644 (file)
@@ -30,10 +30,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #include "bfdlink.h"
 #include "genlink.h"
 #include "elf-bfd.h"
-
-#define START_RELOC_NUMBERS(name)   enum name {
-#define RELOC_NUMBER(name, number)  name = number ,
-#define END_RELOC_NUMBERS           };
 #include "elf/mips.h"
 
 /* Get the ECOFF swapping routines.  */
@@ -64,6 +60,7 @@ static int mips_elf_additional_program_headers PARAMS ((bfd *));
 static boolean mips_elf_modify_segment_map PARAMS ((bfd *));
 static INLINE int elf_mips_isa PARAMS ((flagword));
 static INLINE int elf_mips_mach PARAMS ((flagword));
+static INLINE char* elf_mips_abi_name PARAMS ((flagword));
 static boolean mips_elf32_section_from_shdr
   PARAMS ((bfd *, Elf32_Internal_Shdr *, char *));
 static boolean mips_elf32_section_processing
@@ -164,6 +161,11 @@ struct mips_got_info
 #define STUB_LI16 0x34180000   /* ori t8,zero,0 */
 #define MIPS_FUNCTION_STUB_SIZE (16)
 
+#if 0
+/* We no longer try to identify particular sections for the .dynsym
+   section.  When we do, we wind up crashing if there are other random
+   sections with relocations.  */
+
 /* Names of sections which appear in the .dynsym section in an Irix 5
    executable.  */
 
@@ -188,6 +190,8 @@ static const char * const mips_elf_dynsym_sec_names[] =
 
 #define MIPS_TEXT_DYNSYM_SECNO (3)
 
+#endif /* 0 */
+
 /* The names of the runtime procedure table symbols used on Irix 5.  */
 
 static const char * const mips_elf_dynsym_rtproc_names[] =
@@ -679,22 +683,11 @@ static reloc_howto_type elf_mips_howto_table[] =
         0x0000ffff,            /* dst_mask */
         false),                /* pcrel_offset */
 
-  /* start-sanitize-r5900 */
-  HOWTO (R_MIPS15_S3,          /* type */
-        3,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        15,                    /* bitsize */
-        false,                 /* pc_relative */
-        6,                     /* bitpos */
-        complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
-        "R_MIPS15_S3",         /* name */
-        true,                  /* partial_inplace */
-        0x001fffc0,            /* src_mask */
-        0x001fffc0,            /* dst_mask */
-        false)                 /* pcrel_offset */
-  /* end-sanitize-r5900 */
-
+  { R_MIPS_SCN_DISP },
+  { R_MIPS_REL16 },
+  { R_MIPS_ADD_IMMEDIATE },
+  { R_MIPS_PJUMP },
+  { R_MIPS_RELGOT }
 };
 
 /* The reloc used for BFD_RELOC_CTOR when doing a 64 bit link.  This
@@ -752,6 +745,23 @@ static reloc_howto_type elf_mips16_gprel_howto =
         0xffff,                /* dst_mask */
         false);                /* pcrel_offset */
 
+/* start-sanitize-r5900 */
+static reloc_howto_type elf_mips15_s3_howto =
+  HOWTO (R_MIPS15_S3,          /* type */
+        3,                     /* rightshift */
+        2,                     /* size (0 = byte, 1 = short, 2 = long) */
+        15,                    /* bitsize */
+        false,                 /* pc_relative */
+        6,                     /* bitpos */
+        complain_overflow_bitfield, /* complain_on_overflow */
+        bfd_elf_generic_reloc, /* special_function */
+        "R_MIPS15_S3",         /* name */
+        true,                  /* partial_inplace */
+        0x001fffc0,            /* src_mask */
+        0x001fffc0,            /* dst_mask */
+        false);                /* pcrel_offset */
+
+/* end-sanitize-r5900 */
 /* start-sanitize-sky */
 /* DVP relocations.
    Note that partial_inplace and pcrel_offset are backwards from the
@@ -839,7 +849,7 @@ static reloc_howto_type elf_mips_gnu_vtentry_howto =
         false,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        NULL,                  /* special_function */
+        _bfd_elf_rel_vtable_reloc_fn, /* special_function */
         "R_MIPS_GNU_VTENTRY",  /* name */
         false,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -1578,8 +1588,6 @@ dvp_u15_s3_reloc (abfd, reloc_entry, symbol, data, input_section,
      bfd *output_bfd;
      char **error_message;
 {
-  boolean relocateable;
-  bfd_reloc_status_type ret;
   bfd_vma relocation;
   bfd_vma x;
 
@@ -1655,6 +1663,11 @@ elf_mips_mach (flags)
 
     case E_MIPS_MACH_4100:
       return bfd_mach_mips4100;
+      /* start-sanitize-vr4xxx */
+
+    case E_MIPS_MACH_4121:
+      return bfd_mach_mips4121;
+      /* end-sanitize-vr4xxx */
       /* start-sanitize-vr4320 */
 
     case E_MIPS_MACH_4320:
@@ -1668,11 +1681,11 @@ elf_mips_mach (flags)
     case E_MIPS_MACH_4900:
       return bfd_mach_mips4900;
       /* end-sanitize-tx49 */
-      /* start-sanitize-vr5400 */
+      /* start-sanitize-cygnus */
 
     case E_MIPS_MACH_5400:
       return bfd_mach_mips5400;
-      /* end-sanitize-vr5400 */
+      /* end-sanitize-cygnus */
       /* start-sanitize-r5900 */
 
     case E_MIPS_MACH_5900:
@@ -1704,6 +1717,29 @@ elf_mips_mach (flags)
   return 0;
 }
 
+/* Return printable name for ABI from flagword. */
+
+static INLINE char*
+elf_mips_abi_name (flags)
+     flagword flags;
+{
+  switch (flags & EF_MIPS_ABI)
+    {
+    case 0:
+      return "none";
+    case E_MIPS_ABI_O32:
+      return "O32";
+    case E_MIPS_ABI_O64:
+      return "O64";
+    case E_MIPS_ABI_EABI32:
+      return "EABI32";
+    case E_MIPS_ABI_EABI64:
+      return "EABI64";
+    default:
+      return "unknown abi";
+    }
+}
+
 /* A mapping from BFD reloc types to MIPS ELF reloc types.  */
 
 struct elf_reloc_map {
@@ -1729,10 +1765,7 @@ static CONST struct elf_reloc_map mips_reloc_map[] =
   { BFD_RELOC_MIPS_GOT_HI16, R_MIPS_GOT_HI16 },
   { BFD_RELOC_MIPS_GOT_LO16, R_MIPS_GOT_LO16 },
   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
-  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
-  /* start-sanitize-r5900 */
-  { BFD_RELOC_MIPS15_S3, R_MIPS15_S3 },
-  /* end-sanitize-r5900 */
+  { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 }
 };
 
 /* Given a BFD reloc type, return a howto structure.  */
@@ -1752,6 +1785,10 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
 
   switch (code)
     {
+    default:
+      bfd_set_error (bfd_error_bad_value);
+      return NULL;
+
     case BFD_RELOC_CTOR:
       /* We need to handle BFD_RELOC_CTOR specially.
         Select the right relocation (R_MIPS_32 or R_MIPS_64) based on the
@@ -1765,6 +1802,10 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
       return &elf_mips16_jump_howto;
     case BFD_RELOC_MIPS16_GPREL:
       return &elf_mips16_gprel_howto;
+/* start-sanitize-r5900 */
+    case BFD_RELOC_MIPS15_S3:
+      return &elf_mips15_s3_howto;
+/* end-sanitize-r5900 */
 /* start-sanitize-sky */
     case BFD_RELOC_MIPS_DVP_11_PCREL:
       return &elf_mips_dvp_11_pcrel_howto;
@@ -1780,8 +1821,6 @@ bfd_elf32_bfd_reloc_type_lookup (abfd, code)
     case BFD_RELOC_VTABLE_ENTRY:
       return &elf_mips_gnu_vtentry_howto;
     }
-
-  return NULL;
 }
 
 /* Given a MIPS reloc type, fill in an arelent structure.  */
@@ -1803,6 +1842,11 @@ mips_info_to_howto_rel (abfd, cache_ptr, dst)
     case R_MIPS16_GPREL:
       cache_ptr->howto = &elf_mips16_gprel_howto;
       break;
+/* start-sanitize-r5900 */
+    case R_MIPS15_S3:
+      cache_ptr->howto = &elf_mips15_s3_howto;
+      break;
+/* end-sanitize-r5900 */
 /* start-sanitize-sky */
     case R_MIPS_DVP_11_PCREL:
       cache_ptr->howto = &elf_mips_dvp_11_pcrel_howto;
@@ -2078,6 +2122,7 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
       break;
 
     case bfd_mach_mips4000:
+    case bfd_mach_mips4300:
       val = E_MIPS_ARCH_3;
       break;
 
@@ -2088,6 +2133,12 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
     case bfd_mach_mips4100:
       val = E_MIPS_ARCH_3 | E_MIPS_MACH_4100;
       break;
+      /* start-sanitize-vr4xxx */
+
+    case bfd_mach_mips4121:
+      val = E_MIPS_ARCH_3 | E_MIPS_MACH_4121;
+      break;
+      /* end-sanitize-vr4xxx */
       /* start-sanitize-vr4320 */
 
     case bfd_mach_mips4320:
@@ -2104,12 +2155,12 @@ _bfd_mips_elf_final_write_processing (abfd, linker)
       val = E_MIPS_ARCH_3 | E_MIPS_MACH_4900;
       break;
       /* end-sanitize-tx49 */
-      /* start-sanitize-vr5400 */
+      /* start-sanitize-cygnus */
 
     case bfd_mach_mips5400:
       val = E_MIPS_ARCH_3 | E_MIPS_MACH_5400;
       break;
-      /* end-sanitize-vr5400 */
+      /* end-sanitize-cygnus */
       /* start-sanitize-r5900 */
 
     case bfd_mach_mips5900:
@@ -2361,6 +2412,24 @@ _bfd_mips_elf_merge_private_bfd_data (ibfd, obfd)
       old_flags &= ~ (EF_MIPS_ARCH | EF_MIPS_MACH);
     }
 
+  /* Compare ABI's */
+  if ((new_flags & EF_MIPS_ABI) != (old_flags & EF_MIPS_ABI))
+    {
+      /* Only error if both are set (to different values). */
+      if ((new_flags & EF_MIPS_ABI)
+         && (old_flags & EF_MIPS_ABI))
+       {
+         (*_bfd_error_handler)
+           (_("%s: ABI mismatch: linking %s module with previous %s modules"),
+            bfd_get_filename (ibfd),
+            elf_mips_abi_name (new_flags),
+            elf_mips_abi_name (old_flags));
+         ok = false;
+       }
+      new_flags &= ~EF_MIPS_ABI;
+      old_flags &= ~EF_MIPS_ABI;
+    }
+
   /* Warn about any other mismatches */
   if (new_flags != old_flags)
     {
@@ -2401,7 +2470,7 @@ _bfd_mips_elf_section_from_shdr (abfd, hdr, name)
   switch (hdr->sh_type)
     {
     case SHT_MIPS_LIBLIST:
-      if (strcmp (name, _(".liblist")) != 0)
+      if (strcmp (name, ".liblist") != 0)
        return false;
       break;
     case SHT_MIPS_MSYM:
@@ -2626,7 +2695,10 @@ _bfd_mips_elf_fake_sections (abfd, hdr, sec)
               || strcmp (name, ".dynstr") == 0))
     {
       hdr->sh_entsize = 0;
+#if 0
+      /* This isn't how the Irix 6 linker behaves.  */
       hdr->sh_info = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#endif
     }
   else if (strcmp (name, ".got") == 0
           || strcmp (name, ".sdata") == 0
@@ -3342,6 +3414,11 @@ _bfd_mips_elf_find_nearest_line (abfd, section, symbols, offset, filename_ptr,
 {
   asection *msec;
 
+  if (_bfd_dwarf1_find_nearest_line (abfd, section, symbols, offset,
+                                    filename_ptr, functionname_ptr,
+                                    line_ptr))
+    return true;
+
   if (_bfd_dwarf2_find_nearest_line (abfd, section, symbols, offset,
                                     filename_ptr, functionname_ptr,
                                     line_ptr))
@@ -3503,8 +3580,11 @@ struct mips_elf_link_hash_entry
 struct mips_elf_link_hash_table
 {
   struct elf_link_hash_table root;
+#if 0
+  /* We no longer use this.  */
   /* String section indices for the dynamic section symbols.  */
   bfd_size_type dynsym_sec_strindex[SIZEOF_MIPS_DYNSYM_SECNAMES];
+#endif
   /* The number of .rtproc entries.  */
   bfd_size_type procedure_count;
   /* The size of the .compact_rel section (if SGI_COMPAT).  */
@@ -3589,7 +3669,6 @@ mips_elf_link_hash_table_create (abfd)
      bfd *abfd;
 {
   struct mips_elf_link_hash_table *ret;
-  unsigned int i;
 
   ret = ((struct mips_elf_link_hash_table *)
         bfd_alloc (abfd, sizeof (struct mips_elf_link_hash_table)));
@@ -3603,8 +3682,11 @@ mips_elf_link_hash_table_create (abfd)
       return NULL;
     }
 
+#if 0
+  /* We no longer use this.  */
   for (i = 0; i < SIZEOF_MIPS_DYNSYM_SECNAMES; i++)
     ret->dynsym_sec_strindex[i] = (bfd_size_type) -1;
+#endif
   ret->procedure_count = 0;
   ret->compact_rel_size = 0;
   ret->use_rld_obj_head = false;
@@ -4932,6 +5014,9 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
          || r_type == R_MIPS_GNU_VTENTRY)
        continue;
       if ((r_type < 0 || r_type >= (int) R_MIPS_max)
+/* start-sanitize-r5900 */
+         && r_type != R_MIPS15_S3
+/* end-sanitize-r5900 */
 /* start-sanitize-sky */
          && r_type != R_MIPS_DVP_11_PCREL
          && r_type != R_MIPS_DVP_27_S4
@@ -4948,6 +5033,10 @@ mips_elf_relocate_section (output_bfd, info, input_bfd, input_section,
        howto = &elf_mips16_jump_howto;
       else if (r_type == R_MIPS16_GPREL)
        howto = &elf_mips16_gprel_howto;
+/* start-sanitize-r5900 */
+      else if (r_type == R_MIPS15_S3)
+       howto = &elf_mips15_s3_howto;
+/* end-sanitize-r5900 */
 /* start-sanitize-sky */
       else if (r_type == R_MIPS_DVP_11_PCREL)
        howto = &elf_mips_dvp_11_pcrel_howto;
@@ -6547,6 +6636,9 @@ mips_elf_gc_mark_hook (abfd, info, rel, h, sym)
 
            case bfd_link_hash_common:
              return h->root.u.c.p->section;
+
+           default:
+             break;
            }
        }
     }
@@ -7078,15 +7170,20 @@ mips_elf_size_dynamic_sections (output_bfd, info)
      That means we must increment the dynamic symbol index of every
      other dynamic symbol.  */
   {
-    const char * const *namep;
     unsigned int c, i;
-    bfd_size_type strindex;
-    struct bfd_strtab_hash *dynstr;
     struct mips_got_info *g;
 
     c = 0;
     if (elf_hash_table (info)->dynamic_sections_created)
       {
+#if 0
+       /* We no longer try to restrict the set of sections which get
+           dynamic symbol table entries, since it fails if we have
+           other random sections which need dynamic relocations.  */
+       const char * const *namep;
+       bfd_size_type strindex;
+       struct bfd_strtab_hash *dynstr;
+
        if (SGI_COMPAT (output_bfd))
          {
            c = SIZEOF_MIPS_DYNSYM_SECNAMES - 1;
@@ -7114,6 +7211,7 @@ mips_elf_size_dynamic_sections (output_bfd, info)
              }
          }
        else
+#endif /* 0 */
          {
            c = bfd_count_sections (output_bfd);
            elf_link_hash_traverse (elf_hash_table (info),
@@ -7470,8 +7568,11 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
              break;
 
            case DT_MIPS_UNREFEXTNO:
-             /* XXX FIXME: */
+#if 0
              dyn.d_un.d_val = SIZEOF_MIPS_DYNSYM_SECNAMES;
+#else
+             dyn.d_un.d_val = bfd_count_sections (output_bfd);
+#endif
              bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
 
@@ -7509,12 +7610,7 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
   {
     asection *sdynsym;
     asection *s;
-    unsigned int i;
-    bfd_vma last;
     Elf_Internal_Sym sym;
-    long dindx;
-    const char *name;
-    const char * const * namep = mips_elf_dynsym_sec_names;
     Elf32_compact_rel cpt;
 
     /* Set up the section symbols for the output sections. SGI sets
@@ -7523,6 +7619,16 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
     sdynsym = bfd_get_section_by_name (dynobj, ".dynsym");
     if (sdynsym != NULL)
       {
+#if 0
+       const char *name;
+       const char * const * namep = mips_elf_dynsym_sec_names;
+       unsigned int i;
+       bfd_vma last;
+       long dindx;
+
+       /* We no longer try to restrict the set of sections which get
+           dynamic symbol table entries, since it fails if we have
+           other random sections which need dynamic relocations.  */
        if (SGI_COMPAT (output_bfd))
          {
            sym.st_size = 0;
@@ -7567,6 +7673,7 @@ mips_elf_finish_dynamic_sections (output_bfd, info)
              SIZEOF_MIPS_DYNSYM_SECNAMES;
          }
        else
+#endif /* 0 */
          {
            sym.st_size = 0;
            sym.st_name = 0;