This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Commit: ARM SIM: Add tracing support.


Hi Guys,

  I am applying the attached patch to add tracing support to the ARM
  simulator.  With the patch applied three new command line options are
  now supported: -t enables tracing, -d enables disassembly and -z
  enables a limited form of tracing which just reports function entry
  and exits.

  In the course of testing this patch I also came across a variety of
  compile time warning messages.  So the patch also tidies these up,
  just to make things clean and proper.

Cheers
  Nick

sim/arm/ChangeLog
2014-03-14  Nick Clifton  <nickc@redhat.com>

	* wrapper.c (op_print): New function.
	(sim_dis_read): New function.
	(print_insn): New function - disassembles the given instruction.
	(sim_trace): Note that tracing is now allowed.
	(sim_create_inferior): Default to emulating v6.
	Initialise the disassembler machinery.
	(sim_target_parse_command_line): Add support for -t -d and -z
	options.
	(sim_target_display_usage): Note existence of -d and -z options.
	(sim_open): Parse -t -d and -z options.
	* armemu.h: Add exports of trace, disas and trace_funcs.
	Add prototype for print_insn.
	* armemu.c (ARMul_Emulate26): Add tracing code.
	Delete unused variables.
	* thumbemu (handle_v6_thumb_insn): Delete unused variable Rd.
	Move Rm variable into switch cases.
	Add tracing code.

	* armcopro.c (XScale_cp15_init): Add a return value.
	(XScale_cp13_init): Likewise.
	(XScale_cp14_init): Likewise.
	(XScale_cp15_LDC): Delete unused function.
	(XScale_cp15_STC): Likewise.
	* maverick.c: Delete comment inside comment.
	(DSPInit): Delete unused function.
	(DSPMCR4): Fix compile time warning about missing parenthesis.
	(DSPMCR5): Likewise.
	(DSPCDP6): Delete unused variable opcode2.

diff --git a/sim/arm/armcopro.c b/sim/arm/armcopro.c
index 8194b31..4c5da24 100644
--- a/sim/arm/armcopro.c
+++ b/sim/arm/armcopro.c
@@ -85,6 +85,8 @@ XScale_cp15_init (ARMul_State * state ATTRIBUTE_UNUSED)
 
   /* Initialise the ARM Control Register.  */
   XScale_cp15_opcode_2_is_0_Regs[1] = 0x00000078;
+
+  return TRUE;
 }
 
 /* Check an access to a register.  */
@@ -371,34 +373,6 @@ read_cp15_reg (unsigned reg, unsigned opcode_2, unsigned CRm)
 }
 
 static unsigned
-XScale_cp15_LDC (ARMul_State * state, unsigned type, ARMword instr, ARMword data)
-{
-  unsigned reg = BITS (12, 15);
-  unsigned result;
-  
-  result = check_cp15_access (state, reg, 0, 0, 0);
-
-  if (result == ARMul_DONE && type == ARMul_DATA)
-    write_cp15_reg (state, reg, 0, 0, data);
-
-  return result;
-}
-
-static unsigned
-XScale_cp15_STC (ARMul_State * state, unsigned type, ARMword instr, ARMword * data)
-{
-  unsigned reg = BITS (12, 15);
-  unsigned result;
-
-  result = check_cp15_access (state, reg, 0, 0, 0);
-
-  if (result == ARMul_DONE && type == ARMul_DATA)
-    * data = read_cp15_reg (reg, 0, 0);
-
-  return result;
-}
-
-static unsigned
 XScale_cp15_MRC (ARMul_State * state,
 		 unsigned      type ATTRIBUTE_UNUSED,
 		 ARMword       instr,
@@ -582,6 +556,8 @@ XScale_cp13_init (ARMul_State * state ATTRIBUTE_UNUSED)
       XScale_cp13_CR0_Regs[i] = 0;
       XScale_cp13_CR1_Regs[i] = 0;
     }
+
+  return TRUE;
 }
 
 /* Check an access to a register.  */
@@ -812,6 +788,8 @@ XScale_cp14_init (ARMul_State * state ATTRIBUTE_UNUSED)
 
   for (i = 16; i--;)
     XScale_cp14_Regs[i] = 0;
+
+  return TRUE;
 }
 
 /* Check an access to a register.  */
diff --git a/sim/arm/armemu.c b/sim/arm/armemu.c
index 64c0146..d535a4e 100644
--- a/sim/arm/armemu.c
+++ b/sim/arm/armemu.c
@@ -580,11 +580,20 @@ ARMul_Emulate26 (ARMul_State * state)
 
       if (state->EventSet)
 	ARMul_EnvokeEvent (state);
-#if 0 /* Enable this for a helpful bit of debugging when tracing is needed.  */
-      fprintf (stderr, "pc: %x, instr: %x\n", pc & ~1, instr);
-      if (instr == 0)
-	abort ();
-#endif
+
+      if (! TFLAG && trace)
+	{
+	  fprintf (stderr, "pc: %x, ", pc & ~1);
+	  if (! disas)
+	    fprintf (stderr, "instr: %x\n", instr);
+	}
+
+      if (instr == 0 || pc < 0x10)
+	{
+	  ARMul_Abort (state, ARMUndefinedInstrV);
+	  state->Emulate = FALSE;
+	}
+
 #if 0 /* Enable this code to help track down stack alignment bugs.  */
       {
 	static ARMword old_sp = -1;
@@ -628,8 +637,8 @@ ARMul_Emulate26 (ARMul_State * state)
 	    }
 	  if (state->Debug)
 	    {
-	      fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n", pc, instr,
-		       state->Mode);
+	      fprintf (stderr, "sim: At %08lx Instr %08lx Mode %02lx\n",
+		       (long) pc, (long) instr, (long) state->Mode);
 	      (void) fgetc (stdin);
 	    }
 	}
@@ -667,6 +676,14 @@ ARMul_Emulate26 (ARMul_State * state)
 
 	    case t_decoded:
 	      /* ARM instruction available.  */
+	      if (disas || trace)
+		{
+		  fprintf (stderr, "  emulate as: ");
+		  if (trace)
+		    fprintf (stderr, "%08x ", new);
+		  if (! disas)
+		    fprintf (stderr, "\n");
+		}
 	      instr = new;
 	      /* So continue instruction decoding.  */
 	      break;
@@ -675,6 +692,8 @@ ARMul_Emulate26 (ARMul_State * state)
 	    }
 	}
 #endif
+      if (disas)
+	print_insn (instr);
 
       /* Check the condition codes.  */
       if ((temp = TOPBITS (28)) == AL)
@@ -1654,7 +1673,6 @@ check_PMUintr:
 		{
 		  if (BITS (4, 7) == 0x7)
 		    {
-		      ARMword value;
 		      extern int SWI_vector_installed;
 
 		      /* Hardware is allowed to optionally override this
@@ -1736,7 +1754,6 @@ check_PMUintr:
 		      ARMdword op1 = state->Reg[BITS (0, 3)];
 		      ARMdword op2 = state->Reg[BITS (8, 11)];
 		      ARMdword dest;
-		      ARMdword result;
 
 		      if (BIT (5))
 			op1 >>= 16;
@@ -1877,7 +1894,6 @@ check_PMUintr:
 		      /* ElSegundo SMULxy insn.  */
 		      ARMword op1 = state->Reg[BITS (0, 3)];
 		      ARMword op2 = state->Reg[BITS (8, 11)];
-		      ARMword Rn = state->Reg[BITS (12, 15)];
 
 		      if (BIT (5))
 			op1 >>= 16;
@@ -3459,7 +3475,6 @@ check_PMUintr:
 	      FLUSHPIPE;
 	      break;
 
-
 	      /* Branch and Link forward.  */
 	    case 0xb0:
 	    case 0xb1:
@@ -3477,9 +3492,10 @@ check_PMUintr:
 #endif
 	      state->Reg[15] = pc + 8 + POSBRANCH;
 	      FLUSHPIPE;
+	      if (trace_funcs)
+		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 	      break;
 
-
 	      /* Branch and Link backward.  */
 	    case 0xb8:
 	    case 0xb9:
@@ -3497,9 +3513,10 @@ check_PMUintr:
 #endif
 	      state->Reg[15] = pc + 8 + NEGBRANCH;
 	      FLUSHPIPE;
+	      if (trace_funcs)
+		fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 	      break;
 
-
 	      /* Co-Processor Data Transfers.  */
 	    case 0xc4:
 	      if (state->is_v5)
@@ -4150,6 +4167,8 @@ WriteR15 (ARMul_State * state, ARMword src)
 #endif
 
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 }
 
 /* This routine handles writes to register 15 when the S bit is set.  */
@@ -4187,6 +4206,8 @@ WriteSR15 (ARMul_State * state, ARMword src)
   ARMul_R15Altered (state);
 #endif
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 }
 
 /* In machines capable of running in Thumb mode, BX, BLX, LDR and LDM
@@ -4208,6 +4229,8 @@ WriteR15Branch (ARMul_State * state, ARMword src)
       state->Reg[15] = src & 0xfffffffc;
     }
   FLUSHPIPE;
+  if (trace_funcs)
+    fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 #else
   WriteR15 (state, src);
 #endif
diff --git a/sim/arm/armemu.h b/sim/arm/armemu.h
index d61c85a..419f799 100644
--- a/sim/arm/armemu.h
+++ b/sim/arm/armemu.h
@@ -15,6 +15,10 @@
     along with this program; if not, see <http://www.gnu.org/licenses/>. */
 
 extern ARMword isize;
+extern int trace;
+extern int disas;
+extern int trace_funcs;
+extern void print_insn (ARMword);
 
 /* Condition code values.  */
 #define EQ 0
diff --git a/sim/arm/maverick.c b/sim/arm/maverick.c
index 2acf2b6..b9a6517 100644
--- a/sim/arm/maverick.c
+++ b/sim/arm/maverick.c
@@ -20,7 +20,7 @@
 #include "ansidecl.h"
 #include "armemu.h"
 
-/*#define CIRRUS_DEBUG 1	/**/
+/*#define CIRRUS_DEBUG 1	*/
 #if CIRRUS_DEBUG
 #  define printfdbg printf
 #else
@@ -97,13 +97,6 @@ cirrus_not_implemented (char * insn)
   exit (1);
 }
 
-static unsigned
-DSPInit (ARMul_State * state)
-{
-  ARMul_ConsolePrint (state, ", DSP present");
-  return TRUE;
-}
-
 unsigned
 DSPMRC4 (ARMul_State * state ATTRIBUTE_UNUSED,
 	 unsigned      type  ATTRIBUTE_UNUSED,
@@ -270,8 +263,9 @@ DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,
 	v = SubOverflow (DSPregs[SRC1_REG].lower.i, DSPregs[SRC2_REG].lower.i,
 			 res);
 	/* carry */
-	c = (NEG (a) && POS (b) ||
-	     (NEG (a) && POS (res)) || (POS (b) && POS (res)));
+	c = (NEG (a) && POS (b))
+	  || (NEG (a) && POS (res))
+	  || (POS (b) && POS (res));
 
 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
 	break;
@@ -301,8 +295,9 @@ DSPMRC5 (ARMul_State * state ATTRIBUTE_UNUSED,
 	v = ((NEG64 (a) && POS64 (b) && POS64 (res))
 	     || (POS64 (a) && NEG64 (b) && NEG64 (res)));
 	/* carry */
-	c = (NEG64 (a) && POS64 (b) ||
-	     (NEG64 (a) && POS64 (res)) || (POS64 (b) && POS64 (res)));
+	c =    (NEG64 (a) && POS64 (b))
+	    || (NEG64 (a) && POS64 (res))
+	    || (POS64 (b) && POS64 (res));
 
 	*value = (n << 31) | (z << 30) | (c << 29) | (v << 28);
 	break;
@@ -1167,10 +1162,6 @@ DSPCDP6 (ARMul_State * state,
 	 unsigned      type,
 	 ARMword       instr)
 {
-   int opcode2;
-
-   opcode2 = BITS (5,7);
-
    switch (BITS (20,21))
      {
      case 0:
diff --git a/sim/arm/thumbemu.c b/sim/arm/thumbemu.c
index b8ef7df..e4c91f6 100644
--- a/sim/arm/thumbemu.c
+++ b/sim/arm/thumbemu.c
@@ -38,9 +38,6 @@ handle_v6_thumb_insn (ARMul_State * state,
 		      ARMword       tinstr,
 		      tdstate *     pvalid)
 {
-  ARMword Rd;
-  ARMword Rm;
-
   if (! state->is_v6)
     {
       * pvalid = t_undefined;
@@ -56,33 +53,48 @@ handle_v6_thumb_insn (ARMul_State * state,
     case 0xba40: /* rev16 */
     case 0xbac0: /* revsh */
     case 0xb650: /* setend */
-    default:  
+    default:
       printf ("Unhandled v6 thumb insn: %04x\n", tinstr);
       * pvalid = t_undefined;
       return;
 
     case 0xb200: /* sxth */
-      Rm = state->Reg [(tinstr & 0x38) >> 3];
-      if (Rm & 0x8000)
-	state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
-      else
-	state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
-      break;
+      {
+	ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+	if (Rm & 0x8000)
+	  state->Reg [(tinstr & 0x7)] = (Rm & 0xffff) | 0xffff0000;
+	else
+	  state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+	break;
+      }
+
     case 0xb240: /* sxtb */
-      Rm = state->Reg [(tinstr & 0x38) >> 3];
-      if (Rm & 0x80)
-	state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
-      else
-	state->Reg [(tinstr & 0x7)] = Rm & 0xff;
-      break;
+      {
+	ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+	if (Rm & 0x80)
+	  state->Reg [(tinstr & 0x7)] = (Rm & 0xff) | 0xffffff00;
+	else
+	  state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+	break;
+      }
+
     case 0xb280: /* uxth */
-      Rm = state->Reg [(tinstr & 0x38) >> 3];
-      state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
-      break;
+      {
+	ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+	state->Reg [(tinstr & 0x7)] = Rm & 0xffff;
+	break;
+      }
+
     case 0xb2c0: /* uxtb */
-      Rm = state->Reg [(tinstr & 0x38) >> 3];
-      state->Reg [(tinstr & 0x7)] = Rm & 0xff;
-      break;
+      {
+	ARMword Rm = state->Reg [(tinstr & 0x38) >> 3];
+
+	state->Reg [(tinstr & 0x7)] = Rm & 0xff;
+	break;
+      }
     }
   /* Indicate that the instruction has been processed.  */
   * pvalid = t_branch;
@@ -113,6 +125,9 @@ ARMul_ThumbDecode (ARMul_State * state,
       tinstr &= 0xFFFF;
     }
 
+  if (trace)
+    fprintf (stderr, "pc: %x, Thumb instr: %x", pc & ~1, tinstr);
+
 #if 1				/* debugging to catch non updates */
   *ainstr = 0xDEADC0DE;
 #endif
@@ -550,6 +565,8 @@ ARMul_ThumbDecode (ARMul_State * state,
 	    state->Reg[14] = (tmp | 1);
 	    valid = t_branch;
 	    FLUSHPIPE;
+	    if (trace_funcs)
+	      fprintf (stderr, " pc changed to %x\n", state->Reg[15]);
 	    break;
 	  }
 	}
@@ -610,5 +627,8 @@ ARMul_ThumbDecode (ARMul_State * state,
       break;
     }
 
+  if (trace && valid != t_decoded)
+    fprintf (stderr, "\n");
+
   return valid;
 }
diff --git a/sim/arm/wrapper.c b/sim/arm/wrapper.c
index 064962b..228cbc8 100644
--- a/sim/arm/wrapper.c
+++ b/sim/arm/wrapper.c
@@ -37,6 +37,7 @@
 #include "gdb/sim-arm.h"
 #include "gdb/signals.h"
 #include "libiberty.h"
+#include "iwmmxt.h"
 
 host_callback *sim_callback;
 
@@ -59,6 +60,54 @@ static int big_endian;
 
 int stop_simulator;
 
+#include "dis-asm.h"
+
+int trace = 0;
+int disas = 0;
+int trace_funcs = 0;
+
+static struct disassemble_info  info;
+static char opbuf[1000];
+
+static int
+op_printf (char *buf, char *fmt, ...)
+{
+  int ret;
+  va_list ap;
+
+  va_start (ap, fmt);
+  ret = vsprintf (opbuf + strlen (opbuf), fmt, ap);
+  va_end (ap);
+  return ret;
+}
+
+static int
+sim_dis_read (bfd_vma                     memaddr ATTRIBUTE_UNUSED,
+	      bfd_byte *                  ptr,
+	      unsigned int                length,
+	      struct disassemble_info *   info)
+{
+  ARMword val = (ARMword) *((ARMword *) info->application_data);
+
+  while (length--)
+    {
+      * ptr ++ = val & 0xFF;
+      val >>= 8;
+    }
+  return 0;
+}
+
+void
+print_insn (ARMword instr)
+{
+  int size;
+
+  opbuf[0] = 0;
+  info.application_data = & instr;
+  size = print_insn_little_arm (0, & info);
+  fprintf (stderr, " %*s\n", size, opbuf);
+}
+
 /* Cirrus DSP registers.
 
    We need to define these registers outside of maverick.c because
@@ -192,10 +241,9 @@ sim_read (sd, addr, buffer, size)
 int
 sim_trace (sd)
      SIM_DESC sd ATTRIBUTE_UNUSED;
-{  
-  (*sim_callback->printf_filtered)
-    (sim_callback,
-     "This simulator does not support tracing\n");
+{
+  trace = 1;
+  sim_resume (sd, 0, 0);
   return 1;
 }
 
@@ -269,9 +317,9 @@ sim_create_inferior (sd, abfd, argv, env)
       /* We wouldn't set the machine type with earlier toolchains, so we
 	 explicitly select a processor capable of supporting all ARMs in
 	 32bit mode.  */
-      /* We choose the XScale rather than the iWMMXt, because the iWMMXt
-	 removes the FPE emulator, since it conflicts with its coprocessors.
-	 For the most generic ARM support, we want the FPE emulator in place.  */
+      ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_v6_Prop);
+      break;
+
     case bfd_mach_arm_XScale:
       ARMul_SelectProcessor (state, ARM_v5_Prop | ARM_v5e_Prop | ARM_XScale_Prop | ARM_v6_Prop);
       break;
@@ -351,6 +399,16 @@ sim_create_inferior (sd, abfd, argv, env)
       ARMul_SetCPSR (state, SVC32MODE);
     }
   
+  memset (& info, 0, sizeof (info));
+  INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
+  info.read_memory_func = sim_dis_read;
+  info.arch = bfd_get_arch (abfd);
+  info.mach = bfd_get_mach (abfd);
+  info.endian_code = BFD_ENDIAN_LITTLE;
+  if (info.mach == 0)
+    info.arch = bfd_arch_arm;
+  disassemble_init_for_target (& info);
+
   if (argv != NULL)
     {
       /* Set up the command line by laboriously stringing together
@@ -676,8 +734,6 @@ sim_fetch_register (sd, rn, memory, length)
   return length;
 }
 
-#ifdef SIM_TARGET_SWITCHES
-
 static void sim_target_parse_arg_array (char **);
 
 typedef struct
@@ -718,6 +774,34 @@ sim_target_parse_command_line (argc, argv)
       if ((ptr == NULL) || (* ptr != '-'))
 	break;
 
+      if (strcmp (ptr, "-t") == 0)
+	{
+	  trace = 1;
+	  continue;
+	}
+      
+      if (strcmp (ptr, "-z") == 0)
+	{
+	  /* Remove this option from the argv array.  */
+	  for (arg = i; arg < argc; arg ++)
+	    argv[arg] = argv[arg + 1];
+	  argc --;
+	  i --;
+	  trace_funcs = 1;
+	  continue;
+	}
+      
+      if (strcmp (ptr, "-d") == 0)
+	{
+	  /* Remove this option from the argv array.  */
+	  for (arg = i; arg < argc; arg ++)
+	    argv[arg] = argv[arg + 1];
+	  argc --;
+	  i --;
+	  disas = 1;
+	  continue;
+	}
+
       if (strncmp (ptr, SWI_SWITCH, sizeof SWI_SWITCH - 1) != 0)
 	continue;
 
@@ -789,8 +873,9 @@ sim_target_display_usage (help)
   fprintf (stream, "%s=<list>  Comma seperated list of SWI protocols to supoport.\n\
                 This list can contain: NONE, DEMON, ANGEL, REDBOOT and/or ALL.\n",
 	   SWI_SWITCH);
+  fprintf (stream, "-d\t\tEnable disassembly of instructions during tracing.\n");
+  fprintf (stream, "-z\t\tTrace entering and leaving functions.\n\n");
 }
-#endif
 
 SIM_DESC
 sim_open (kind, ptr, abfd, argv)
@@ -853,6 +938,21 @@ sim_open (kind, ptr, abfd, argv)
 		break;
 	      }
 	  }
+	else if (argv[i][0] == '-' && argv[i][1] == 't')
+	  {
+	    trace = 1;
+	    break;
+	  }
+	else if (argv[i][0] == '-' && argv[i][1] == 'z')
+	  {
+	    trace_funcs = 1;
+	    break;
+	  }
+	else if (argv[i][0] == '-' && argv[i][1] == 'd')
+	  {
+	    disas = 1;
+	    break;
+	  }
 	else if (argv[i][0] == '-' && argv[i][1] == 'm')
 	  {
 	    if (argv[i][2] != '\0')

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]