diff options
Diffstat (limited to 'sim/common/sim-trace.c')
-rw-r--r-- | sim/common/sim-trace.c | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/sim/common/sim-trace.c b/sim/common/sim-trace.c index 6c01e15..e299cf8 100644 --- a/sim/common/sim-trace.c +++ b/sim/common/sim-trace.c @@ -25,6 +25,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ #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, |