1 /* Simulator tracing/debugging support.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23 #include "sim-options.h"
35 #define SIZE_LOCATION 20
42 #ifndef SIZE_LINE_NUMBER
43 #define SIZE_LINE_NUMBER 4
46 static MODULE_UNINSTALL_FN trace_uninstall
;
48 static DECLARE_OPTION_HANDLER (trace_option_handler
);
50 #define OPTION_TRACE_INSN (OPTION_START + 0)
51 #define OPTION_TRACE_DECODE (OPTION_START + 1)
52 #define OPTION_TRACE_EXTRACT (OPTION_START + 2)
53 #define OPTION_TRACE_LINENUM (OPTION_START + 3)
54 #define OPTION_TRACE_MEMORY (OPTION_START + 4)
55 #define OPTION_TRACE_MODEL (OPTION_START + 5)
56 #define OPTION_TRACE_ALU (OPTION_START + 6)
57 #define OPTION_TRACE_CORE (OPTION_START + 7)
58 #define OPTION_TRACE_EVENTS (OPTION_START + 8)
59 #define OPTION_TRACE_FPU (OPTION_START + 9)
60 #define OPTION_TRACE_FILE (OPTION_START + 10)
62 static const OPTION trace_options
[] =
64 { {"trace", no_argument
, NULL
, 't'},
65 't', NULL
, "Perform tracing",
66 trace_option_handler
},
67 { {"trace-insn", no_argument
, NULL
, OPTION_TRACE_INSN
},
68 '\0', NULL
, "Perform instruction tracing",
69 trace_option_handler
},
70 { {"trace-decode", no_argument
, NULL
, OPTION_TRACE_DECODE
},
71 '\0', NULL
, "Perform instruction decoding tracing",
72 trace_option_handler
},
73 { {"trace-extract", no_argument
, NULL
, OPTION_TRACE_EXTRACT
},
74 '\0', NULL
, "Perform instruction extraction tracing",
75 trace_option_handler
},
76 { {"trace-linenum", no_argument
, NULL
, OPTION_TRACE_LINENUM
},
77 '\0', NULL
, "Perform line number tracing (implies --trace-insn)",
78 trace_option_handler
},
79 { {"trace-memory", no_argument
, NULL
, OPTION_TRACE_MEMORY
},
80 '\0', NULL
, "Perform memory tracing",
81 trace_option_handler
},
82 { {"trace-model", no_argument
, NULL
, OPTION_TRACE_MODEL
},
83 '\0', NULL
, "Perform model tracing",
84 trace_option_handler
},
85 { {"trace-alu", no_argument
, NULL
, OPTION_TRACE_ALU
},
86 '\0', NULL
, "Perform ALU tracing",
87 trace_option_handler
},
88 { {"trace-core", no_argument
, NULL
, OPTION_TRACE_CORE
},
89 '\0', NULL
, "Perform CORE tracing",
90 trace_option_handler
},
91 { {"trace-events", no_argument
, NULL
, OPTION_TRACE_EVENTS
},
92 '\0', NULL
, "Perform EVENTS tracing",
93 trace_option_handler
},
94 { {"trace-fpu", no_argument
, NULL
, OPTION_TRACE_FPU
},
95 '\0', NULL
, "Perform FPU tracing",
96 trace_option_handler
},
97 { {"trace-file", required_argument
, NULL
, OPTION_TRACE_FILE
},
98 '\0', "FILE NAME", "Specify tracing output file",
99 trace_option_handler
},
100 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
104 trace_option_handler (sd
, opt
, arg
)
115 sim_io_eprintf (sd
, "Tracing not compiled in, `-t' ignored\n");
118 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
119 for (i
= 0; i
< MAX_TRACE_VALUES
; ++i
)
120 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
121 STATE_CORE(sd
)->trace
= 1;
122 STATE_EVENTS(sd
)->trace
= 1;
126 case OPTION_TRACE_INSN
:
127 if (WITH_TRACE_INSN_P
)
128 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
129 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_INSN_IDX
] = 1;
131 sim_io_eprintf (sd
, "Instruction tracing not compiled in, `--trace-insn' ignored\n");
134 case OPTION_TRACE_DECODE
:
135 if (WITH_TRACE_DECODE_P
)
136 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
137 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_DECODE_IDX
] = 1;
139 sim_io_eprintf (sd
, "Decode tracing not compiled in, `--trace-decode' ignored\n");
142 case OPTION_TRACE_EXTRACT
:
143 if (WITH_TRACE_EXTRACT_P
)
144 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
145 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_EXTRACT_IDX
] = 1;
147 sim_io_eprintf (sd
, "Extract tracing not compiled in, `--trace-extract' ignored\n");
150 case OPTION_TRACE_LINENUM
:
151 if (WITH_TRACE_LINENUM_P
&& WITH_TRACE_INSN_P
)
152 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
154 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_LINENUM_IDX
] = 1;
155 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_INSN_IDX
] = 1;
158 sim_io_eprintf (sd
, "Line number or instruction tracing not compiled in, `--trace-linenum' ignored\n");
161 case OPTION_TRACE_MEMORY
:
162 if (WITH_TRACE_MEMORY_P
)
163 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
164 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MEMORY_IDX
] = 1;
166 sim_io_eprintf (sd
, "Memory tracing not compiled in, `--trace-memory' ignored\n");
169 case OPTION_TRACE_MODEL
:
170 if (WITH_TRACE_MODEL_P
)
171 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
172 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MODEL_IDX
] = 1;
174 sim_io_eprintf (sd
, "Model tracing not compiled in, `--trace-model' ignored\n");
177 case OPTION_TRACE_ALU
:
178 if (WITH_TRACE_ALU_P
)
179 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
180 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_ALU_IDX
] = 1;
182 sim_io_eprintf (sd
, "ALU tracing not compiled in, `--trace-alu' ignored\n");
185 case OPTION_TRACE_CORE
:
186 if (WITH_TRACE_CORE_P
)
188 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
189 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_CORE_IDX
] = 1;
190 STATE_CORE(sd
)->trace
= 1;
193 sim_io_eprintf (sd
, "CORE tracing not compiled in, `--trace-core' ignored\n");
196 case OPTION_TRACE_EVENTS
:
197 if (WITH_TRACE_EVENTS_P
)
199 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
200 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_EVENTS_IDX
] = 1;
201 STATE_EVENTS(sd
)->trace
= 1;
204 sim_io_eprintf (sd
, "EVENTS tracing not compiled in, `--trace-events' ignored\n");
207 case OPTION_TRACE_FPU
:
208 if (WITH_TRACE_FPU_P
)
209 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
210 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_FPU_IDX
] = 1;
212 sim_io_eprintf (sd
, "FPU tracing not compiled in, `--trace-fpu' ignored\n");
215 case OPTION_TRACE_FILE
:
217 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-file' ignored\n");
220 FILE *f
= fopen (arg
, "w");
224 sim_io_eprintf (sd
, "Unable to open trace output file `%s'\n", arg
);
227 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
228 TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd
, n
))) = f
;
236 /* Install tracing support. */
239 trace_install (SIM_DESC sd
)
243 sim_add_option_table (sd
, trace_options
);
244 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
245 memset (CPU_TRACE_DATA (STATE_CPU (sd
, i
)), 0,
246 sizeof (* CPU_TRACE_DATA (STATE_CPU (sd
, i
))));
247 sim_module_add_uninstall_fn (sd
, trace_uninstall
);
252 trace_uninstall (SIM_DESC sd
)
256 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
258 TRACE_DATA
*data
= CPU_TRACE_DATA (STATE_CPU (sd
, i
));
259 if (TRACE_FILE (data
) != NULL
)
260 fclose (TRACE_FILE (data
));
265 trace_one_insn (SIM_DESC sd
, sim_cpu
*cpu
, const char *filename
,
266 int linenum
, int idecode
, address_word pc
, const char *name
)
269 trace_printf(sd
, cpu
, "%s:%-*d 0x%.*lx (decode) %s\n",
271 SIZE_LINE_NUMBER
, linenum
,
275 else if (!TRACE_LINENUM_P (cpu
))
276 trace_printf(sd
, cpu
, "%s:%-*d 0x%.*lx %s\n",
278 SIZE_LINE_NUMBER
, linenum
,
287 if (STATE_TEXT_SECTION (CPU_STATE (cpu
))
288 && pc
>= STATE_TEXT_START (CPU_STATE (cpu
))
289 && pc
< STATE_TEXT_END (CPU_STATE (cpu
)))
291 const char *pc_filename
= (const char *)0;
292 const char *pc_function
= (const char *)0;
293 unsigned int pc_linenum
= 0;
295 if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu
)),
296 STATE_TEXT_SECTION (CPU_STATE (cpu
)),
297 (struct symbol_cache_entry
**) 0,
298 pc
- STATE_TEXT_START (CPU_STATE (cpu
)),
299 &pc_filename
, &pc_function
, &pc_linenum
))
304 sprintf (p
, "#%-*d ", SIZE_LINE_NUMBER
, pc_linenum
);
309 sprintf (p
, "%-*s ", SIZE_LINE_NUMBER
+1, "---");
310 p
+= SIZE_LINE_NUMBER
+2;
315 sprintf (p
, "%s ", pc_function
);
320 char *q
= (char *) strrchr (filename
, '/');
321 sprintf (p
, "%s ", (q
) ? q
+1 : filename
);
330 trace_printf (sd
, cpu
, "0x%.*x %-*.*s %s\n",
331 SIZE_PC
, (unsigned) pc
,
332 SIZE_LOCATION
, SIZE_LOCATION
, buf
,
338 trace_printf
VPARAMS ((SIM_DESC sd
, sim_cpu
*cpu
, const char *fmt
, ...))
349 sd
= va_arg (ap
, SIM_DESC
);
350 cpu
= va_arg (ap
, sim_cpu
*);
351 fmt
= va_arg (ap
, const char *);
354 if (cpu
!= NULL
&& TRACE_FILE (CPU_TRACE_DATA (cpu
)) != NULL
)
355 vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu
)), fmt
, ap
);
357 sim_io_evprintf (sd
, fmt
, ap
);
363 debug_printf
VPARAMS ((sim_cpu
*cpu
, const char *fmt
, ...))
373 cpu
= va_arg (ap
, sim_cpu
*);
374 fmt
= va_arg (ap
, const char *);
377 if (CPU_DEBUG_FILE (cpu
) == NULL
)
378 (* STATE_CALLBACK (CPU_STATE (cpu
))->evprintf_filtered
)
379 (STATE_CALLBACK (CPU_STATE (cpu
)), fmt
, ap
);
381 vfprintf (CPU_DEBUG_FILE (cpu
), fmt
, ap
);