]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - opcodes/vax-dis.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / opcodes / vax-dis.c
index 937c45206b89c8add6bbd179c5cffb88aaf8b60c..b0000f617b2d9a6ac5afb4cd78c7c2b3c5e9bed4 100644 (file)
@@ -1,5 +1,5 @@
 /* Print VAX instructions.
-   Copyright (C) 1995-2016 Free Software Foundation, Inc.
+   Copyright (C) 1995-2021 Free Software Foundation, Inc.
    Contributed by Pauline Middelink <middelin@polyware.iaf.nl>
 
    This file is part of the GNU opcodes library.
@@ -23,7 +23,7 @@
 #include <setjmp.h>
 #include <string.h>
 #include "opcode/vax.h"
-#include "dis-asm.h"
+#include "disassemble.h"
 
 static char *reg_names[] =
 {
@@ -64,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
@@ -117,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:";
 
@@ -129,8 +129,8 @@ parse_disassembler_options (char * options)
       if (entry_addr_occupied_slots >= entry_addr_total_slots)
        {
          /* A guesstimate of the number of entries we will have to create.  */
-         entry_addr_total_slots +=
-           strlen (options) / (strlen (entry_switch) + 5);
+         entry_addr_total_slots
+           += 1 + strlen (options) / (strlen (entry_switch) + 5);
 
          entry_addr = realloc (entry_addr, sizeof (bfd_vma)
                                * entry_addr_total_slots);
@@ -240,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]);
@@ -296,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);
@@ -305,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);
@@ -314,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);
@@ -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;