From patchwork Fri Mar 14 15:20:57 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nick Clifton X-Patchwork-Id: 89 Return-Path: X-Original-To: siddhesh@wilcox.dreamhost.com Delivered-To: siddhesh@wilcox.dreamhost.com Received: from homiemail-mx20.g.dreamhost.com (caibbdcaaahc.dreamhost.com [208.113.200.72]) by wilcox.dreamhost.com (Postfix) with ESMTP id 9EE6D3600C0 for ; Fri, 14 Mar 2014 08:21:18 -0700 (PDT) Received: by homiemail-mx20.g.dreamhost.com (Postfix, from userid 14314964) id 4CE0040DDDA0B; Fri, 14 Mar 2014 08:21:18 -0700 (PDT) X-Original-To: gdb@patchwork.siddhesh.in Delivered-To: x14314964@homiemail-mx20.g.dreamhost.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by homiemail-mx20.g.dreamhost.com (Postfix) with ESMTPS id 01C4D408400A1 for ; Fri, 14 Mar 2014 08:21:17 -0700 (PDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; q=dns; s=default; b=fuv4Y5FN5lEevuHzdzhnYoC/hboC+ OW95ym9Qsh7lhHIutALdD+6Y/qtJhFp3yZc4Q6A0f94xdfNOjh1JEcYd6NUd+fAb DXtK09rQSXyaE7XGAWd1KSw95zM+E5v1fabxZvFOH4+g4fpuZNcfyUJSSzmQLmul 3i3GZWLM4bml54= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:subject:date:message-id:mime-version :content-type; s=default; bh=ulLigzlNZDtkL8dzHgBW+34C/rU=; b=qjx WFPGFd0I+GwscuaFig8uOBJs7WBs+48lp9VDgFPerCJoTbS6+Vr5uoYYpawOHepn Z08RK5B3E1vdz5qMTsiBWMWsTxJKigq1UKxzlwy/x4YOlxzkrNALW6shNQNUg1Bu W95ICSfUuxIpPoxs5htbT3YBLs37y97B/+3D6WTs= Received: (qmail 29862 invoked by alias); 14 Mar 2014 15:21:08 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 29796 invoked by uid 89); 14 Mar 2014 15:21:08 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL, BAYES_00, SPF_HELO_PASS, SPF_PASS, T_FILL_THIS_FORM_SHORT, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 14 Mar 2014 15:21:04 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s2EFL2f3012962 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 14 Mar 2014 11:21:02 -0400 Received: from littlehelper.redhat.com (vpn1-7-166.ams2.redhat.com [10.36.7.166]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s2EFKwvP007212 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO) for ; Fri, 14 Mar 2014 11:21:00 -0400 From: Nick Clifton To: gdb-patches@sourceware.org Subject: Commit: ARM SIM: Add tracing support. Date: Fri, 14 Mar 2014 15:20:57 +0000 Message-ID: <87vbvg7qna.fsf@redhat.com> MIME-Version: 1.0 X-DH-Original-To: gdb@patchwork.siddhesh.in 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 * 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 . */ 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= 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')