Don't decode powerpc insns with invalid fields
[deliverable/binutils-gdb.git] / bfd / coff-ppc.c
index 19ae3e69374654a9d67633f1b5e7069d4dd7f395..7cd29acdd786e975406577297681f43efbdfba22 100644 (file)
@@ -1,7 +1,5 @@
 /* BFD back-end for PowerPC Microsoft Portable Executable files.
-   Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
-   2012  Free Software Foundation, Inc.
+   Copyright (C) 1990-2017 Free Software Foundation, Inc.
 
    Original version pieced together by Kim Knuttila (krk@cygnus.com)
 
@@ -81,9 +79,10 @@ extern void dump_toc (void *);
 #define HASH_CHECK_DCL char eye_catcher[8];
 #define HASH_CHECK_INIT(ret)      strcpy(ret->eye_catcher, EYE)
 #define HASH_CHECK(addr) \
- if (strcmp(addr->eye_catcher, EYE) != 0) \
+ if (strcmp (addr->eye_catcher, EYE) != 0) \
   { \
     fprintf (stderr,\
+    /* xgettext: c-format */ \
     _("File %s, line %d, Hash check failure, bad eye %8s\n"), \
     __FILE__, __LINE__, addr->eye_catcher); \
     abort (); \
@@ -301,13 +300,13 @@ ppc_coff_link_hash_table_create (bfd *abfd)
 
 static bfd_reloc_status_type ppc_refhi_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type ppc_pair_reloc 
+static bfd_reloc_status_type ppc_pair_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc_toc16_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc_section_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
-static bfd_reloc_status_type ppc_secrel_reloc 
+static bfd_reloc_status_type ppc_secrel_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 static bfd_reloc_status_type ppc_imglue_reloc
   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
@@ -316,7 +315,7 @@ static bfd_reloc_status_type ppc_imglue_reloc
    get us started, so those I'll make sure work. Those marked FIXME are either
    completely unverified or have a specific unknown marked in the comment.  */
 
-/* Relocation entries for Windows/NT on PowerPC.                             
+/* Relocation entries for Windows/NT on PowerPC.
 
    From the document "" we find the following listed as used relocs:
 
@@ -846,7 +845,7 @@ ppc_record_toc_entry (bfd *abfd,
          /* The size must fit in a 16-bit displacement.  */
          if (global_toc_size > 65535)
            {
-             (*_bfd_error_handler) (_("TOC overflow"));
+             _bfd_error_handler (_("TOC overflow"));
              bfd_set_error (bfd_error_file_too_big);
              return FALSE;
            }
@@ -864,7 +863,7 @@ ppc_record_toc_entry (bfd *abfd,
          /* The size must fit in a 16-bit displacement.  */
          if (global_toc_size >= 65535)
            {
-             (*_bfd_error_handler) (_("TOC overflow"));
+             _bfd_error_handler (_("TOC overflow"));
              bfd_set_error (bfd_error_file_too_big);
              return FALSE;
            }
@@ -949,7 +948,7 @@ coff_ppc_relocate_section (bfd *output_bfd,
   /* If we are performing a relocatable link, we don't need to do a
      thing.  The caller will take care of adjusting the reloc
      addresses and symbol indices.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   rel = relocs;
@@ -1028,12 +1027,9 @@ coff_ppc_relocate_section (bfd *output_bfd,
                     + sec->output_offset);
            }
          else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.root.string, input_bfd, input_section,
-                     rel->r_vaddr - input_section->vma, TRUE)))
-               return FALSE;
-           }
+           (*info->callbacks->undefined_symbol)
+             (info, h->root.root.root.string, input_bfd, input_section,
+              rel->r_vaddr - input_section->vma, TRUE);
        }
 
       rstat = bfd_reloc_ok;
@@ -1042,7 +1038,8 @@ coff_ppc_relocate_section (bfd *output_bfd,
       switch (r_type)
        {
        default:
-         (*_bfd_error_handler)
+         _bfd_error_handler
+           /* xgettext: c-format */
            (_("%B: unsupported relocation type 0x%02x"), input_bfd, r_type);
          bfd_set_error (bfd_error_bad_value);
          return FALSE;
@@ -1075,10 +1072,11 @@ coff_ppc_relocate_section (bfd *output_bfd,
              {
                /* It is a file local symbol.  */
                int *local_toc_table;
-               const char *name;
+               char name[SYMNMLEN + 1];
 
                sym = syms + symndx;
-               name = sym->_n._n_name;
+               strncpy (name, sym->_n._n_name, SYMNMLEN);
+               name[SYMNMLEN] = '\0';
 
                local_toc_table = obj_coff_local_toc_table(input_bfd);
                our_toc_offset = local_toc_table[symndx];
@@ -1131,8 +1129,10 @@ coff_ppc_relocate_section (bfd *output_bfd,
                    /* The size must still fit in a 16-bit displacement.  */
                    if ((bfd_vma) our_toc_offset >= 65535)
                      {
-                       (*_bfd_error_handler)
-                         (_("%B: Relocation for %s of %lx exceeds Toc size limit"),
+                       _bfd_error_handler
+                         /* xgettext: c-format */
+                         (_("%B: Relocation for %s of %lx exceeds "
+                            "Toc size limit"),
                           input_bfd, name,
                           (unsigned long) our_toc_offset);
                        bfd_set_error (bfd_error_bad_value);
@@ -1184,7 +1184,8 @@ coff_ppc_relocate_section (bfd *output_bfd,
            if ((r_flags & IMAGE_REL_PPC_TOCDEFN) != IMAGE_REL_PPC_TOCDEFN
                && (bfd_vma) our_toc_offset > toc_section->size)
              {
-               (*_bfd_error_handler)
+               _bfd_error_handler
+                 /* xgettext: c-format */
                  (_("%B: Relocation exceeds allocated TOC (%lx)"),
                   input_bfd, (unsigned long) toc_section->size);
                bfd_set_error (bfd_error_bad_value);
@@ -1200,7 +1201,7 @@ coff_ppc_relocate_section (bfd *output_bfd,
          {
            /* To solve this, we need to know whether or not the symbol
               appearing on the call instruction is a glue function or not.
-              A glue function must announce itself via a IMGLUE reloc, and 
+              A glue function must announce itself via a IMGLUE reloc, and
               the reloc contains the required toc restore instruction.  */
            DUMP_RELOC2 (howto->name, rel);
 
@@ -1227,13 +1228,19 @@ coff_ppc_relocate_section (bfd *output_bfd,
        case IMAGE_REL_PPC_ABSOLUTE:
          {
            const char *my_name;
+           char buf[SYMNMLEN + 1];
 
            if (h == 0)
-             my_name = (syms+symndx)->_n._n_name;
+             {
+               strncpy (buf, (syms+symndx)->_n._n_name, SYMNMLEN);
+               buf[SYMNMLEN] = '\0';
+               my_name = buf;
+             }
            else
              my_name = h->root.root.root.string;
 
-           (*_bfd_error_handler)
+           _bfd_error_handler
+             /* xgettext: c-format */
              (_("Warning: unsupported reloc %s <file %B, section %A>\n"
                 "sym %ld (%s), r_vaddr %ld (%lx)"),
               input_bfd, input_section, howto->name,
@@ -1251,7 +1258,8 @@ coff_ppc_relocate_section (bfd *output_bfd,
              break;
            my_name = h->root.root.root.string;
 
-           (*_bfd_error_handler)
+           _bfd_error_handler
+             /* xgettext: c-format */
              (_("%B: Out of order IMGLUE reloc for %s"), input_bfd, my_name);
            bfd_set_error (bfd_error_bad_value);
            return FALSE;
@@ -1290,11 +1298,8 @@ coff_ppc_relocate_section (bfd *output_bfd,
              }
 
            if (h == 0)
-             {
-               /* It is a file local symbol.  */
-               sym = syms + symndx;
-               name = sym->_n._n_name;
-             }
+             /* It is a file local symbol.  */
+             sym = syms + symndx;
            else
              {
                char *target = 0;
@@ -1422,11 +1427,10 @@ coff_ppc_relocate_section (bfd *output_bfd,
                name = buf;
              }
 
-           if (! ((*info->callbacks->reloc_overflow)
-                  (info, (h ? &h->root.root : NULL), name, howto->name,
-                   (bfd_vma) 0, input_bfd,
-                   input_section, rel->r_vaddr - input_section->vma)))
-             return FALSE;
+           (*info->callbacks->reloc_overflow)
+             (info, (h ? &h->root.root : NULL), name, howto->name,
+              (bfd_vma) 0, input_bfd, input_section,
+              rel->r_vaddr - input_section->vma);
          }
        }
     }
@@ -1486,6 +1490,7 @@ dump_toc (void * vfile)
          else
            {
              fprintf (file,
+                      /* xgettext: c-format */
                      _("**** global_toc_size %ld(%lx), thunk_size %ld(%lx)\n"),
                       global_toc_size, (unsigned long) global_toc_size,
                       thunk_size, (unsigned long) thunk_size);
@@ -1762,9 +1767,10 @@ ppc_coff_rtype2howto (arelent *relent, struct internal_reloc *internal)
        howto = ppc_coff_howto_table + IMAGE_REL_PPC_TOCREL16;
       break;
     default:
-      (*_bfd_error_handler) (_("warning: unsupported reloc %s [%d] used -- it may not work"),
-                            ppc_coff_howto_table[r_type].name,
-                            r_type);
+      _bfd_error_handler
+       /* xgettext: c-format */
+       (_("warning: unsupported reloc %s [%d] used -- it may not work"),
+        ppc_coff_howto_table[r_type].name, r_type);
       howto = ppc_coff_howto_table + r_type;
       break;
     }
@@ -1833,9 +1839,10 @@ coff_ppc_rtype_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
       howto = ppc_coff_howto_table + r_type;
       break;
     default:
-      (*_bfd_error_handler) (_("warning: unsupported reloc %s [%d] used -- it may not work"),
-                            ppc_coff_howto_table[r_type].name,
-                            r_type);
+      _bfd_error_handler
+       /* xgettext: c-format */
+       (_("warning: unsupported reloc %s [%d] used -- it may not work"),
+        ppc_coff_howto_table[r_type].name, r_type);
       howto = ppc_coff_howto_table + r_type;
       break;
     }
@@ -2042,7 +2049,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
                  || info->strip == strip_some)
                o->lineno_count += sec->lineno_count;
 
-             if (info->relocatable)
+             if (bfd_link_relocatable (info))
                o->reloc_count += sec->reloc_count;
 
              if (sec->rawsize > max_contents_size)
@@ -2054,7 +2061,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
              if (sec->reloc_count > max_reloc_count)
                max_reloc_count = sec->reloc_count;
            }
-         else if (info->relocatable
+         else if (bfd_link_relocatable (info)
                   && (p->type == bfd_section_reloc_link_order
                       || p->type == bfd_symbol_reloc_link_order))
            ++o->reloc_count;
@@ -2071,7 +2078,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
 
   /* If doing a relocatable link, allocate space for the pointers we
      need to keep.  */
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
       unsigned int i;
 
@@ -2122,7 +2129,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
             memory until the end of the link.  This wastes memory,
             but only when doing a relocatable link, which is not the
             common case.  */
-         BFD_ASSERT (info->relocatable);
+         BFD_ASSERT (bfd_link_relocatable (info));
          amt = o->reloc_count;
          amt *= sizeof (struct internal_reloc);
          flaginfo.section_info[o->target_index].relocs =
@@ -2151,7 +2158,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
      the opportunity to clear the output_has_begun fields of all the
      input BFD's.  */
   max_sym_count = 0;
-  for (sub = info->input_bfds; sub != NULL; sub = sub->link_next)
+  for (sub = info->input_bfds; sub != NULL; sub = sub->link.next)
     {
       bfd_size_type sz;
 
@@ -2174,7 +2181,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
   flaginfo.linenos = (bfd_byte *) bfd_malloc (amt);
   flaginfo.contents = (bfd_byte *) bfd_malloc (max_contents_size);
   flaginfo.external_relocs = (bfd_byte *) bfd_malloc (max_reloc_count * relsz);
-  if (! info->relocatable)
+  if (! bfd_link_relocatable (info))
     {
       amt = max_reloc_count * sizeof (struct internal_reloc);
       flaginfo.internal_relocs = (struct internal_reloc *) bfd_malloc (amt);
@@ -2186,7 +2193,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
       || (flaginfo.linenos == NULL && max_lineno_count > 0)
       || (flaginfo.contents == NULL && max_contents_size > 0)
       || (flaginfo.external_relocs == NULL && max_reloc_count > 0)
-      || (! info->relocatable
+      || (! bfd_link_relocatable (info)
          && flaginfo.internal_relocs == NULL
          && max_reloc_count > 0))
     goto error_return;
@@ -2320,7 +2327,7 @@ ppc_bfd_coff_final_link (bfd *abfd, struct bfd_link_info *info)
       flaginfo.outsyms = NULL;
     }
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     {
       /* Now that we have written out all the global symbols, we know
         the symbol indices to use for relocs against them, and we can
This page took 0.028326 seconds and 4 git commands to generate.