This is the mail archive of the gdb-patches@sources.redhat.com 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]

[patch] add trace capabilities to arm sim



And fix a harmless bug, too.

2001-02-23  DJ Delorie  <dj@redhat.com>

	* armemu.c (ARMul_Emulate): Add hook for tracing.
	* wrapper.c (current_bfd): New, remembers which bfd we're
	simulating.
	(sim_dis_read): New, helper for tracing.
	(remove_useless_symbols): New, helper for tracing.  From objdump.
	(compare_symbols): Ditto.
	(sim_trace_one_arm_insn): New, trace one instruction using
	disassembler.
	(sim_trace): Make it do something useful now.
	(sim_create_inferior): Save current bfd.
	(sim_open): Ditto.
	(sim_load): Ditto.
	(sim_do_command): Handle the `trace' command.

	* wrapper.c (ARMul_Debug): Return insn just in case we're called.

Index: armemu.c
===================================================================
RCS file: /cvs/src/src/sim/arm/armemu.c,v
retrieving revision 1.21
diff -p -3 -r1.21 armemu.c
*** armemu.c	2001/02/16 22:04:22	1.21
--- armemu.c	2001/02/24 00:24:39
*************** ARMul_Emulate26 (register ARMul_State * 
*** 377,382 ****
--- 377,383 ----
        if (instr == 0)
  	abort ();
  #endif
+       sim_trace_one_arm_insn (pc, instr);
  
        if (state->Exception)
  	{			/* Any exceptions */
Index: wrapper.c
===================================================================
RCS file: /cvs/src/src/sim/arm/wrapper.c,v
retrieving revision 1.12
diff -p -3 -r1.12 wrapper.c
*** wrapper.c	2001/02/14 22:21:20	1.12
--- wrapper.c	2001/02/24 00:24:40
***************
*** 1,5 ****
  /* run front end support for arm
!    Copyright (C) 1995, 1996, 1997, 2000 Free Software Foundation, Inc.
  
  This file is part of ARM SIM.
  
--- 1,5 ----
  /* run front end support for arm
!    Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
  
  This file is part of ARM SIM.
  
*************** Foundation, Inc., 59 Temple Place - Suit
*** 32,40 ****
--- 32,43 ----
  #include "armemu.h"
  #include "dbg_rdi.h"
  #include "ansidecl.h"
+ #include "dis-asm.h"
  
  host_callback *sim_callback;
  
+ static bfd *current_bfd;
+ 
  static struct ARMul_State *state;
  
  /* Who is using the simulator.  */
*************** ARMul_ConsolePrint (ARMul_State * state,
*** 109,117 ****
  }
  
  ARMword
! ARMul_Debug (ARMul_State * state ATTRIBUTE_UNUSED, ARMword pc ATTRIBUTE_UNUSED, ARMword instr ATTRIBUTE_UNUSED)
  {
!   return 0;
  }
  
  int
--- 112,120 ----
  }
  
  ARMword
! ARMul_Debug (ARMul_State * state ATTRIBUTE_UNUSED, ARMword pc ATTRIBUTE_UNUSED, ARMword instr)
  {
!   return instr;
  }
  
  int
*************** sim_read (sd, addr, buffer, size)
*** 147,158 ****
    return size;
  }
  
  int
  sim_trace (sd)
       SIM_DESC sd ATTRIBUTE_UNUSED;
! {  
!   (*sim_callback->printf_filtered) (sim_callback,
! 				    "This simulator does not support tracing\n");
    return 1;
  }
  
--- 150,306 ----
    return size;
  }
  
+ static int do_tracing = 0;
+ 
+ static int
+ sim_dis_read (memaddr, ptr, length, info)
+      bfd_vma memaddr;
+      bfd_byte *ptr;
+      unsigned int length;
+      struct disassemble_info *info;
+ {
+   sim_read (0, memaddr, ptr, length);
+   return 0;
+ }
+ 
+ /* Filter out (in place) symbols that are useless for disassembly.
+    COUNT is the number of elements in SYMBOLS.
+    Return the number of useful symbols. */
+ 
+ static long
+ remove_useless_symbols (symbols, count)
+      asymbol **symbols;
+      long count;
+ {
+   register asymbol **in_ptr = symbols, **out_ptr = symbols;
+ 
+   while (--count >= 0)
+     {
+       asymbol *sym = *in_ptr++;
+ 
+       if (strstr(sym->name, "gcc2_compiled"))
+ 	continue;
+       if (sym->name == NULL || sym->name[0] == '\0')
+ 	continue;
+       if (sym->flags & (BSF_DEBUGGING))
+ 	continue;
+       if (bfd_is_und_section (sym->section)
+ 	  || bfd_is_com_section (sym->section))
+ 	continue;
+ 
+       *out_ptr++ = sym;
+     }
+   return out_ptr - symbols;
+ }
+ 
+ static int 
+ compare_symbols (ap, bp)
+      const PTR ap;
+      const PTR bp;
+ {
+   const asymbol *a = *(const asymbol **)ap;
+   const asymbol *b = *(const asymbol **)bp;
+ 
+   if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
+     return 1;
+   else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
+     return -1;
+   return 0;
+ }
+ 
+ void
+ sim_trace_one_arm_insn(pc, insn)
+ 	      int pc;
+ 	      unsigned int insn;
+ {
+   static int initted = 0;
+   static asymbol **symtab = 0;
+   static int symcount = 0;
+   static int last_sym = -1;
+   static struct disassemble_info info;
+   int storage, sym, bestsym, bestaddr;
+   int min, max, i, pnl;
+   static ARMword prevregs[16];
+ 
+   if (insn == 0)
+     {
+       state->Emulate = STOP;
+       return;
+     }
+   if (current_bfd == 0)
+     return;
+   if (!do_tracing)
+     return;
+ 
+   if (!initted)
+     {
+       initted = 1;
+       memset(prevregs, 0, sizeof(prevregs));
+       memset(&info, 0, sizeof(info));
+       INIT_DISASSEMBLE_INFO(info, stdout, fprintf);
+       info.read_memory_func = sim_dis_read;
+ 
+       storage = bfd_get_symtab_upper_bound (current_bfd);
+       if (storage > 0)
+ 	{
+ 	  symtab = (asymbol **) xmalloc (storage);
+ 	  symcount = bfd_canonicalize_symtab (current_bfd, symtab);
+ 	  symcount = remove_useless_symbols (symtab, symcount);
+ 	  qsort (symtab, symcount, sizeof(asymbol *), compare_symbols);
+ 	}
+     }
+ 
+   min = -1; max = symcount;
+   while (min < max-1) {
+     bfd_vma sa;
+     sym = (min+max)/2;
+     sa = bfd_asymbol_value (symtab[sym]);
+     if (sa > pc)
+       max = sym;
+     else if (sa < pc)
+       min = sym;
+     else
+       {
+ 	min = sym;
+ 	break;
+       }
+   }
+   bestaddr = bfd_asymbol_value (symtab[min]);
+   if (min != -1 && min != last_sym)
+     {
+       printf("%s", bfd_asymbol_name (symtab[min]));
+       if (bestaddr != pc)
+ 	printf("+%d", pc-bestaddr);
+       printf(":\n");
+       last_sym = min;
+     }
+   printf("%8x:  %08x\t", pc, insn);
+   if (bfd_big_endian (current_bfd))
+     print_insn_big_arm(pc, &info);
+   else
+     print_insn_little_arm(pc, &info);
+ 
+   pnl = 0;
+   for (i=0; i<15; i++)
+     if (prevregs[i] != state->Reg[i])
+       {
+ 	if (pnl == 0)
+ 	  printf("\t");
+ 	prevregs[i] = state->Reg[i];
+ 	printf(" r%d=%08x", i, state->Reg[i]);
+ 	pnl = 1;
+       }
+ 
+   printf("\n");
+ }
+ 
  int
  sim_trace (sd)
       SIM_DESC sd ATTRIBUTE_UNUSED;
! {
!   do_tracing = 1;
!   sim_resume(sd, 0, 0);
!   do_tracing = 0;
    return 1;
  }
  
*************** sim_create_inferior (sd, abfd, argv, env
*** 207,212 ****
--- 355,361 ----
    else
      ARMul_SetPC (state, 0);	/* ??? */
  
+   current_bfd = abfd;
    mach = bfd_get_mach (abfd);
  
    switch (mach)
*************** sim_open (kind, ptr, abfd, argv)
*** 411,416 ****
--- 560,567 ----
    myname = (char *) xstrdup (argv[0]);
    sim_callback = ptr;
  
+   current_bfd = abfd;
+ 
    /* Decide upon the endian-ness of the processor.
       If we can, get the information from the bfd itself.
       Otherwise look to see if we have been given a command
*************** sim_load (sd, prog, abfd, from_tty)
*** 480,485 ****
--- 631,638 ----
    extern bfd *sim_load_file ();	/* ??? Don't know where this should live.  */
    bfd *prog_bfd;
  
+   current_bfd = abfd;
+ 
    prog_bfd = sim_load_file (sd, myname, sim_callback, prog, abfd,
  			    sim_kind == SIM_OPEN_DEBUG, 0, sim_write);
    if (prog_bfd == NULL)
*************** void
*** 520,528 ****
  sim_do_command (sd, cmd)
       SIM_DESC sd ATTRIBUTE_UNUSED;
       char *cmd ATTRIBUTE_UNUSED;
! {  
!   (*sim_callback->printf_filtered) (sim_callback,
! 				    "This simulator does not accept any commands.\n");
  }
  
  
--- 673,692 ----
  sim_do_command (sd, cmd)
       SIM_DESC sd ATTRIBUTE_UNUSED;
       char *cmd ATTRIBUTE_UNUSED;
! {
!   if (strcmp(cmd, "trace") == 0)
!     {
!       do_tracing = !do_tracing;
!       if (do_tracing)
! 	(*sim_callback->printf_filtered) (sim_callback,
! 					  "Tracing on.\n");
!       else
! 	(*sim_callback->printf_filtered) (sim_callback,
! 					  "Tracing off.\n");
!     }
!   else
! 	(*sim_callback->printf_filtered) (sim_callback,
! 					  "Unknown command, only `trace' allowed.\n");
  }
  
  


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