This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[patch] add trace capabilities to arm sim
- To: gdb-patches at sources dot redhat dot com
- Subject: [patch] add trace capabilities to arm sim
- From: DJ Delorie <dj at redhat dot com>
- Date: Fri, 23 Feb 2001 19:25:06 -0500
- CC: dj at redhat dot com
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");
}