From patchwork Thu Dec 31 04:32:25 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mike Frysinger X-Patchwork-Id: 10182 X-Patchwork-Delegate: vapier@gentoo.org Received: (qmail 96464 invoked by alias); 31 Dec 2015 04:32:42 -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 96428 invoked by uid 89); 31 Dec 2015 04:32:40 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 required=5.0 tests=AWL, BAYES_20, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 spammy=Trace, lowercase, 906, UD:dis-asm.h X-HELO: smtp.gentoo.org Received: from smtp.gentoo.org (HELO smtp.gentoo.org) (140.211.166.183) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 31 Dec 2015 04:32:38 +0000 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.gentoo.org (Postfix) with ESMTP id 109FC340873; Thu, 31 Dec 2015 04:32:35 +0000 (UTC) From: Mike Frysinger To: gdb-patches@sourceware.org Cc: nickc@redhat.com Subject: [PATCH 1/4] sim: trace: add support for disassembling Date: Wed, 30 Dec 2015 23:32:25 -0500 Message-Id: <1451536348-31380-2-git-send-email-vapier@gentoo.org> In-Reply-To: <1451536348-31380-1-git-send-email-vapier@gentoo.org> References: <1451536348-31380-1-git-send-email-vapier@gentoo.org> X-IsSubscribed: yes Some targets have started to add support for calling the disassembler automatically when executing code. Add support for that directly into the trace core. --- sim/common/sim-trace.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ sim/common/sim-trace.h | 40 +++++++++++++++++++++++++++++++- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/sim/common/sim-trace.c b/sim/common/sim-trace.c index e69c62d..66ff4ac 100644 --- a/sim/common/sim-trace.c +++ b/sim/common/sim-trace.c @@ -25,6 +25,8 @@ along with this program. If not, see . */ #include "bfd.h" #include "libiberty.h" +#include "dis-asm.h" + #include "sim-assert.h" #ifdef HAVE_STRING_H @@ -61,6 +63,7 @@ static DECLARE_OPTION_HANDLER (trace_option_handler); enum { OPTION_TRACE_INSN = OPTION_START, + OPTION_TRACE_DISASM, OPTION_TRACE_DECODE, OPTION_TRACE_EXTRACT, OPTION_TRACE_LINENUM, @@ -90,6 +93,9 @@ static const OPTION trace_options[] = { {"trace-insn", optional_argument, NULL, OPTION_TRACE_INSN}, '\0', "on|off", "Perform instruction tracing", trace_option_handler, NULL }, + { {"trace-disasm", optional_argument, NULL, OPTION_TRACE_DISASM}, + '\0', "on|off", "Disassemble instructions (slower, but more accurate)", + trace_option_handler, NULL }, { {"trace-decode", optional_argument, NULL, OPTION_TRACE_DECODE}, '\0', "on|off", "Trace instruction decoding", trace_option_handler, NULL }, @@ -249,6 +255,13 @@ trace_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-insn' ignored\n"); break; + case OPTION_TRACE_DISASM : + if (WITH_TRACE_DISASM_P) + return set_trace_option (sd, "-disasm", TRACE_DISASM_IDX, arg); + else + sim_io_eprintf (sd, "Instruction tracing not compiled in, `--trace-disasm' ignored\n"); + break; + case OPTION_TRACE_DECODE : if (WITH_TRACE_DECODE_P) return set_trace_option (sd, "-decode", TRACE_DECODE_IDX, arg); @@ -616,6 +629,7 @@ trace_idx_to_str (int trace_idx) { case TRACE_ALU_IDX: return "alu: "; case TRACE_INSN_IDX: return "insn: "; + case TRACE_DISASM_IDX: return "disasm: "; case TRACE_DECODE_IDX: return "decode: "; case TRACE_EXTRACT_IDX: return "extract: "; case TRACE_MEMORY_IDX: return "memory: "; @@ -837,6 +851,54 @@ trace_generic (SIM_DESC sd, trace_printf (sd, cpu, "\n"); } +static int +dis_read (bfd_vma memaddr, bfd_byte *myaddr, unsigned int length, + struct disassemble_info *dinfo) +{ + SIM_CPU *cpu = dinfo->application_data; + sim_core_read_buffer (CPU_STATE (cpu), cpu, NULL_CIA, myaddr, memaddr, length); + return 0; +} + +static int +dis_printf (SIM_CPU *cpu, const char *fmt, ...) +{ + SIM_DESC sd = CPU_STATE (cpu); + va_list ap; + va_start (ap, fmt); + trace_vprintf (sd, cpu, fmt, ap); + va_end (ap); + return 0; +} + +void +trace_disasm (SIM_DESC sd, sim_cpu *cpu, address_word addr) +{ + struct bfd *bfd = STATE_PROG_BFD (sd); + TRACE_DATA *trace_data = CPU_TRACE_DATA (cpu); + disassemble_info *info = &trace_data->dis_info; + + /* See if we need to set up the disassembly func. */ + if (trace_data->dis_bfd != bfd) + { + trace_data->dis_bfd = bfd; + trace_data->disassembler = disassembler (trace_data->dis_bfd); + INIT_DISASSEMBLE_INFO (*info, cpu, dis_printf); + info->read_memory_func = dis_read; + info->arch = bfd_get_arch (bfd); + info->mach = bfd_get_mach (bfd); + disassemble_init_for_target (info); + } + + info->application_data = cpu; + + trace_printf (sd, cpu, "%s %s", + trace_idx_to_str (TRACE_DISASM_IDX), + TRACE_PREFIX (trace_data)); + trace_data->disassembler (addr, info); + trace_printf (sd, cpu, "\n"); +} + void trace_input0 (SIM_DESC sd, sim_cpu *cpu, diff --git a/sim/common/sim-trace.h b/sim/common/sim-trace.h index 28fc351..87e0478 100644 --- a/sim/common/sim-trace.h +++ b/sim/common/sim-trace.h @@ -22,12 +22,20 @@ along with this program. If not, see . */ #ifndef SIM_TRACE_H #define SIM_TRACE_H +#include "dis-asm.h" + /* Standard traceable entities. */ enum { - /* Trace insn execution. */ + /* Trace insn execution. The port itself is responsible for displaying what + it thinks it is decoding. */ TRACE_INSN_IDX = 1, + /* Disassemble code addresses. Like insn tracing, but relies on the opcode + framework for displaying code. Can be slower, more accurate as to what + the binary code actually is, but not how the sim is decoding it. */ + TRACE_DISASM_IDX, + /* Trace insn decoding. ??? This is more of a simulator debugging operation and might best be moved to --debug-decode. */ @@ -97,6 +105,7 @@ enum { The case choice here is on purpose. The lowercase parts are args to --with-trace. */ #define TRACE_insn (1 << TRACE_INSN_IDX) +#define TRACE_disasm (1 << TRACE_DISASM_IDX) #define TRACE_decode (1 << TRACE_DECODE_IDX) #define TRACE_extract (1 << TRACE_EXTRACT_IDX) #define TRACE_linenum (1 << TRACE_LINENUM_IDX) @@ -118,6 +127,7 @@ enum { /* Preprocessor macros to simplify tests of WITH_TRACE. */ #define WITH_TRACE_ANY_P (WITH_TRACE) #define WITH_TRACE_INSN_P WITH_TRACE_P (TRACE_INSN_IDX) +#define WITH_TRACE_DISASM_P WITH_TRACE_P (TRACE_DISASM_IDX) #define WITH_TRACE_DECODE_P WITH_TRACE_P (TRACE_DECODE_IDX) #define WITH_TRACE_EXTRACT_P WITH_TRACE_P (TRACE_EXTRACT_IDX) #define WITH_TRACE_LINENUM_P WITH_TRACE_P (TRACE_LINENUM_IDX) @@ -190,6 +200,19 @@ typedef struct _trace_data { ??? Not all cpu's support this. */ ADDR_RANGE range; #define TRACE_RANGE(t) (& (t)->range) + + /* The bfd used to disassemble code. Should compare against STATE_PROG_BFD + before using the disassembler helper. + Meant for use by the internal trace module only. */ + struct bfd *dis_bfd; + + /* The function used to actually disassemble code. + Meant for use by the internal trace module only. */ + disassembler_ftype disassembler; + + /* State used with the disassemble function. + Meant for use by the internal trace module only. */ + disassemble_info dis_info; } TRACE_DATA; /* System tracing support. */ @@ -204,6 +227,7 @@ typedef struct _trace_data { /* Non-zero if --trace- was specified for SD. */ #define STRACE_ANY_P(sd) (WITH_TRACE_ANY_P && (STATE_TRACE_DATA (sd)->trace_any_p)) #define STRACE_INSN_P(sd) STRACE_P (sd, TRACE_INSN_IDX) +#define STRACE_DISASM_P(sd) STRACE_P (sd, TRACE_DISASM_IDX) #define STRACE_DECODE_P(sd) STRACE_P (sd, TRACE_DECODE_IDX) #define STRACE_EXTRACT_P(sd) STRACE_P (sd, TRACE_EXTRACT_IDX) #define STRACE_LINENUM_P(sd) STRACE_P (sd, TRACE_LINENUM_IDX) @@ -226,6 +250,7 @@ typedef struct _trace_data { trace_generic (sd, NULL, idx, fmt, ## args); \ } while (0) #define STRACE_INSN(sd, fmt, args...) STRACE (sd, TRACE_INSN_IDX, fmt, ## args) +#define STRACE_DISASM(sd, fmt, args...) STRACE (sd, TRACE_DISASM_IDX, fmt, ## args) #define STRACE_DECODE(sd, fmt, args...) STRACE (sd, TRACE_DECODE_IDX, fmt, ## args) #define STRACE_EXTRACT(sd, fmt, args...) STRACE (sd, TRACE_EXTRACT_IDX, fmt, ## args) #define STRACE_LINENUM(sd, fmt, args...) STRACE (sd, TRACE_LINENUM_IDX, fmt, ## args) @@ -252,6 +277,7 @@ typedef struct _trace_data { /* Non-zero if --trace- was specified for CPU. */ #define TRACE_ANY_P(cpu) (WITH_TRACE_ANY_P && (CPU_TRACE_DATA (cpu)->trace_any_p)) #define TRACE_INSN_P(cpu) TRACE_P (cpu, TRACE_INSN_IDX) +#define TRACE_DISASM_P(cpu) TRACE_P (cpu, TRACE_DISASM_IDX) #define TRACE_DECODE_P(cpu) TRACE_P (cpu, TRACE_DECODE_IDX) #define TRACE_EXTRACT_P(cpu) TRACE_P (cpu, TRACE_EXTRACT_IDX) #define TRACE_LINENUM_P(cpu) TRACE_P (cpu, TRACE_LINENUM_IDX) @@ -266,6 +292,7 @@ typedef struct _trace_data { #define TRACE_SYSCALL_P(cpu) TRACE_P (cpu, TRACE_SYSCALL_IDX) #define TRACE_REGISTER_P(cpu) TRACE_P (cpu, TRACE_REGISTER_IDX) #define TRACE_DEBUG_P(cpu) TRACE_P (cpu, TRACE_DEBUG_IDX) +#define TRACE_DISASM_P(cpu) TRACE_P (cpu, TRACE_DISASM_IDX) /* Helper functions for printing messages. */ #define TRACE(cpu, idx, fmt, args...) \ @@ -288,6 +315,11 @@ typedef struct _trace_data { #define TRACE_SYSCALL(cpu, fmt, args...) TRACE (cpu, TRACE_SYSCALL_IDX, fmt, ## args) #define TRACE_REGISTER(cpu, fmt, args...) TRACE (cpu, TRACE_REGISTER_IDX, fmt, ## args) #define TRACE_DEBUG(cpu, fmt, args...) TRACE (cpu, TRACE_DEBUG_IDX, fmt, ## args) +#define TRACE_DISASM(cpu, addr) \ + do { \ + if (TRACE_DISASM_P (cpu)) \ + trace_disasm (CPU_STATE (cpu), cpu, addr); \ + } while (0) /* Tracing functions. */ @@ -313,6 +345,12 @@ extern void trace_generic (SIM_DESC sd, ...) __attribute__((format (printf, 4, 5))); +/* Disassemble the specified address. */ + +extern void trace_disasm (SIM_DESC sd, + sim_cpu *cpu, + address_word addr); + typedef enum { trace_fmt_invalid, trace_fmt_word,