2005-02-14 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / bfd / elf32-mips.c
index 299c39546bc2329f857fac39dcb12873248cf1ba..5c259f101f32ae7f405c152e37e00c1306c37e32 100644 (file)
@@ -1,6 +1,6 @@
 /* MIPS-specific support for 32-bit ELF
    Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-   2003 Free Software Foundation, Inc.
+   2003, 2004 Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -47,14 +47,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 #define ECOFF_SIGNED_32
 #include "ecoffswap.h"
 
-static bfd_reloc_status_type mips_elf_generic_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_hi16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_lo16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type mips_elf_got16_reloc
-  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type gprel32_with_gp
   (bfd *, asymbol *, arelent *, asection *, bfd_boolean, void *, bfd_vma);
 static bfd_reloc_status_type mips_elf_gprel32_reloc
@@ -120,7 +112,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_NONE",         /* name */
         FALSE,                 /* partial_inplace */
         0,                     /* src_mask */
@@ -135,7 +127,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_16",           /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -150,7 +142,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_32",           /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -165,7 +157,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_REL32",        /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -183,7 +175,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
                                /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC + 4.  */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_26",           /* name */
         TRUE,                  /* partial_inplace */
         0x03ffffff,            /* src_mask */
@@ -192,13 +184,13 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,          /* type */
-        0,                     /* rightshift */
+        16,                    /* rightshift */
         2,                     /* size (0 = byte, 1 = short, 2 = long) */
         16,                    /* bitsize */
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_hi16_reloc,   /* special_function */
+        _bfd_mips_elf_hi16_reloc, /* special_function */
         "R_MIPS_HI16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -213,7 +205,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_lo16_reloc,   /* special_function */
+        _bfd_mips_elf_lo16_reloc, /* special_function */
         "R_MIPS_LO16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -258,7 +250,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_got16_reloc,  /* special_function */
+        _bfd_mips_elf_got16_reloc, /* special_function */
         "R_MIPS_GOT16",        /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -273,7 +265,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC16",         /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -288,7 +280,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL16",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -324,7 +316,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT5",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c0,            /* src_mask */
@@ -341,7 +333,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         6,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SHIFT6",       /* name */
         TRUE,                  /* partial_inplace */
         0x000007c4,            /* src_mask */
@@ -371,7 +363,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -386,7 +378,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_PAGE",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -401,7 +393,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_OFST",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -416,7 +408,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_HI16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -431,7 +423,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GOT_LO16",     /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -446,7 +438,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SUB",          /* name */
         TRUE,                  /* partial_inplace */
         MINUS_ONE,             /* src_mask */
@@ -466,7 +458,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHER",       /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -481,7 +473,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_HIGHEST",      /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -496,7 +488,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_HI16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -511,7 +503,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_CALL_LO16",    /* name */
         TRUE,                  /* partial_inplace */
         0x0000ffff,            /* src_mask */
@@ -526,7 +518,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_SCN_DISP",     /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -547,7 +539,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
         FALSE,                 /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_JALR",         /* name */
         FALSE,                 /* partial_inplace */
         0x00000000,            /* src_mask */
@@ -607,39 +599,6 @@ static reloc_howto_type elf_mips16_gprel_howto =
         0x07ff001f,            /* dst_mask */
         FALSE);                /* pcrel_offset */
 
-/* GNU extensions for embedded-pic.  */
-/* High 16 bits of symbol value, pc-relative.  */
-static reloc_howto_type elf_mips_gnu_rel_hi16 =
-  HOWTO (R_MIPS_GNU_REL_HI16,  /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_hi16_reloc,   /* special_function */
-        "R_MIPS_GNU_REL_HI16", /* name */
-        TRUE,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE);                 /* pcrel_offset */
-
-/* Low 16 bits of symbol value, pc-relative.  */
-static reloc_howto_type elf_mips_gnu_rel_lo16 =
-  HOWTO (R_MIPS_GNU_REL_LO16,  /* type */
-        0,                     /* rightshift */
-        2,                     /* size (0 = byte, 1 = short, 2 = long) */
-        16,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_dont, /* complain_on_overflow */
-        mips_elf_lo16_reloc,   /* special_function */
-        "R_MIPS_GNU_REL_LO16", /* name */
-        TRUE,                  /* partial_inplace */
-        0xffff,                /* src_mask */
-        0xffff,                /* dst_mask */
-        TRUE);                 /* pcrel_offset */
-
 /* 16 bit offset for pc-relative branches.  */
 static reloc_howto_type elf_mips_gnu_rel16_s2 =
   HOWTO (R_MIPS_GNU_REL16_S2,  /* type */
@@ -649,30 +608,17 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_GNU_REL16_S2", /* name */
         TRUE,                  /* partial_inplace */
         0xffff,                /* src_mask */
         0xffff,                /* dst_mask */
         TRUE);                 /* pcrel_offset */
 
-/* 64 bit pc-relative.  */
-static reloc_howto_type elf_mips_gnu_pcrel64 =
-  HOWTO (R_MIPS_PC64,          /* type */
-        0,                     /* rightshift */
-        4,                     /* size (0 = byte, 1 = short, 2 = long) */
-        64,                    /* bitsize */
-        TRUE,                  /* pc_relative */
-        0,                     /* bitpos */
-        complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
-        "R_MIPS_PC64",         /* name */
-        TRUE,                  /* partial_inplace */
-        MINUS_ONE,             /* src_mask */
-        MINUS_ONE,             /* dst_mask */
-        TRUE);                 /* pcrel_offset */
-
-/* 32 bit pc-relative.  */
+/* 32 bit pc-relative.  This was a GNU extension used by embedded-PIC.
+   It was co-opted by mips-linux for exception-handling data.  It is no
+   longer used, but should continue to be supported by the linker for
+   backward compatibility.  (GCC stopped using it in May, 2004.)  */
 static reloc_howto_type elf_mips_gnu_pcrel32 =
   HOWTO (R_MIPS_PC32,          /* type */
         0,                     /* rightshift */
@@ -681,7 +627,7 @@ static reloc_howto_type elf_mips_gnu_pcrel32 =
         TRUE,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        mips_elf_generic_reloc, /* special_function */
+        _bfd_mips_elf_generic_reloc, /* special_function */
         "R_MIPS_PC32",         /* name */
         TRUE,                  /* partial_inplace */
         0xffffffff,            /* src_mask */
@@ -720,260 +666,6 @@ static reloc_howto_type elf_mips_gnu_vtentry_howto =
         0,                     /* dst_mask */
         FALSE);                /* pcrel_offset */
 
-/* We use this instead of bfd_elf_generic_reloc because the latter
-   gets the handling of zero addends wrong. */
-static bfd_reloc_status_type
-mips_elf_generic_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                       asymbol *symbol, void *data ATTRIBUTE_UNUSED,
-                       asection *input_section, bfd *output_bfd,
-                       char **error_message ATTRIBUTE_UNUSED)
-{
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  /* Just go on, nothing to see here.  */
-  return bfd_reloc_continue;
-}
-
-/* Do a R_MIPS_HI16 relocation.  This has to be done in combination
-   with a R_MIPS_LO16 reloc, because there is a carry from the LO16 to
-   the HI16.  Here we just save the information we need; we do the
-   actual relocation when we see the LO16.
-
-   MIPS ELF requires that the LO16 immediately follow the HI16.  As a
-   GNU extension, for non-pc-relative relocations, we permit an
-   arbitrary number of HI16 relocs to be associated with a single LO16
-   reloc.  This extension permits gcc to output the HI and LO relocs
-   itself.
-
-   This cannot be done for PC-relative relocations because both the HI16
-   and LO16 parts of the relocations must be done relative to the LO16
-   part, and there can be carry to or borrow from the HI16 part.  */
-
-struct mips_hi16
-{
-  struct mips_hi16 *next;
-  bfd_byte *addr;
-  bfd_vma addend;
-};
-
-/* FIXME: This should not be a static variable.  */
-
-static struct mips_hi16 *mips_hi16_list;
-
-static bfd_reloc_status_type
-mips_elf_hi16_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
-                    asymbol *symbol, void *data, asection *input_section,
-                    bfd *output_bfd, char **error_message)
-{
-  bfd_reloc_status_type ret;
-  bfd_vma relocation;
-  struct mips_hi16 *n;
-
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  ret = bfd_reloc_ok;
-
-  if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-    {
-      bfd_boolean relocatable;
-      bfd_vma gp;
-
-      if (ret == bfd_reloc_undefined)
-       abort ();
-
-      if (output_bfd != NULL)
-       relocatable = TRUE;
-      else
-       {
-         relocatable = FALSE;
-         output_bfd = symbol->section->output_section->owner;
-       }
-
-      ret = mips_elf_final_gp (output_bfd, symbol, relocatable,
-                              error_message, &gp);
-      if (ret != bfd_reloc_ok)
-       return ret;
-
-      relocation = gp - reloc_entry->address;
-    }
-  else
-    {
-      if (bfd_is_und_section (symbol->section) && output_bfd == NULL)
-       ret = bfd_reloc_undefined;
-
-      if (bfd_is_com_section (symbol->section))
-       relocation = 0;
-      else
-       relocation = symbol->value;
-    }
-
-  relocation += symbol->section->output_section->vma;
-  relocation += symbol->section->output_offset;
-  relocation += reloc_entry->addend;
-
-  if (reloc_entry->address > input_section->_cooked_size)
-    return bfd_reloc_outofrange;
-
-  /* Save the information, and let LO16 do the actual relocation.  */
-  n = bfd_malloc (sizeof *n);
-  if (n == NULL)
-    return bfd_reloc_outofrange;
-  n->addr = (bfd_byte *) data + reloc_entry->address;
-  n->addend = relocation;
-  n->next = mips_hi16_list;
-  mips_hi16_list = n;
-
-  if (output_bfd != NULL)
-    reloc_entry->address += input_section->output_offset;
-
-  return ret;
-}
-
-/* Do a R_MIPS_LO16 relocation.  This is a straightforward 16 bit
-   inplace relocation; this function exists in order to do the
-   R_MIPS_HI16 relocation described above.  */
-
-static bfd_reloc_status_type
-mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                    void *data, asection *input_section, bfd *output_bfd,
-                    char **error_message)
-{
-  arelent gp_disp_relent;
-
-  if (mips_hi16_list != NULL)
-    {
-      struct mips_hi16 *l;
-
-      l = mips_hi16_list;
-      while (l != NULL)
-       {
-         unsigned long insn;
-         unsigned long val;
-         unsigned long vallo;
-         struct mips_hi16 *next;
-
-         if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-           {
-             gp_disp_relent = *reloc_entry;
-             reloc_entry = &gp_disp_relent;
-             reloc_entry->addend = l->addend;
-           }
-         else
-           {
-             /* Do the HI16 relocation.  Note that we actually don't need
-                to know anything about the LO16 itself, except where to
-                find the low 16 bits of the addend needed by the LO16.  */
-             insn = bfd_get_32 (abfd, l->addr);
-             vallo = bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address);
-             /* The low order 16 bits are always treated as a signed
-                value.  */
-             vallo = ((vallo & 0xffff) ^ 0x8000) - 0x8000;
-             val = ((insn & 0xffff) << 16) + vallo;
-             val += l->addend;
-
-             /* If PC-relative, we need to subtract out the address of the LO
-                half of the HI/LO.  (The actual relocation is relative
-                to that instruction.)  */
-             if (reloc_entry->howto->pc_relative)
-               val -= reloc_entry->address;
-
-             /* At this point, "val" has the value of the combined HI/LO
-                pair.  If the low order 16 bits (which will be used for
-                the LO16 insn) are negative, then we will need an
-                adjustment for the high order 16 bits.  */
-             val += 0x8000;
-             val = (val >> 16) & 0xffff;
-
-             insn &= ~ (bfd_vma) 0xffff;
-             insn |= val;
-             bfd_put_32 (abfd, insn, l->addr);
-           }
-
-         next = l->next;
-         free (l);
-         l = next;
-       }
-
-      mips_hi16_list = NULL;
-    }
-  else if (strcmp (bfd_asymbol_name (symbol), "_gp_disp") == 0)
-    {
-      bfd_reloc_status_type ret;
-      bfd_vma gp, relocation;
-
-      /* FIXME: Does this case ever occur?  */
-
-      ret = mips_elf_final_gp (output_bfd, symbol, TRUE, error_message, &gp);
-      if (ret != bfd_reloc_ok)
-       return ret;
-
-      relocation = gp - reloc_entry->address;
-      relocation += symbol->section->output_section->vma;
-      relocation += symbol->section->output_offset;
-      relocation += reloc_entry->addend;
-
-      if (reloc_entry->address > input_section->_cooked_size)
-       return bfd_reloc_outofrange;
-
-      gp_disp_relent = *reloc_entry;
-      reloc_entry = &gp_disp_relent;
-      reloc_entry->addend = relocation - 4;
-    }
-
-  /* Now do the LO16 reloc in the usual way.  */
-  return mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                                input_section, output_bfd, error_message);
-}
-
-/* Do a R_MIPS_GOT16 reloc.  This is a reloc against the global offset
-   table used for PIC code.  If the symbol is an external symbol, the
-   instruction is modified to contain the offset of the appropriate
-   entry in the global offset table.  If the symbol is a section
-   symbol, the next reloc is a R_MIPS_LO16 reloc.  The two 16 bit
-   addends are combined to form the real addend against the section
-   symbol; the GOT16 is modified to contain the offset of an entry in
-   the global offset table, and the LO16 is modified to offset it
-   appropriately.  Thus an offset larger than 16 bits requires a
-   modified value in the global offset table.
-
-   This implementation suffices for the assembler, but the linker does
-   not yet know how to create global offset tables.  */
-
-static bfd_reloc_status_type
-mips_elf_got16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                     void *data, asection *input_section, bfd *output_bfd,
-                     char **error_message)
-{
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
-      && (symbol->flags & BSF_SECTION_SYM) == 0
-      && (symbol->flags & BSF_LOCAL) != 0)
-    {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
-    }
-
-  return mips_elf_hi16_reloc (abfd, reloc_entry, symbol, data,
-                             input_section, output_bfd, error_message);
-}
-
 /* Set the GP value for OUTPUT_BFD.  Returns FALSE if this is a
    dangerous relocation.  */
 
@@ -1078,14 +770,15 @@ _bfd_mips_elf32_gprel16_reloc (bfd *abfd, arelent *reloc_entry,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
-  if (output_bfd != NULL
+  /* R_MIPS_LITERAL relocations are defined for local symbols only.  */
+  if (reloc_entry->howto->type == R_MIPS_LITERAL
+      && output_bfd != NULL
       && (symbol->flags & BSF_SECTION_SYM) == 0
       && (symbol->flags & BSF_LOCAL) != 0)
     {
-      reloc_entry->address += input_section->output_offset;
-      return bfd_reloc_ok;
+      *error_message = (char *)
+       _("literal relocation occurs for an external symbol");
+      return bfd_reloc_outofrange;
     }
 
   if (output_bfd != NULL)
@@ -1118,8 +811,7 @@ mips_elf_gprel32_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   bfd_reloc_status_type ret;
   bfd_vma gp;
 
-  /* If we're relocating, and this is an external symbol, we don't want
-     to change anything.  */
+  /* R_MIPS_GPREL32 relocations are defined for local symbols only.  */
   if (output_bfd != NULL
       && (symbol->flags & BSF_SECTION_SYM) == 0
       && (symbol->flags & BSF_LOCAL) != 0)
@@ -1162,7 +854,7 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
   relocation += symbol->section->output_section->vma;
   relocation += symbol->section->output_offset;
 
-  if (reloc_entry->address > input_section->_cooked_size)
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   /* Set val to the offset into the section or symbol.  */
@@ -1194,20 +886,16 @@ gprel32_with_gp (bfd *abfd, asymbol *symbol, arelent *reloc_entry,
    sign extension.  */
 
 static bfd_reloc_status_type
-mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
-                   void *data, asection *input_section, bfd *output_bfd,
-                   char **error_message)
+mips32_64bit_reloc (bfd *abfd, arelent *reloc_entry,
+                   asymbol *symbol ATTRIBUTE_UNUSED,
+                   void *data, asection *input_section,
+                   bfd *output_bfd, char **error_message)
 {
   bfd_reloc_status_type r;
   arelent reloc32;
   unsigned long val;
   bfd_size_type addr;
 
-  r = mips_elf_generic_reloc (abfd, reloc_entry, symbol, data,
-                             input_section, output_bfd, error_message);
-  if (r != bfd_reloc_continue)
-    return r;
-
   /* Do a normal 32 bit relocation on the lower 32 bits.  */
   reloc32 = *reloc_entry;
   if (bfd_big_endian (abfd))
@@ -1298,7 +986,7 @@ mips16_gprel_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
   if (ret != bfd_reloc_ok)
     return ret;
 
-  if (reloc_entry->address > input_section->_cooked_size)
+  if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
     return bfd_reloc_outofrange;
 
   if (bfd_is_com_section (symbol->section))
@@ -1421,14 +1109,8 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
       return &elf_mips_gnu_vtinherit_howto;
     case BFD_RELOC_VTABLE_ENTRY:
       return &elf_mips_gnu_vtentry_howto;
-    case BFD_RELOC_PCREL_HI16_S:
-      return &elf_mips_gnu_rel_hi16;
-    case BFD_RELOC_PCREL_LO16:
-      return &elf_mips_gnu_rel_lo16;
     case BFD_RELOC_16_PCREL_S2:
       return &elf_mips_gnu_rel16_s2;
-    case BFD_RELOC_64_PCREL:
-      return &elf_mips_gnu_pcrel64;
     case BFD_RELOC_32_PCREL:
       return &elf_mips_gnu_pcrel32;
     }
@@ -1450,14 +1132,8 @@ mips_elf32_rtype_to_howto (unsigned int r_type,
       return &elf_mips_gnu_vtinherit_howto;
     case R_MIPS_GNU_VTENTRY:
       return &elf_mips_gnu_vtentry_howto;
-    case R_MIPS_GNU_REL_HI16:
-      return &elf_mips_gnu_rel_hi16;
-    case R_MIPS_GNU_REL_LO16:
-      return &elf_mips_gnu_rel_lo16;
     case R_MIPS_GNU_REL16_S2:
       return &elf_mips_gnu_rel16_s2;
-    case R_MIPS_PC64:
-      return &elf_mips_gnu_pcrel64;
     case R_MIPS_PC32:
       return &elf_mips_gnu_pcrel32;
     default:
@@ -1554,7 +1230,7 @@ static bfd_boolean
 elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 {
   int offset;
-  unsigned int raw_size;
+  unsigned int size;
 
   switch (note->descsz)
     {
@@ -1570,14 +1246,14 @@ elf32_mips_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
        /* pr_reg */
        offset = 72;
-       raw_size = 180;
+       size = 180;
 
        break;
     }
 
   /* Make a ".reg/999" section.  */
   return _bfd_elfcore_make_pseudosection (abfd, ".reg",
-                                         raw_size, note->descpos + offset);
+                                         size, note->descpos + offset);
 }
 
 static bfd_boolean
@@ -1622,139 +1298,6 @@ elf32_mips_irix_compat (bfd *abfd)
     return ict_none;
 }
 \f
-/* Given a data section and an in-memory embedded reloc section, store
-   relocation information into the embedded reloc section which can be
-   used at runtime to relocate the data section.  This is called by the
-   linker when the --embedded-relocs switch is used.  This is called
-   after the add_symbols entry point has been called for all the
-   objects, and before the final_link entry point is called.  */
-
-bfd_boolean
-bfd_mips_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info,
-                                      asection *datasec, asection *relsec,
-                                      char **errmsg)
-{
-  Elf_Internal_Shdr *symtab_hdr;
-  Elf_Internal_Sym *isymbuf = NULL;
-  Elf_Internal_Rela *internal_relocs = NULL;
-  Elf_Internal_Rela *irel, *irelend;
-  bfd_byte *p;
-
-  BFD_ASSERT (! info->relocatable);
-
-  *errmsg = NULL;
-
-  if (datasec->reloc_count == 0)
-    return TRUE;
-
-  /* Read this BFD's symbols if we haven't done so already, or get the cached
-     copy if it exists.  */
-  symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
-  if (symtab_hdr->sh_info != 0)
-    {
-      isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
-      if (isymbuf == NULL)
-       isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
-                                       symtab_hdr->sh_info, 0,
-                                       NULL, NULL, NULL);
-      if (isymbuf == NULL)
-       goto error_return;
-    }
-
-  /* Get a copy of the native relocations.  */
-  internal_relocs = _bfd_elf_link_read_relocs (abfd, datasec, NULL, NULL,
-                                              info->keep_memory);
-  if (internal_relocs == NULL)
-    goto error_return;
-
-  relsec->contents = bfd_alloc (abfd, datasec->reloc_count * 12);
-  if (relsec->contents == NULL)
-    goto error_return;
-
-  p = relsec->contents;
-
-  irelend = internal_relocs + datasec->reloc_count;
-
-  for (irel = internal_relocs; irel < irelend; irel++, p += 12)
-    {
-      asection *targetsec;
-
-      /* We are going to write a four byte longword into the runtime
-        reloc section.  The longword will be the address in the data
-        section which must be relocated.  It is followed by the name
-        of the target section NUL-padded or truncated to 8
-        characters.  */
-
-      /* We can only relocate absolute longword relocs at run time.  */
-      if ((ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_32) &&
-         (ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_64))
-       {
-         *errmsg = _("unsupported reloc type");
-         bfd_set_error (bfd_error_bad_value);
-         goto error_return;
-       }
-      /* Get the target section referred to by the reloc.  */
-      if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
-       {
-          Elf_Internal_Sym *isym;
-
-          /* A local symbol.  */
-         isym = isymbuf + ELF32_R_SYM (irel->r_info);
-         targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
-       }
-      else
-       {
-         unsigned long indx;
-         struct elf_link_hash_entry *h;
-
-         /* An external symbol.  */
-         indx = ELF32_R_SYM (irel->r_info);
-         h = elf_sym_hashes (abfd)[indx];
-         targetsec = NULL;
-         /*
-            For some reason, in certain programs, the symbol will
-            not be in the hash table.  It seems to happen when you
-            declare a static table of pointers to const external structures.
-            In this case, the relocs are relative to data, not
-            text, so just treating it like an undefined link
-            should be sufficient.  */
-         BFD_ASSERT(h != NULL);
-         if (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-           targetsec = h->root.u.def.section;
-       }
-
-
-      /*
-         Set the low bit of the relocation offset if it's a MIPS64 reloc.
-         Relocations will always be on (at least) 32-bit boundaries.  */
-
-      bfd_put_32 (abfd, ((irel->r_offset + datasec->output_offset) +
-                 ((ELF32_R_TYPE (irel->r_info) == (int) R_MIPS_64) ? 1 : 0)),
-                 p);
-      memset (p + 4, 0, 8);
-      if (targetsec != NULL)
-       strncpy (p + 4, targetsec->output_section->name, 8);
-    }
-
-  if (internal_relocs != NULL
-      && elf_section_data (datasec)->relocs != internal_relocs)
-    free (internal_relocs);
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
-    free (isymbuf);
-  return TRUE;
-
- error_return:
-  if (internal_relocs != NULL
-      && elf_section_data (datasec)->relocs != internal_relocs)
-    free (internal_relocs);
-  if (isymbuf != NULL
-      && symtab_hdr->contents != (unsigned char *) isymbuf)
-    free (isymbuf);
-  return FALSE;
-}
-\f
 /* ECOFF swapping routines.  These are used when dealing with the
    .mdebug section, which is in the ECOFF debugging format.  */
 static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
@@ -1800,10 +1343,6 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define ELF_ARCH                       bfd_arch_mips
 #define ELF_MACHINE_CODE               EM_MIPS
 
-/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
-   a value of 0x1000, and we are compatible.  */
-#define ELF_MAXPAGESIZE                        0x1000
-
 #define elf_backend_collect            TRUE
 #define elf_backend_type_change_ok     TRUE
 #define elf_backend_can_gc_sections    TRUE
@@ -1881,20 +1420,29 @@ static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
 #define TARGET_BIG_SYM                 bfd_elf32_bigmips_vec
 #define TARGET_BIG_NAME                        "elf32-bigmips"
 
+/* The SVR4 MIPS ABI says that this should be 0x10000, but Irix 5 uses
+   a value of 0x1000, and we are compatible.  */
+#define ELF_MAXPAGESIZE                        0x1000
+
 #include "elf32-target.h"
 
 /* Support for traditional mips targets.  */
-#define INCLUDED_TARGET_FILE            /* More a type of flag.  */
-
 #undef TARGET_LITTLE_SYM
 #undef TARGET_LITTLE_NAME
 #undef TARGET_BIG_SYM
 #undef TARGET_BIG_NAME
 
+#undef ELF_MAXPAGESIZE
+
 #define TARGET_LITTLE_SYM               bfd_elf32_tradlittlemips_vec
 #define TARGET_LITTLE_NAME              "elf32-tradlittlemips"
 #define TARGET_BIG_SYM                  bfd_elf32_tradbigmips_vec
 #define TARGET_BIG_NAME                 "elf32-tradbigmips"
 
+/* 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 elf32_bed                      elf32_tradbed
+
 /* Include the target file again for this target.  */
 #include "elf32-target.h"
This page took 0.034657 seconds and 4 git commands to generate.