OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [sim/] [m32c/] [trace.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* trace.c --- tracing output for the M32C simulator.
2
 
3
Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
4
Contributed by Red Hat, Inc.
5
 
6
This file is part of the GNU simulators.
7
 
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.
12
 
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.
17
 
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/>.  */
20
 
21
 
22
#include <stdio.h>
23
#include <stdarg.h>
24
#include <string.h>
25
#include <stdlib.h>
26
#include <sys/types.h>
27
#include <sys/stat.h>
28
#include <ctype.h>
29
 
30
#include "bfd.h"
31
#include "dis-asm.h"
32
#include "m32c-desc.h"
33
 
34
#include "cpu.h"
35
#include "mem.h"
36
#include "load.h"
37
 
38
static int
39
sim_dis_read (bfd_vma memaddr, bfd_byte * ptr, unsigned int length,
40
              struct disassemble_info *info)
41
{
42
  mem_get_blk (memaddr, ptr, length);
43
  return 0;
44
}
45
 
46
/* Filter out (in place) symbols that are useless for disassembly.
47
   COUNT is the number of elements in SYMBOLS.
48
   Return the number of useful symbols. */
49
 
50
static long
51
remove_useless_symbols (asymbol ** symbols, long count)
52
{
53
  register asymbol **in_ptr = symbols, **out_ptr = symbols;
54
 
55
  while (--count >= 0)
56
    {
57
      asymbol *sym = *in_ptr++;
58
 
59
      if (strstr (sym->name, "gcc2_compiled"))
60
        continue;
61
      if (sym->name == NULL || sym->name[0] == '\0')
62
        continue;
63
      if (sym->flags & (BSF_DEBUGGING))
64
        continue;
65
      if (bfd_is_und_section (sym->section)
66
          || bfd_is_com_section (sym->section))
67
        continue;
68
 
69
      *out_ptr++ = sym;
70
    }
71
  return out_ptr - symbols;
72
}
73
 
74
static int
75
compare_symbols (const PTR ap, const PTR bp)
76
{
77
  const asymbol *a = *(const asymbol **) ap;
78
  const asymbol *b = *(const asymbol **) bp;
79
 
80
  if (bfd_asymbol_value (a) > bfd_asymbol_value (b))
81
    return 1;
82
  else if (bfd_asymbol_value (a) < bfd_asymbol_value (b))
83
    return -1;
84
  return 0;
85
}
86
 
87
static char opbuf[1000];
88
 
89
static int
90
op_printf (char *buf, char *fmt, ...)
91
{
92
  int ret;
93
  va_list ap;
94
 
95
  va_start (ap, fmt);
96
  ret = vsprintf (opbuf + strlen (opbuf), fmt, ap);
97
  va_end (ap);
98
  return ret;
99
}
100
 
101
static bfd *current_bfd;
102
 
103
void
104
sim_disasm_init (bfd *prog)
105
{
106
  current_bfd = prog;
107
}
108
 
109
typedef struct Files
110
{
111
  struct Files *next;
112
  char *filename;
113
  int nlines;
114
  char **lines;
115
  char *data;
116
} Files;
117
Files *files = 0;
118
 
119
static char *
120
load_file_and_line (const char *filename, int lineno)
121
{
122
  Files *f;
123
  for (f = files; f; f = f->next)
124
    if (strcmp (f->filename, filename) == 0)
125
      break;
126
  if (!f)
127
    {
128
      int i;
129
      struct stat s;
130
      const char *found_filename, *slash;
131
 
132
      found_filename = filename;
133
      while (1)
134
        {
135
          if (stat (found_filename, &s) == 0)
136
            break;
137
          slash = strchr (found_filename, '/');
138
          if (!slash)
139
            return "";
140
          found_filename = slash + 1;
141
        }
142
 
143
      f = (Files *) malloc (sizeof (Files));
144
      f->next = files;
145
      files = f;
146
      f->filename = strdup (filename);
147
      f->data = (char *) malloc (s.st_size + 2);
148
      FILE *file = fopen (found_filename, "rb");
149
      fread (f->data, 1, s.st_size, file);
150
      f->data[s.st_size] = 0;
151
      fclose (file);
152
 
153
      f->nlines = 1;
154
      for (i = 0; i < s.st_size; i++)
155
        if (f->data[i] == '\n')
156
          f->nlines++;
157
      f->lines = (char **) malloc (f->nlines * sizeof (char *));
158
      f->lines[0] = f->data;
159
      f->nlines = 1;
160
      for (i = 0; i < s.st_size; i++)
161
        if (f->data[i] == '\n')
162
          {
163
            f->lines[f->nlines] = f->data + i + 1;
164
            while (*f->lines[f->nlines] == ' '
165
                   || *f->lines[f->nlines] == '\t')
166
              f->lines[f->nlines]++;
167
            f->nlines++;
168
            f->data[i] = 0;
169
          }
170
    }
171
  if (lineno < 1 || lineno > f->nlines)
172
    return "";
173
  return f->lines[lineno - 1];
174
}
175
 
176
void
177
sim_disasm_one ()
178
{
179
  static int initted = 0;
180
  static asymbol **symtab = 0;
181
  static int symcount = 0;
182
  static int last_sym = -1;
183
  static struct disassemble_info info;
184
  int storage, sym, bestaddr;
185
  int min, max, i;
186
  static asection *code_section = 0;
187
  static bfd_vma code_base = 0;
188
  asection *s;
189
  int save_trace = trace;
190
 
191
  static const char *prev_filename = "";
192
  static int prev_lineno = 0;
193
  const char *filename;
194
  const char *functionname;
195
  unsigned int lineno;
196
 
197
  int mypc = get_reg (pc);
198
 
199
  if (current_bfd == 0)
200
    return;
201
 
202
  trace = 0;
203
 
204
  if (!initted)
205
    {
206
      initted = 1;
207
      memset (&info, 0, sizeof (info));
208
      INIT_DISASSEMBLE_INFO (info, stdout, op_printf);
209
      info.read_memory_func = sim_dis_read;
210
      info.arch = bfd_get_arch (current_bfd);
211
      info.mach = bfd_get_mach (current_bfd);
212
      if (info.mach == 0)
213
        {
214
          info.arch = bfd_arch_m32c;
215
          info.mach = default_machine;
216
        }
217
      disassemble_init_for_target (&info);
218
 
219
      storage = bfd_get_symtab_upper_bound (current_bfd);
220
      if (storage > 0)
221
        {
222
          symtab = (asymbol **) malloc (storage);
223
          symcount = bfd_canonicalize_symtab (current_bfd, symtab);
224
          symcount = remove_useless_symbols (symtab, symcount);
225
          qsort (symtab, symcount, sizeof (asymbol *), compare_symbols);
226
        }
227
      for (s = current_bfd->sections; s; s = s->next)
228
        {
229
          if (s->flags & SEC_CODE || code_section == 0)
230
            {
231
              code_section = s;
232
              code_base = bfd_section_lma (current_bfd, s);
233
              break;
234
            }
235
        }
236
    }
237
 
238
  filename = functionname = 0;
239
  lineno = 0;
240
  if (bfd_find_nearest_line
241
      (current_bfd, code_section, symtab, mypc - code_base, &filename,
242
       &functionname, &lineno))
243
    {
244
      if (filename && functionname && lineno)
245
        {
246
          if (lineno != prev_lineno || strcmp (prev_filename, filename))
247
            {
248
              char *the_line = load_file_and_line (filename, lineno);
249
              const char *slash = strrchr (filename, '/');
250
              if (!slash)
251
                slash = filename;
252
              else
253
                slash++;
254
              printf
255
                ("========================================"
256
                 "=====================================\n");
257
              printf ("\033[37;41m %s:%d: \033[33;40m %s\033[K\033[0m\n",
258
                      slash, lineno, the_line);
259
            }
260
          prev_lineno = lineno;
261
          prev_filename = filename;
262
        }
263
    }
264
 
265
  {
266
    min = -1;
267
    max = symcount;
268
    while (min < max - 1)
269
      {
270
        bfd_vma sa;
271
        sym = (min + max) / 2;
272
        sa = bfd_asymbol_value (symtab[sym]);
273
        /*printf("checking %4d %08x %s\n",
274
                 sym, sa, bfd_asymbol_name (symtab[sym])); */
275
        if (sa > mypc)
276
          max = sym;
277
        else if (sa < mypc)
278
          min = sym;
279
        else
280
          {
281
            min = sym;
282
            break;
283
          }
284
      }
285
    if (min != -1 && min != last_sym)
286
      {
287
        bestaddr = bfd_asymbol_value (symtab[min]);
288
        printf ("\033[43;30m%s", bfd_asymbol_name (symtab[min]));
289
        if (bestaddr != mypc)
290
          printf ("+%d", mypc - bestaddr);
291
        printf (":\t\t\t\033[0m\n");
292
        last_sym = min;
293
#if 0
294
        if (trace == 1)
295
          if (strcmp (bfd_asymbol_name (symtab[min]), "abort") == 0
296
              || strcmp (bfd_asymbol_name (symtab[min]), "exit") == 0)
297
            trace = 0;
298
#endif
299
      }
300
  }
301
 
302
  opbuf[0] = 0;
303
  printf ("\033[33m%06x: ", mypc);
304
  max = print_insn_m32c (mypc, &info);
305
  for (i = 0; i < max; i++)
306
    printf ("%02x", mem_get_qi (mypc + i));
307
  for (; i < 6; i++)
308
    printf ("  ");
309
  printf ("%-16s  ", opbuf);
310
 
311
  printf ("\033[0m\n");
312
  trace = save_trace;
313
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.