PR29482 - strip: heap-buffer-overflow
[binutils-gdb.git] / sim / h8300 / compile.c
index a45a676ad0e3dbe9556e4f97b510712aadc11bf1..9be7dd565a922466cede1fae3fea94f5f5bab809 100644 (file)
@@ -33,6 +33,8 @@
 #include "sys/stat.h"
 #include "sys/types.h"
 #include "sim-options.h"
+#include "sim-signal.h"
+#include "sim/callback.h"
 
 #ifndef SIGTRAP
 # define SIGTRAP 5
@@ -490,6 +492,7 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
 
   dst->dst.type = -1;
   dst->src.type = -1;
+  dst->op3.type = -1;
 
   /* Find the exact opcode/arg combo.  */
   for (q = h8_opcodes; q->name; q++)
@@ -1100,6 +1103,35 @@ decode (SIM_DESC sd, int addr, unsigned char *data, decoded_inst *dst)
                      /* End of Processing for system calls.  */
                    }
 
+                 /* Use same register is specified for source
+                    and destination.
+                    The value of source will be the value after
+                    address calculation.  */
+                 if (OP_KIND (dst->opcode) != O_CMP &&
+                     OP_KIND (dst->src.type) == OP_REG &&
+                     (dst->src.reg & 7) == dst->dst.reg) {
+                   switch (OP_KIND (dst->dst.type))
+                     {
+                     case OP_POSTDEC:
+                       dst->src.type = X (OP_REG_DEC,
+                                          OP_SIZE (dst->dst.type));
+                       break;
+                     case OP_POSTINC:
+                       dst->src.type = X (OP_REG_INC,
+                                          OP_SIZE (dst->dst.type));
+                       break;
+                     case OP_PREINC:
+                       if (OP_KIND (dst->opcode) == O_MOV)
+                         dst->src.type = X (OP_REG_INC,
+                                            OP_SIZE (dst->dst.type));
+                       break;
+                     case OP_PREDEC:
+                       if (OP_KIND (dst->opcode) == O_MOV)
+                         dst->src.type = X (OP_REG_DEC,
+                                            OP_SIZE (dst->dst.type));
+                       break;
+                     }
+                 }
                  dst->next_pc = addr + len / 2;
                  return;
                }
@@ -1370,6 +1402,25 @@ fetch_1 (SIM_DESC sd, ea_type *arg, int *val, int twice)
       *val = abs;
       break;
 
+    case X (OP_REG_DEC, SB):   /* Register direct, affected decrement byte.  */
+      *val = GET_B_REG (rn) - 1;
+      break;
+    case X (OP_REG_DEC, SW):   /* Register direct, affected decrement word.  */
+      *val = GET_W_REG (rn) - 2;
+      break;
+    case X (OP_REG_DEC, SL):   /* Register direct, affected decrement long.  */
+      *val = GET_L_REG (rn) - 4;
+      break;
+    case X (OP_REG_INC, SB):   /* Register direct, affected increment byte.  */
+      *val = GET_B_REG (rn) + 1;
+      break;
+    case X (OP_REG_INC, SW):   /* Register direct, affected increment word.  */
+      *val = GET_W_REG (rn) + 2;
+      break;
+    case X (OP_REG_INC, SL):   /* Register direct, affected increment long.  */
+      *val = GET_L_REG (rn) + 4;
+      break;
+
     case X (OP_MEM, SB):       /* Why isn't this implemented?  */
     default:
       sim_engine_halt (sd, cpu, NULL, NULL_CIA, sim_stopped, SIM_SIGSEGV);
@@ -1803,7 +1854,7 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
                of the same register.
          */
 
-         if (code->op3.type == 0)
+         if (code->op3.type == -1)
            {
              /* Short form: src == INDEXB/INDEXW, dst == op3 == 0.
                 We get to compose dst and op3 as follows:
@@ -1981,7 +2032,7 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
 
        case O (O_AND, SB):             /* and.b */
          /* Fetch rd and ea.  */
-         if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 
+         if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
            goto end;
          res = rd & ea;
          goto log8;
@@ -2002,7 +2053,7 @@ step_once (SIM_DESC sd, SIM_CPU *cpu)
 
        case O (O_OR, SB):              /* or.b */
          /* Fetch rd and ea.  */
-         if (fetch (sd, &code->src, &ea) || fetch2 (sd, &code->dst, &rd)) 
+         if (fetch2 (sd, &code->dst, &rd) || fetch (sd, &code->src, &ea))
            goto end;
          res = rd | ea;
          goto log8;
@@ -4667,6 +4718,9 @@ sim_open (SIM_OPEN_KIND kind,
 
   sd = sim_state_alloc_extra (kind, callback, sizeof (struct h8300_sim_state));
 
+  /* Set default options before parsing user options.  */
+  current_target_byte_order = BFD_ENDIAN_BIG;
+
   /* The cpu data is kept in a separately allocated chunk of memory.  */
   if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
     {
@@ -4702,10 +4756,7 @@ sim_open (SIM_OPEN_KIND kind,
     }
 
   /* Check for/establish the a reference program image.  */
-  if (sim_analyze_program (sd,
-                          (STATE_PROG_ARGV (sd) != NULL
-                           ? *STATE_PROG_ARGV (sd)
-                           : NULL), abfd) != SIM_RC_OK)
+  if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
     {
       free_state (sd);
       return 0;