ubsan: moxie: left shift of negative value
[deliverable/binutils-gdb.git] / opcodes / s12z-dis.c
index 14176fb6d9e47f83280ec0c8eacfcfea4d1a113e..5930ab4ef6698b42d2ffd2f5ccd90c8f9270d0e6 100644 (file)
 #include <assert.h>
 
 #include "opcode/s12z.h"
-
 #include "bfd.h"
 #include "dis-asm.h"
-
 #include "disassemble.h"
-
 #include "s12z-opc.h"
+#include "opintl.h"
 
 struct mem_read_abstraction
 {
@@ -255,7 +253,11 @@ opr_emit_disassembly (const struct operand *opr,
     case OPND_CL_REGISTER:
       {
         int r = ((struct register_operand*) opr)->reg;
-       (*info->fprintf_func) (info->stream, "%s", registers[r].name);
+
+       if (r < 0 || r >= S12Z_N_REGISTERS)
+         (*info->fprintf_func) (info->stream, _("<illegal reg num>"));
+       else
+         (*info->fprintf_func) (info->stream, "%s", registers[r].name);
       }
       break;
     case OPND_CL_REGISTER_ALL16:
@@ -282,41 +284,49 @@ opr_emit_disassembly (const struct operand *opr,
         struct memory_operand *mo = (struct memory_operand *) opr;
        (*info->fprintf_func) (info->stream, "%c", mo->indirect ? '[' : '(');
 
-        if (mo->base_offset != 0)
-          {
-            (*info->fprintf_func) (info->stream, "%d", mo->base_offset);
-          }
-        else if (mo->n_regs > 0)
-          {
-           const char *fmt;
-           switch (mo->mutation)
-             {
-             case OPND_RM_PRE_DEC:
-               fmt = "-%s";
-               break;
-             case OPND_RM_PRE_INC:
-               fmt = "+%s";
-               break;
-             case OPND_RM_POST_DEC:
-               fmt = "%s-";
-               break;
-             case OPND_RM_POST_INC:
-               fmt = "%s+";
-               break;
-             case OPND_RM_NONE:
-             default:
-               fmt = "%s";
-               break;
-             }
-            (*info->fprintf_func) (info->stream, fmt,
-                                  registers[mo->regs[0]].name);
-            used_reg = 1;
-          }
+       const char *fmt;
+       assert (mo->mutation == OPND_RM_NONE || mo->n_regs == 1);
+       switch (mo->mutation)
+         {
+         case OPND_RM_PRE_DEC:
+           fmt = "-%s";
+           break;
+         case OPND_RM_PRE_INC:
+           fmt = "+%s";
+           break;
+         case OPND_RM_POST_DEC:
+           fmt = "%s-";
+           break;
+         case OPND_RM_POST_INC:
+           fmt = "%s+";
+           break;
+         case OPND_RM_NONE:
+         default:
+           if (mo->n_regs < 2)
+             (*info->fprintf_func) (info->stream, (mo->n_regs == 0) ? "%d" : "%d,", mo->base_offset);
+           fmt = "%s";
+           break;
+         }
+       if (mo->n_regs > 0)
+         {
+           int r = mo->regs[0];
+
+           if (r < 0 || r >= S12Z_N_REGISTERS)
+             (*info->fprintf_func) (info->stream, fmt, _("<illegal reg num>"));
+           else
+             (*info->fprintf_func) (info->stream, fmt, registers[r].name);
+         }
+       used_reg = 1;
 
         if (mo->n_regs > used_reg)
           {
-            (*info->fprintf_func) (info->stream, ",%s",
-                                  registers[mo->regs[used_reg]].name);
+           int r = mo->regs[used_reg];
+
+           if (r < 0 || r >= S12Z_N_REGISTERS)
+             (*info->fprintf_func) (info->stream, _("<illegal reg num>"));
+           else
+             (*info->fprintf_func) (info->stream, ",%s",
+                                    registers[r].name);
           }
 
        (*info->fprintf_func) (info->stream, "%c",
@@ -326,7 +336,9 @@ opr_emit_disassembly (const struct operand *opr,
     };
 }
 
-static const char shift_size_table[] = {
+#define S12Z_N_SIZES 4
+static const char shift_size_table[S12Z_N_SIZES] =
+{
   'b', 'w', 'p', 'l'
 };
 
@@ -334,7 +346,7 @@ int
 print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
 {
   int o;
-  enum operator operator = OP_INVALID;
+  enum optr operator = OP_INVALID;
   int n_operands = 0;
 
   /* The longest instruction in S12Z can have 6 operands.
@@ -354,33 +366,43 @@ print_insn_s12z (bfd_vma memaddr, struct disassemble_info* info)
                 (struct mem_read_abstraction_base *) &mra);
 
   (info->fprintf_func) (info->stream, "%s", mnemonics[(long)operator]);
-  
+
   /* Ship out size sufficies for those instructions which
      need them.  */
   if (osize == -1)
     {
       bool suffix = false;
+
       for (o = 0; o < n_operands; ++o)
        {
-         if (operands[o]->osize != -1)
+         if (operands[o] && operands[o]->osize != -1)
            {
              if (!suffix)
                {
                  (*mra.info->fprintf_func) (mra.info->stream, "%c", '.');
                  suffix = true;
                }
-             (*mra.info->fprintf_func) (mra.info->stream, "%c",
-                                    shift_size_table[operands[o]->osize]);
+
+             osize = operands[o]->osize;
+
+             if (osize < 0 || osize >= S12Z_N_SIZES)
+               (*mra.info->fprintf_func) (mra.info->stream, _("<bad>"));
+             else
+               (*mra.info->fprintf_func) (mra.info->stream, "%c",
+                                          shift_size_table[osize]);
+               
            }
        }
     }
   else
     {
-      (*mra.info->fprintf_func) (mra.info->stream, ".%c",
-                            shift_size_table[osize]);
+      if (osize < 0 || osize >= S12Z_N_SIZES)
+       (*mra.info->fprintf_func) (mra.info->stream, _(".<bad>"));
+      else
+       (*mra.info->fprintf_func) (mra.info->stream, ".%c",
+                                  shift_size_table[osize]);
     }
 
-
   /* Ship out the operands.  */
   for (o = 0; o < n_operands; ++o)
     {
This page took 0.042854 seconds and 4 git commands to generate.