correct ft32 reloc range test
[deliverable/binutils-gdb.git] / bfd / pe-mips.c
index a6cc489c0f02ee47f79c6b362795accfe38ea62c..1a617a1583d66f1e8a31e75714935d4557971f78 100644 (file)
@@ -1,13 +1,12 @@
 /* BFD back-end for MIPS PE COFF files.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+   Copyright (C) 1990-2018 Free Software Foundation, Inc.
    Modified from coff-i386.c by DJ Delorie, dj@cygnus.com
 
    This file is part of BFD, the Binary File Descriptor library.
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
 
    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+   MA 02110-1301, USA.  */
 
 #define COFF_WITH_PE
+/* pei-mips.c may have defined this to default off (0) before
+  including this file, so don't redefine if that's the case.
+  Otherwise we're generating objects, not executable images,
+  so we want to define it to default on.  */
+#ifndef COFF_LONG_SECTION_NAMES
 #define COFF_LONG_SECTION_NAMES
+#endif /* COFF_LONG_SECTION_NAMES */
 #define PCRELOFFSET TRUE
 
-#include "bfd.h"
 #include "sysdep.h"
+#include "bfd.h"
 #include "libbfd.h"
 #include "coff/mipspe.h"
 #include "coff/internal.h"
@@ -89,44 +95,44 @@ coff_mips_reloc (bfd *abfd,
 #define DOIT(x) \
   x = ((x & ~howto->dst_mask) | (((x & howto->src_mask) + (diff >> howto->rightshift)) & howto->dst_mask))
 
-    if (diff != 0)
-      {
-       reloc_howto_type *howto = reloc_entry->howto;
-       unsigned char *addr = (unsigned char *) data + reloc_entry->address;
+  if (diff != 0)
+    {
+      reloc_howto_type *howto = reloc_entry->howto;
+      unsigned char *addr = (unsigned char *) data + reloc_entry->address;
 
-       switch (howto->size)
+      switch (howto->size)
+       {
+       case 0:
          {
-         case 0:
-           {
-             char x = bfd_get_8 (abfd, addr);
-
-             DOIT (x);
-             bfd_put_8 (abfd, x, addr);
-           }
-           break;
+           char x = bfd_get_8 (abfd, addr);
 
-         case 1:
-           {
-             short x = bfd_get_16 (abfd, addr);
+           DOIT (x);
+           bfd_put_8 (abfd, x, addr);
+         }
+         break;
 
-             DOIT (x);
-             bfd_put_16 (abfd, (bfd_vma) x, addr);
-           }
-           break;
+       case 1:
+         {
+           short x = bfd_get_16 (abfd, addr);
 
-         case 2:
-           {
-             long x = bfd_get_32 (abfd, addr);
+           DOIT (x);
+           bfd_put_16 (abfd, (bfd_vma) x, addr);
+         }
+         break;
 
-             DOIT (x);
-             bfd_put_32 (abfd, (bfd_vma) x, addr);
-           }
-           break;
+       case 2:
+         {
+           long x = bfd_get_32 (abfd, addr);
 
-         default:
-           abort ();
+           DOIT (x);
+           bfd_put_32 (abfd, (bfd_vma) x, addr);
          }
-      }
+         break;
+
+       default:
+         abort ();
+       }
+    }
 
   /* Now let bfd_perform_relocation finish everything up.  */
   return bfd_reloc_continue;
@@ -204,7 +210,7 @@ static reloc_howto_type howto_table[] =
         FALSE,                 /* PC_relative.  */
         0,                     /* Bitpos. */
         complain_overflow_dont, /* Complain_on_overflow. */
-                               /* This needs complex overflow
+                               /* This needs complex overflow
                                   detection, because the upper four
                                   bits must match the PC.  */
         coff_mips_reloc,       /* Special_function. */
@@ -303,46 +309,51 @@ static reloc_howto_type howto_table[] =
   EMPTY_HOWTO (31),
   EMPTY_HOWTO (32),
   EMPTY_HOWTO (33),
-  HOWTO (MIPS_R_RVA,            /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        32,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
-        0,                     /* Bitpos. */
+  HOWTO (MIPS_R_RVA,           /* Type.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        FALSE,                 /* PC_relative.  */
+        0,                     /* Bitpos. */
         complain_overflow_bitfield, /* Complain_on_overflow. */
-        coff_mips_reloc,       /* Special_function. */
-        "rva32",               /* Name. */
-        TRUE,                  /* Partial_inplace. */
-        0xffffffff,            /* Src_mask. */
-        0xffffffff,            /* Dst_mask. */
-        FALSE),                /* Pcrel_offset. */
+        coff_mips_reloc,       /* Special_function. */
+        "rva32",               /* Name. */
+        TRUE,                  /* Partial_inplace. */
+        0xffffffff,            /* Src_mask. */
+        0xffffffff,            /* Dst_mask. */
+        FALSE),                /* Pcrel_offset. */
   EMPTY_HOWTO (35),
   EMPTY_HOWTO (36),
-  HOWTO (MIPS_R_PAIR,           /* Type.  */
-        0,                     /* Rightshift.  */
-        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
-        32,                    /* Bitsize.  */
-        FALSE,                 /* PC_relative.  */
-        0,                     /* Bitpos. */
+  HOWTO (MIPS_R_PAIR,          /* Type.  */
+        0,                     /* Rightshift.  */
+        2,                     /* Size (0 = byte, 1 = short, 2 = long).  */
+        32,                    /* Bitsize.  */
+        FALSE,                 /* PC_relative.  */
+        0,                     /* Bitpos. */
         complain_overflow_bitfield, /* Complain_on_overflow. */
-        coff_mips_reloc,       /* Special_function. */
-        "PAIR",                /* Name. */
-        TRUE,                  /* Partial_inplace. */
-        0xffffffff,            /* Src_mask. */
-        0xffffffff,            /* Dst_mask. */
-        FALSE),                /* Pcrel_offset. */
+        coff_mips_reloc,       /* Special_function. */
+        "PAIR",                /* Name. */
+        TRUE,                  /* Partial_inplace. */
+        0xffffffff,            /* Src_mask. */
+        0xffffffff,            /* Dst_mask. */
+        FALSE),                /* Pcrel_offset. */
 };
 
+#define NUM_HOWTOS (sizeof (howto_table) / sizeof (howto_table[0]))
+
 /* Turn a howto into a reloc nunmber.  */
 
 #define SELECT_RELOC(x, howto) { x.r_type = howto->type; }
-#define BADMAG(x)              MIPSBADMAG (x)
+#define BADMAG(x)             MIPSBADMAG (x)
 
 /* Customize coffcode.h.  */
 #define MIPS 1
 
-#define RTYPE2HOWTO(cache_ptr, dst) \
-           (cache_ptr)->howto = howto_table + (dst)->r_type;
+#define RTYPE2HOWTO(cache_ptr, dst)                            \
+  ((cache_ptr)->howto =                                                \
+   ((dst)->r_type < NUM_HOWTOS                                 \
+    ? howto_table + (dst)->r_type                              \
+    : NULL))
 
 /* Compute the addend of a reloc.  If the reloc is to a common symbol,
    the object file contains the value of the common symbol.  By the
@@ -362,9 +373,9 @@ static reloc_howto_type howto_table[] =
     coff_symbol_type *coffsym = NULL;                          \
     if (ptr && bfd_asymbol_bfd (ptr) != abfd)                  \
       coffsym = (obj_symbols (abfd)                            \
-                + (cache_ptr->sym_ptr_ptr - symbols));         \
+                + (cache_ptr->sym_ptr_ptr - symbols));         \
     else if (ptr)                                              \
-      coffsym = coff_symbol_from (abfd, ptr);                  \
+      coffsym = coff_symbol_from (ptr);                                \
     if (coffsym != NULL                                                \
        && coffsym->native->u.syment.n_scnum == 0)              \
       cache_ptr->addend = - coffsym->native->u.syment.n_value; \
@@ -373,7 +384,8 @@ static reloc_howto_type howto_table[] =
       cache_ptr->addend = - (ptr->section->vma + ptr->value);  \
     else                                                       \
       cache_ptr->addend = 0;                                   \
-    if (ptr && howto_table[reloc.r_type].pc_relative)          \
+    if (ptr && reloc.r_type < NUM_HOWTOS                       \
+       && howto_table[reloc.r_type].pc_relative)               \
       cache_ptr->addend += asect->vma;                         \
   }
 
@@ -435,11 +447,11 @@ coff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
       *addendp -= 4;
 
       /* If the symbol is defined, then the generic code is going to
-         add back the symbol value in order to cancel out an
-         adjustment it made to the addend.  However, we set the addend
-         to 0 at the start of this function.  We need to adjust here,
-         to avoid the adjustment the generic code will make.  FIXME:
-         This is getting a bit hackish.  */
+        add back the symbol value in order to cancel out an
+        adjustment it made to the addend.  However, we set the addend
+        to 0 at the start of this function.  We need to adjust here,
+        to avoid the adjustment the generic code will make.  FIXME:
+        This is getting a bit hackish.  */
       if (sym != NULL && sym->n_scnum != 0)
        *addendp -= sym->n_value;
     }
@@ -451,8 +463,9 @@ coff_mips_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
   return howto;
 }
 
-#define coff_rtype_to_howto         coff_mips_rtype_to_howto
+#define coff_rtype_to_howto        coff_mips_rtype_to_howto
 #define coff_bfd_reloc_type_lookup  coff_mips_reloc_type_lookup
+#define coff_bfd_reloc_name_lookup coff_mips_reloc_name_lookup
 
 /* Get the howto structure for a generic reloc type.  */
 
@@ -496,6 +509,20 @@ coff_mips_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
   return & howto_table [mips_type];
 }
 
+static reloc_howto_type *
+coff_mips_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
+                            const char *r_name)
+{
+  unsigned int i;
+
+  for (i = 0; i < NUM_HOWTOS; i++)
+    if (howto_table[i].name != NULL
+       && strcasecmp (howto_table[i].name, r_name) == 0)
+      return &howto_table[i];
+
+  return NULL;
+}
+
 static void
 mips_swap_reloc_in (bfd * abfd, void * src, void * dst)
 {
@@ -527,7 +554,6 @@ mips_swap_reloc_in (bfd * abfd, void * src, void * dst)
 static unsigned int
 mips_swap_reloc_out (bfd * abfd, void * src, void * dst)
 {
-  static int prev_offset = 1;
   static bfd_vma prev_addr = 0;
   struct internal_reloc *reloc_src = (struct internal_reloc *)src;
   struct external_reloc *reloc_dst = (struct external_reloc *)dst;
@@ -536,7 +562,6 @@ mips_swap_reloc_out (bfd * abfd, void * src, void * dst)
     {
     case MIPS_R_REFHI:
       prev_addr = reloc_src->r_vaddr;
-      prev_offset = reloc_src->r_offset;
       break;
     case MIPS_R_REFLO:
       if (reloc_src->r_vaddr == prev_addr)
@@ -574,18 +599,14 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
                               struct internal_syment *syms,
                               asection **sections)
 {
-  bfd_vma gp;
-  bfd_boolean gp_undefined;
-  size_t adjust;
   struct internal_reloc *rel;
   struct internal_reloc *rel_end;
   unsigned int i;
-  bfd_boolean got_lo;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
-      (*_bfd_error_handler)
-       (_("%B: `ld -r' not supported with PE MIPS objects\n"), input_bfd);
+      _bfd_error_handler
+       (_("%pB: `ld -r' not supported with PE MIPS objects"), input_bfd);
       bfd_set_error (bfd_error_bad_value);
       return FALSE;
     }
@@ -593,10 +614,6 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
   BFD_ASSERT (input_bfd->xvec->byteorder
              == output_bfd->xvec->byteorder);
 
-  gp = _bfd_get_gp_value (output_bfd);
-  gp_undefined = (gp == 0) ? TRUE : FALSE;
-  got_lo = FALSE;
-  adjust = 0;
   rel = relocs;
   rel_end = rel + input_section->reloc_count;
 
@@ -624,9 +641,9 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
        }
 
       /* COFF treats common symbols in one of two ways.  Either the
-         size of the symbol is included in the section contents, or it
-         is not.  We assume that the size is not included, and force
-         the rtype_to_howto function to adjust the addend as needed.  */
+        size of the symbol is included in the section contents, or it
+        is not.  We assume that the size is not included, and force
+        the rtype_to_howto function to adjust the addend as needed.  */
 
       if (sym != NULL && sym->n_scnum != 0)
        addend = - sym->n_value;
@@ -639,12 +656,12 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
        return FALSE;
 
       /* If we are doing a relocatable link, then we can just ignore
-         a PC relative reloc that is pcrel_offset.  It will already
-         have the correct value.  If this is not a relocatable link,
-         then we should ignore the symbol value.  */
+        a PC relative reloc that is pcrel_offset.  It will already
+        have the correct value.  If this is not a relocatable link,
+        then we should ignore the symbol value.  */
       if (howto->pc_relative && howto->pcrel_offset)
        {
-         if (info->relocatable)
+         if (bfd_link_relocatable (info))
            continue;
          if (sym != NULL && sym->n_scnum != 0)
            addend += sym->n_value;
@@ -664,7 +681,7 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
          else
            {
              sec = sections[symndx];
-              val = (sec->output_section->vma
+             val = (sec->output_section->vma
                     + sec->output_offset
                     + sym->n_value);
              if (! obj_pe (input_bfd))
@@ -684,13 +701,10 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
                     + sec->output_offset);
              }
 
-         else if (! info->relocatable)
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd, input_section,
-                     rel->r_vaddr - input_section->vma, TRUE)))
-               return FALSE;
-           }
+         else if (! bfd_link_relocatable (info))
+           (*info->callbacks->undefined_symbol)
+             (info, h->root.root.string, input_bfd, input_section,
+              rel->r_vaddr - input_section->vma, TRUE);
        }
 
       src = rel->r_vaddr + input_section->output_section->vma
@@ -701,9 +715,11 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
           mem = pointer to memory we're fixing up
           val = VMA of what we need to refer to.  */
 
-#define UI(x) (*_bfd_error_handler) (_("%B: unimplemented %s\n"), \
-                                    input_bfd, x); \
-             bfd_set_error (bfd_error_bad_value);
+#define UI(x)                                                 \
+      /* xgettext:c-format */                                 \
+       _bfd_error_handler (_("%pB: unimplemented %s"),        \
+                           input_bfd, x);                     \
+       bfd_set_error (bfd_error_bad_value);
 
       switch (rel->r_type)
        {
@@ -727,7 +743,7 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
          targ = val + (tmp & 0x03ffffff) * 4;
          if ((src & 0xf0000000) != (targ & 0xf0000000))
            {
-             (*_bfd_error_handler) (_("%B: jump too far away\n"), input_bfd);
+             _bfd_error_handler (_("%pB: jump too far away"), input_bfd);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -753,8 +769,8 @@ coff_pe_mips_relocate_section (bfd *output_bfd,
              targ = val + low + ((tmp & 0xffff) << 16);
              break;
            default:
-             (*_bfd_error_handler) (_("%B: bad pair/reflo after refhi\n"),
-                                    input_bfd);
+             _bfd_error_handler (_("%pB: bad pair/reflo after refhi"),
+                                 input_bfd);
              bfd_set_error (bfd_error_bad_value);
              return FALSE;
            }
@@ -833,13 +849,17 @@ coff_mips_is_local_label_name (bfd *abfd, const char *name)
 
 #define COFF_NO_HACK_SCNHDR_SIZE
 
+#ifndef bfd_pe_print_pdata
+#define bfd_pe_print_pdata     NULL
+#endif
+
 #include "coffcode.h"
 
 const bfd_target
 #ifdef TARGET_SYM
   TARGET_SYM =
 #else
-  mipslpe_vec =
+  mips_pe_le_vec =
 #endif
 {
 #ifdef TARGET_NAME
@@ -851,9 +871,9 @@ const bfd_target
   BFD_ENDIAN_LITTLE,           /* Data byte order is little.  */
   BFD_ENDIAN_LITTLE,           /* Header byte order is little.  */
 
-  (HAS_RELOC | EXEC_P |                /* Object flags.  */
-   HAS_LINENO | HAS_DEBUG |
-   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
+  (HAS_RELOC | EXEC_P          /* Object flags.  */
+   | HAS_LINENO | HAS_DEBUG
+   HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
 
 #ifndef COFF_WITH_PE
   (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC /* Section flags.  */
@@ -871,6 +891,7 @@ const bfd_target
 #endif
   '/',                         /* AR_pad_char.  */
   15,                          /* AR_max_namelen.  */
+  0,                           /* match priority.  */
 
   bfd_getl64, bfd_getl_signed_64, bfd_putl64,
      bfd_getl32, bfd_getl_signed_32, bfd_putl32,
@@ -880,12 +901,24 @@ const bfd_target
      bfd_getl16, bfd_getl_signed_16, bfd_putl16, /* Headers.  */
 
   /* Note that we allow an object file to be treated as a core file as well.  */
-  {_bfd_dummy_target, coff_object_p, /* bfd_check_format.  */
-   bfd_generic_archive_p, coff_object_p},
-  {bfd_false, coff_mkobject, _bfd_generic_mkarchive, /* bfd_set_format.  */
-   bfd_false},
-  {bfd_false, coff_write_object_contents, /* bfd_write_contents.  */
-   _bfd_write_archive_contents, bfd_false},
+  {                            /* bfd_check_format.  */
+    _bfd_dummy_target,
+    coff_object_p,
+    bfd_generic_archive_p,
+    coff_object_p
+  },
+  {                            /* bfd_set_format.  */
+    _bfd_bool_bfd_false_error,
+    coff_mkobject,
+    _bfd_generic_mkarchive,
+    _bfd_bool_bfd_false_error
+  },
+  {                            /* bfd_write_contents.  */
+    _bfd_bool_bfd_false_error,
+    coff_write_object_contents,
+    _bfd_write_archive_contents,
+    _bfd_bool_bfd_false_error
+  },
 
   BFD_JUMP_TABLE_GENERIC (coff),
   BFD_JUMP_TABLE_COPY (coff),
This page took 0.029398 seconds and 4 git commands to generate.