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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-7.1/] [sim/] [rx/] [trace.c] - Blame information for rev 830

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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