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"
39 #define SIZE_LOCATION 20
46 #ifndef SIZE_LINE_NUMBER
47 #define SIZE_LINE_NUMBER 4
50 static MODULE_UNINSTALL_FN trace_uninstall
;
52 static DECLARE_OPTION_HANDLER (trace_option_handler
);
55 OPTION_TRACE_INSN
= OPTION_START
,
66 OPTION_TRACE_SEMANTICS
,
70 static const OPTION trace_options
[] =
72 { {"trace", no_argument
, NULL
, 't'},
73 't', NULL
, "Perform tracing",
74 trace_option_handler
},
75 { {"trace-insn", no_argument
, NULL
, OPTION_TRACE_INSN
},
76 '\0', NULL
, "Perform instruction tracing",
77 trace_option_handler
},
78 { {"trace-decode", no_argument
, NULL
, OPTION_TRACE_DECODE
},
79 '\0', NULL
, "Perform instruction decoding tracing",
80 trace_option_handler
},
81 { {"trace-extract", no_argument
, NULL
, OPTION_TRACE_EXTRACT
},
82 '\0', NULL
, "Perform instruction extraction tracing",
83 trace_option_handler
},
84 { {"trace-linenum", no_argument
, NULL
, OPTION_TRACE_LINENUM
},
85 '\0', NULL
, "Perform line number tracing (implies --trace-insn)",
86 trace_option_handler
},
87 { {"trace-memory", no_argument
, NULL
, OPTION_TRACE_MEMORY
},
88 '\0', NULL
, "Perform memory tracing",
89 trace_option_handler
},
90 { {"trace-model", no_argument
, NULL
, OPTION_TRACE_MODEL
},
91 '\0', NULL
, "Perform model tracing",
92 trace_option_handler
},
93 { {"trace-alu", no_argument
, NULL
, OPTION_TRACE_ALU
},
94 '\0', NULL
, "Perform ALU tracing",
95 trace_option_handler
},
96 { {"trace-core", no_argument
, NULL
, OPTION_TRACE_CORE
},
97 '\0', NULL
, "Perform CORE tracing",
98 trace_option_handler
},
99 { {"trace-events", no_argument
, NULL
, OPTION_TRACE_EVENTS
},
100 '\0', NULL
, "Perform EVENTS tracing",
101 trace_option_handler
},
102 { {"trace-fpu", no_argument
, NULL
, OPTION_TRACE_FPU
},
103 '\0', NULL
, "Perform FPU tracing",
104 trace_option_handler
},
105 { {"trace-branch", no_argument
, NULL
, OPTION_TRACE_BRANCH
},
106 '\0', NULL
, "Perform branch tracing",
107 trace_option_handler
},
108 { {"trace-semantics", no_argument
, NULL
, OPTION_TRACE_SEMANTICS
},
109 '\0', NULL
, "Perform ALU, FPU, and MEMORY tracing",
110 trace_option_handler
},
111 { {"trace-file", required_argument
, NULL
, OPTION_TRACE_FILE
},
112 '\0', "FILE NAME", "Specify tracing output file",
113 trace_option_handler
},
114 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
118 trace_option_handler (sd
, opt
, arg
)
129 sim_io_eprintf (sd
, "Tracing not compiled in, `-t' ignored\n");
132 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
133 for (i
= 0; i
< MAX_TRACE_VALUES
; ++i
)
134 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
135 STATE_CORE(sd
)->trace
= 1;
136 STATE_EVENTS(sd
)->trace
= 1;
140 case OPTION_TRACE_INSN
:
141 if (WITH_TRACE_INSN_P
)
142 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
143 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_INSN_IDX
] = 1;
145 sim_io_eprintf (sd
, "Instruction tracing not compiled in, `--trace-insn' ignored\n");
148 case OPTION_TRACE_DECODE
:
149 if (WITH_TRACE_DECODE_P
)
150 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
151 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_DECODE_IDX
] = 1;
153 sim_io_eprintf (sd
, "Decode tracing not compiled in, `--trace-decode' ignored\n");
156 case OPTION_TRACE_EXTRACT
:
157 if (WITH_TRACE_EXTRACT_P
)
158 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
159 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_EXTRACT_IDX
] = 1;
161 sim_io_eprintf (sd
, "Extract tracing not compiled in, `--trace-extract' ignored\n");
164 case OPTION_TRACE_LINENUM
:
165 if (WITH_TRACE_LINENUM_P
&& WITH_TRACE_INSN_P
)
166 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
168 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_LINENUM_IDX
] = 1;
169 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_INSN_IDX
] = 1;
172 sim_io_eprintf (sd
, "Line number or instruction tracing not compiled in, `--trace-linenum' ignored\n");
175 case OPTION_TRACE_MEMORY
:
176 if (WITH_TRACE_MEMORY_P
)
177 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
178 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MEMORY_IDX
] = 1;
180 sim_io_eprintf (sd
, "Memory tracing not compiled in, `--trace-memory' ignored\n");
183 case OPTION_TRACE_MODEL
:
184 if (WITH_TRACE_MODEL_P
)
185 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
186 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MODEL_IDX
] = 1;
188 sim_io_eprintf (sd
, "Model tracing not compiled in, `--trace-model' ignored\n");
191 case OPTION_TRACE_ALU
:
192 if (WITH_TRACE_ALU_P
)
193 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
194 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_ALU_IDX
] = 1;
196 sim_io_eprintf (sd
, "ALU tracing not compiled in, `--trace-alu' ignored\n");
199 case OPTION_TRACE_CORE
:
200 if (WITH_TRACE_CORE_P
)
202 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
203 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_CORE_IDX
] = 1;
204 STATE_CORE(sd
)->trace
= 1;
207 sim_io_eprintf (sd
, "CORE tracing not compiled in, `--trace-core' ignored\n");
210 case OPTION_TRACE_EVENTS
:
211 if (WITH_TRACE_EVENTS_P
)
213 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
214 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_EVENTS_IDX
] = 1;
215 STATE_EVENTS(sd
)->trace
= 1;
218 sim_io_eprintf (sd
, "EVENTS tracing not compiled in, `--trace-events' ignored\n");
221 case OPTION_TRACE_FPU
:
222 if (WITH_TRACE_FPU_P
)
223 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
224 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_FPU_IDX
] = 1;
226 sim_io_eprintf (sd
, "FPU tracing not compiled in, `--trace-fpu' ignored\n");
229 case OPTION_TRACE_BRANCH
:
230 if (WITH_TRACE_BRANCH_P
)
231 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
232 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_FPU_IDX
] = 1;
234 sim_io_eprintf (sd
, "Branch tracing not compiled in, `--trace-branch' ignored\n");
237 case OPTION_TRACE_SEMANTICS
:
238 if (WITH_TRACE_ALU_P
&& WITH_TRACE_FPU_P
&& WITH_TRACE_MEMORY_P
)
239 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
241 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_ALU_IDX
] = 1;
242 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_FPU_IDX
] = 1;
243 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MEMORY_IDX
] = 1;
244 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_BRANCH_IDX
] = 1;
247 sim_io_eprintf (sd
, "Alu, fpu, and/or memory tracing not compiled in, `--trace-semantics' ignored\n");
250 case OPTION_TRACE_FILE
:
252 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-file' ignored\n");
255 FILE *f
= fopen (arg
, "w");
259 sim_io_eprintf (sd
, "Unable to open trace output file `%s'\n", arg
);
262 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
263 TRACE_FILE (CPU_TRACE_DATA (STATE_CPU (sd
, n
))) = f
;
271 /* Install tracing support. */
274 trace_install (SIM_DESC sd
)
278 sim_add_option_table (sd
, trace_options
);
279 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
280 memset (CPU_TRACE_DATA (STATE_CPU (sd
, i
)), 0,
281 sizeof (* CPU_TRACE_DATA (STATE_CPU (sd
, i
))));
282 sim_module_add_uninstall_fn (sd
, trace_uninstall
);
287 trace_uninstall (SIM_DESC sd
)
291 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
293 TRACE_DATA
*data
= CPU_TRACE_DATA (STATE_CPU (sd
, i
));
294 if (TRACE_FILE (data
) != NULL
)
295 fclose (TRACE_FILE (data
));
300 trace_one_insn (SIM_DESC sd
, sim_cpu
*cpu
, address_word pc
,
301 int line_p
, const char *filename
, int linenum
,
302 const char *phase_wo_colon
, const char *name
)
304 char phase
[SIZE_PHASE
+2];
306 strncpy (phase
, phase_wo_colon
, SIZE_PHASE
);
310 trace_printf(sd
, cpu
, "%-*s %s:%-*d 0x%.*lx %s\n",
313 SIZE_LINE_NUMBER
, linenum
,
322 if (STATE_TEXT_SECTION (CPU_STATE (cpu
))
323 && pc
>= STATE_TEXT_START (CPU_STATE (cpu
))
324 && pc
< STATE_TEXT_END (CPU_STATE (cpu
)))
326 const char *pc_filename
= (const char *)0;
327 const char *pc_function
= (const char *)0;
328 unsigned int pc_linenum
= 0;
330 if (bfd_find_nearest_line (STATE_PROG_BFD (CPU_STATE (cpu
)),
331 STATE_TEXT_SECTION (CPU_STATE (cpu
)),
332 (struct symbol_cache_entry
**) 0,
333 pc
- STATE_TEXT_START (CPU_STATE (cpu
)),
334 &pc_filename
, &pc_function
, &pc_linenum
))
339 sprintf (p
, "#%-*d ", SIZE_LINE_NUMBER
, pc_linenum
);
344 sprintf (p
, "%-*s ", SIZE_LINE_NUMBER
+1, "---");
345 p
+= SIZE_LINE_NUMBER
+2;
350 sprintf (p
, "%s ", pc_function
);
353 else if (pc_filename
)
355 char *q
= (char *) strrchr (pc_filename
, '/');
356 sprintf (p
, "%s ", (q
) ? q
+1 : pc_filename
);
365 trace_printf (sd
, cpu
, "%-*s 0x%.*x %-*.*s %s\n",
367 SIZE_PC
, (unsigned) pc
,
368 SIZE_LOCATION
, SIZE_LOCATION
, buf
,
374 trace_printf
VPARAMS ((SIM_DESC sd
, sim_cpu
*cpu
, const char *fmt
, ...))
385 sd
= va_arg (ap
, SIM_DESC
);
386 cpu
= va_arg (ap
, sim_cpu
*);
387 fmt
= va_arg (ap
, const char *);
390 if (cpu
!= NULL
&& TRACE_FILE (CPU_TRACE_DATA (cpu
)) != NULL
)
391 vfprintf (TRACE_FILE (CPU_TRACE_DATA (cpu
)), fmt
, ap
);
393 sim_io_evprintf (sd
, fmt
, ap
);
399 debug_printf
VPARAMS ((sim_cpu
*cpu
, const char *fmt
, ...))
409 cpu
= va_arg (ap
, sim_cpu
*);
410 fmt
= va_arg (ap
, const char *);
413 if (CPU_DEBUG_FILE (cpu
) == NULL
)
414 (* STATE_CALLBACK (CPU_STATE (cpu
))->evprintf_filtered
)
415 (STATE_CALLBACK (CPU_STATE (cpu
)), fmt
, ap
);
417 vfprintf (CPU_DEBUG_FILE (cpu
), fmt
, ap
);