Don't define _FORTIFY_SOURCE on MinGW
[deliverable/binutils-gdb.git] / opcodes / vax-dis.c
index 63884f6b158cf0603140f0b8b07f79f9e9d3dafe..f58c4ad4f2d7ccdf90974a56198fb822c6a05304 100644 (file)
@@ -1,6 +1,5 @@
 /* Print VAX instructions.
-   Copyright 1995, 1998, 2000, 2001, 2002, 2005, 2007
-   Free Software Foundation, Inc.
+   Copyright (C) 1995-2020 Free Software Foundation, Inc.
    Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
 
    This file is part of the GNU opcodes library.
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
+#include "sysdep.h"
 #include <setjmp.h>
 #include <string.h>
-#include "sysdep.h"
 #include "opcode/vax.h"
-#include "dis-asm.h"
+#include "disassemble.h"
 
 static char *reg_names[] =
 {
@@ -65,7 +64,7 @@ static char *entry_mask_bit[] =
 #define COERCE32(x) ((int) (((x) ^ 0x80000000) - 0x80000000))
 #define NEXTLONG(p)  \
   (p += 4, FETCH_DATA (info, p), \
-   (COERCE32 ((((((p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
+   (COERCE32 (((((((unsigned) p[-1] << 8) + p[-2]) << 8) + p[-3]) << 8) + p[-4])))
 
 /* Maximum length of an instruction.  */
 #define MAXLEN 25
@@ -76,7 +75,7 @@ struct private
   bfd_byte * max_fetched;
   bfd_byte   the_buffer[MAXLEN];
   bfd_vma    insn_start;
-  jmp_buf    bailout;
+  OPCODES_SIGJMP_BUF    bailout;
 };
 
 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
@@ -100,7 +99,7 @@ fetch_data (struct disassemble_info *info, bfd_byte *addr)
   if (status != 0)
     {
       (*info->memory_error_func) (status, start, info);
-      longjmp (priv->bailout, 1);
+      OPCODES_SIGLONGJMP (priv->bailout, 1);
     }
   else
     priv->max_fetched = addr;
@@ -118,7 +117,7 @@ static bfd_vma *     entry_addr = NULL;
    there's no symbol table.  Returns TRUE upon success, FALSE otherwise.  */
 
 static bfd_boolean
-parse_disassembler_options (char * options)
+parse_disassembler_options (const char *options)
 {
   const char * entry_switch = "entry:";
 
@@ -132,14 +131,14 @@ parse_disassembler_options (char * options)
          /* A guesstimate of the number of entries we will have to create.  */
          entry_addr_total_slots +=
            strlen (options) / (strlen (entry_switch) + 5);
-         
+
          entry_addr = realloc (entry_addr, sizeof (bfd_vma)
                                * entry_addr_total_slots);
        }
 
       if (entry_addr == NULL)
        return FALSE;
-         
+
       entry_addr[entry_addr_occupied_slots] = bfd_scan_vma (options, NULL, 0);
       entry_addr_occupied_slots ++;
     }
@@ -241,8 +240,18 @@ print_insn_mode (const char *d,
         (*info->fprintf_func) (info->stream, "$0x%x", mode);
       break;
     case 0x40: /* Index:                       base-addr[Rn] */
-      p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
-      (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
+      {
+       unsigned char *q = p0 + 1;
+       unsigned char nextmode = NEXTBYTE (q);
+       if (nextmode < 0x60 || nextmode == 0x8f)
+         /* Literal, index, register, or immediate is invalid.  In
+            particular don't recurse into another index mode which
+            might overflow the_buffer.   */
+         (*info->fprintf_func) (info->stream, "[invalid base]");
+       else
+         p += print_insn_mode (d, size, p0 + 1, addr + 1, info);
+       (*info->fprintf_func) (info->stream, "[%s]", reg_names[reg]);
+      }
       break;
     case 0x50: /* Register:                    Rn */
       (*info->fprintf_func) (info->stream, "%s", reg_names[reg]);
@@ -297,6 +306,7 @@ print_insn_mode (const char *d,
       break;
     case 0xB0: /* Displacement byte deferred:  *displ(Rn).  */
       (*info->fprintf_func) (info->stream, "*");
+      /* Fall through.  */
     case 0xA0: /* Displacement byte:           displ(Rn).  */
       if (reg == 0xF)
        (*info->print_address_func) (addr + 2 + NEXTBYTE (p), info);
@@ -306,6 +316,7 @@ print_insn_mode (const char *d,
       break;
     case 0xD0: /* Displacement word deferred:  *displ(Rn).  */
       (*info->fprintf_func) (info->stream, "*");
+      /* Fall through.  */
     case 0xC0: /* Displacement word:           displ(Rn).  */
       if (reg == 0xF)
        (*info->print_address_func) (addr + 3 + NEXTWORD (p), info);
@@ -315,6 +326,7 @@ print_insn_mode (const char *d,
       break;
     case 0xF0: /* Displacement long deferred:  *displ(Rn).  */
       (*info->fprintf_func) (info->stream, "*");
+      /* Fall through.  */
     case 0xE0: /* Displacement long:           displ(Rn).  */
       if (reg == 0xF)
        (*info->print_address_func) (addr + 5 + NEXTLONG (p), info);
@@ -396,14 +408,15 @@ print_insn_vax (bfd_vma memaddr, disassemble_info *info)
       parsed_disassembler_options = TRUE;
     }
 
-  if (setjmp (priv.bailout) != 0)
+  if (OPCODES_SIGSETJMP (priv.bailout) != 0)
     /* Error return.  */
     return -1;
 
   argp = NULL;
   /* Check if the info buffer has more than one byte left since
      the last opcode might be a single byte with no argument data.  */
-  if (info->buffer_length - (memaddr - info->buffer_vma) > 1)
+  if (info->buffer_length - (memaddr - info->buffer_vma) > 1
+      && (info->stop_vma == 0 || memaddr < (info->stop_vma - 1)))
     {
       FETCH_DATA (info, buffer + 2);
     }
@@ -437,7 +450,8 @@ print_insn_vax (bfd_vma memaddr, disassemble_info *info)
       int offset;
 
       FETCH_DATA (info, buffer + 4);
-      offset = buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0];
+      offset = ((unsigned) buffer[3] << 24 | buffer[2] << 16
+               | buffer[1] << 8 | buffer[0]);
       (*info->fprintf_func) (info->stream, ".long 0x%08x", offset);
 
       return 4;
This page took 0.02444 seconds and 4 git commands to generate.