1 /* trace.c --- tracing output for the RL78 simulator.
3 Copyright (C) 2005-2024 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
6 This file is part of the GNU simulators.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 /* This must come before any other includes. */
29 #include <sys/types.h>
33 #include "libiberty.h"
42 static disassembler_ftype rl78_disasm_fn
= NULL
;
45 sim_dis_read (bfd_vma memaddr
, bfd_byte
* ptr
, unsigned int length
,
46 struct disassemble_info
*info
)
48 mem_get_blk (memaddr
, ptr
, length
);
52 /* Filter out (in place) symbols that are useless for disassembly.
53 COUNT is the number of elements in SYMBOLS.
54 Return the number of useful symbols. */
57 remove_useless_symbols (asymbol
** symbols
, long count
)
59 register asymbol
**in_ptr
= symbols
, **out_ptr
= symbols
;
63 asymbol
*sym
= *in_ptr
++;
65 if (strstr (sym
->name
, "gcc2_compiled"))
67 if (sym
->name
== NULL
|| sym
->name
[0] == '\0')
69 if (sym
->flags
& (BSF_DEBUGGING
))
71 if (bfd_is_und_section (sym
->section
)
72 || bfd_is_com_section (sym
->section
))
77 return out_ptr
- symbols
;
81 compare_symbols (const void *ap
, const void *bp
)
83 const asymbol
*a
= *(const asymbol
**) ap
;
84 const asymbol
*b
= *(const asymbol
**) bp
;
86 if (bfd_asymbol_value (a
) > bfd_asymbol_value (b
))
88 else if (bfd_asymbol_value (a
) < bfd_asymbol_value (b
))
93 static char opbuf
[1000];
95 static int ATTRIBUTE_PRINTF (2, 3)
96 op_printf (char *buf
, char *fmt
, ...)
102 ret
= vsprintf (opbuf
+ strlen (opbuf
), fmt
, ap
);
107 static int ATTRIBUTE_PRINTF (3, 4)
108 op_styled_printf (char *buf
, enum disassembler_style style
, char *fmt
, ...)
114 ret
= vsprintf (opbuf
+ strlen (opbuf
), fmt
, ap
);
119 static bfd
* current_bfd
= NULL
;
120 static asymbol
** symtab
= NULL
;
121 static int symcount
= 0;
122 static asection
* code_section
= NULL
;
123 static bfd_vma code_base
= 0;
124 static struct disassemble_info info
;
127 sim_disasm_init (bfd
*prog
)
130 rl78_disasm_fn
= NULL
;
144 load_file_and_line (const char *filename
, int lineno
)
147 for (f
= files
; f
; f
= f
->next
)
148 if (strcmp (f
->filename
, filename
) == 0)
154 const char *found_filename
, *slash
;
158 found_filename
= filename
;
161 if (stat (found_filename
, &s
) == 0)
163 slash
= strchr (found_filename
, '/');
166 found_filename
= slash
+ 1;
169 f
= (Files
*) xmalloc (sizeof (Files
));
172 f
->filename
= xstrdup (filename
);
173 f
->data
= (char *) xmalloc (s
.st_size
+ 2);
174 file
= fopen (found_filename
, "rb");
175 ret
= fread (f
->data
, 1, s
.st_size
, file
);
180 for (i
= 0; i
< s
.st_size
; i
++)
181 if (f
->data
[i
] == '\n')
183 f
->lines
= (char **) xmalloc (f
->nlines
* sizeof (char *));
184 f
->lines
[0] = f
->data
;
186 for (i
= 0; i
< s
.st_size
; i
++)
187 if (f
->data
[i
] == '\n')
189 f
->lines
[f
->nlines
] = f
->data
+ i
+ 1;
190 while (*f
->lines
[f
->nlines
] == ' '
191 || *f
->lines
[f
->nlines
] == '\t')
192 f
->lines
[f
->nlines
] ++;
197 if (lineno
< 1 || lineno
> f
->nlines
)
199 return f
->lines
[lineno
- 1];
203 sim_get_current_source_location (const char ** pfilename
,
204 const char ** pfunctionname
,
205 unsigned int * plineno
)
207 static int initted
= 0;
210 if (current_bfd
== NULL
)
219 memset (& info
, 0, sizeof (info
));
220 INIT_DISASSEMBLE_INFO (info
, stdout
, op_printf
, op_styled_printf
);
221 info
.read_memory_func
= sim_dis_read
;
222 info
.arch
= bfd_get_arch (current_bfd
);
223 info
.mach
= bfd_get_mach (current_bfd
);
225 info
.arch
= bfd_arch_rl78
;
227 disassemble_init_for_target (& info
);
229 storage
= bfd_get_symtab_upper_bound (current_bfd
);
232 symtab
= (asymbol
**) xmalloc (storage
);
233 symcount
= bfd_canonicalize_symtab (current_bfd
, symtab
);
234 symcount
= remove_useless_symbols (symtab
, symcount
);
235 qsort (symtab
, symcount
, sizeof (asymbol
*), compare_symbols
);
238 for (s
= current_bfd
->sections
; s
; s
= s
->next
)
240 if (s
->flags
& SEC_CODE
|| code_section
== 0)
243 code_base
= bfd_section_lma (s
);
249 *pfilename
= *pfunctionname
= NULL
;
252 bfd_find_nearest_line
253 (current_bfd
, code_section
, symtab
, mypc
- code_base
,
254 pfilename
, pfunctionname
, plineno
);
260 sim_disasm_one (void)
262 static int last_sym
= -1;
263 static const char * prev_filename
= "";
264 static int prev_lineno
= 0;
265 const char * filename
;
266 const char * functionname
;
270 int save_trace
= trace
;
273 if (! sim_get_current_source_location (& filename
, & functionname
, & lineno
))
281 rl78_disasm_fn
= print_insn_rl78_g10
;
282 else if (g14_multiply
)
283 rl78_disasm_fn
= print_insn_rl78_g14
;
284 else if (g13_multiply
)
285 rl78_disasm_fn
= print_insn_rl78_g13
;
287 rl78_disasm_fn
= print_insn_rl78
;
290 if (filename
&& functionname
&& lineno
)
292 if (lineno
!= prev_lineno
|| strcmp (prev_filename
, filename
))
294 char * the_line
= load_file_and_line (filename
, lineno
);
295 const char * slash
= strrchr (filename
, '/');
302 ("========================================"
303 "=====================================\n");
304 printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
305 slash
, lineno
, the_line
);
307 prev_lineno
= lineno
;
308 prev_filename
= filename
;
313 while (min
< max
- 1)
317 sym
= (min
+ max
) / 2;
318 sa
= bfd_asymbol_value (symtab
[sym
]);
319 /*printf ("checking %4d %08x %s\n",
320 sym, sa, bfd_asymbol_name (symtab[sym])); */
332 if (min
!= -1 && min
!= last_sym
)
334 bestaddr
= bfd_asymbol_value (symtab
[min
]);
335 printf ("\033[43;30m%s", bfd_asymbol_name (symtab
[min
]));
336 if (bestaddr
!= mypc
)
337 printf ("+%d", mypc
- bestaddr
);
338 printf (":\t\t\t\033[0m\n");
342 if (strcmp (bfd_asymbol_name (symtab
[min
]), "abort") == 0
343 || strcmp (bfd_asymbol_name (symtab
[min
]), "exit") == 0)
351 #ifdef CYCLE_ACCURATE
352 printf ("\033[33m %04u %06x: ", (int)(regs
.cycle_count
% 10000), mypc
);
354 printf ("\033[33m %08llx %06x: ", total_clocks
, mypc
);
357 max
= rl78_disasm_fn (mypc
, & info
);
359 for (i
= 0; i
< max
; i
++)
360 printf ("%02x", mem_get_qi (mypc
+ i
));
369 printf ("%-16s ", opbuf
);
371 printf ("\033[0m\n");