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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gdb-6.8/] [sim/] [common/] [sim-utils.c] - Blame information for rev 856

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

Line No. Rev Author Line
1 24 jeremybenn
/* Miscellaneous simulator utilities.
2
   Copyright (C) 1997, 1998, 2007, 2008 Free Software Foundation, Inc.
3
   Contributed by Cygnus Support.
4
 
5
This file is part of GDB, the GNU debugger.
6
 
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 3 of the License, or
10
(at your option) any later version.
11
 
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.
16
 
17
You should have received a copy of the GNU General Public License
18
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
19
 
20
#include "sim-main.h"
21
#include "sim-assert.h"
22
 
23
#ifdef HAVE_STDLIB_H
24
#include <stdlib.h>
25
#endif
26
 
27
#ifdef HAVE_TIME_H
28
#include <time.h>
29
#endif
30
 
31
#ifdef HAVE_SYS_TIME_H
32
#include <sys/time.h> /* needed by sys/resource.h */
33
#endif
34
 
35
#ifdef HAVE_SYS_RESOURCE_H
36
#include <sys/resource.h>
37
#endif
38
 
39
#ifdef HAVE_STRING_H
40
#include <string.h>
41
#else
42
#ifdef HAVE_STRINGS_H
43
#include <strings.h>
44
#endif
45
#endif
46
 
47
#include "libiberty.h"
48
#include "bfd.h"
49
#include "sim-utils.h"
50
 
51
/* Global pointer to all state data.
52
   Set by sim_resume.  */
53
struct sim_state *current_state;
54
 
55
/* Allocate zero filled memory with xmalloc - xmalloc aborts of the
56
   allocation fails.  */
57
 
58
void *
59
zalloc (unsigned long size)
60
{
61
  void *memory = (void *) xmalloc (size);
62
  memset (memory, 0, size);
63
  return memory;
64
}
65
 
66
void
67
zfree (void *data)
68
{
69
  free (data);
70
}
71
 
72
/* Allocate a sim_state struct.  */
73
 
74
SIM_DESC
75
sim_state_alloc (SIM_OPEN_KIND kind,
76
                 host_callback *callback)
77
{
78
  SIM_DESC sd = ZALLOC (struct sim_state);
79
 
80
  STATE_MAGIC (sd) = SIM_MAGIC_NUMBER;
81
  STATE_CALLBACK (sd) = callback;
82
  STATE_OPEN_KIND (sd) = kind;
83
 
84
#if 0
85
  {
86
    int cpu_nr;
87
 
88
    /* Initialize the back link from the cpu struct to the state struct.  */
89
    /* ??? I can envision a design where the state struct contains an array
90
       of pointers to cpu structs, rather than an array of structs themselves.
91
       Implementing this is trickier as one may not know what to allocate until
92
       one has parsed the args.  Parsing the args twice wouldn't be unreasonable,
93
       IMHO.  If the state struct ever does contain an array of pointers then we
94
       can't do this here.
95
       ??? See also sim_post_argv_init*/
96
    for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
97
      {
98
        CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd;
99
        CPU_INDEX (STATE_CPU (sd, cpu_nr)) = cpu_nr;
100
      }
101
  }
102
#endif
103
 
104
#ifdef SIM_STATE_INIT
105
  SIM_STATE_INIT (sd);
106
#endif
107
 
108
  return sd;
109
}
110
 
111
/* Free a sim_state struct.  */
112
 
113
void
114
sim_state_free (SIM_DESC sd)
115
{
116
  ASSERT (sd->base.magic == SIM_MAGIC_NUMBER);
117
 
118
#ifdef SIM_STATE_FREE
119
  SIM_STATE_FREE (sd);
120
#endif
121
 
122
  zfree (sd);
123
}
124
 
125
/* Return a pointer to the cpu data for CPU_NAME, or NULL if not found.  */
126
 
127
sim_cpu *
128
sim_cpu_lookup (SIM_DESC sd, const char *cpu_name)
129
{
130
  int i;
131
 
132
  for (i = 0; i < MAX_NR_PROCESSORS; ++i)
133
    if (strcmp (cpu_name, CPU_NAME (STATE_CPU (sd, i))) == 0)
134
      return STATE_CPU (sd, i);
135
  return NULL;
136
}
137
 
138
/* Return the prefix to use for a CPU specific message (typically an
139
   error message).  */
140
 
141
const char *
142
sim_cpu_msg_prefix (sim_cpu *cpu)
143
{
144
#if MAX_NR_PROCESSORS == 1
145
  return "";
146
#else
147
  static char *prefix;
148
 
149
  if (prefix == NULL)
150
    {
151
      int maxlen = 0;
152
      for (i = 0; i < MAX_NR_PROCESSORS; ++i)
153
        {
154
          int len = strlen (CPU_NAME (STATE_CPU (sd, i)));
155
          if (len > maxlen)
156
            maxlen = len;
157
        }
158
      prefix = (char *) xmalloc (maxlen + 5);
159
    }
160
  sprintf (prefix, "%s: ", CPU_NAME (cpu));
161
  return prefix;
162
#endif
163
}
164
 
165
/* Cover fn to sim_io_eprintf.  */
166
 
167
void
168
sim_io_eprintf_cpu (sim_cpu *cpu, const char *fmt, ...)
169
{
170
  SIM_DESC sd = CPU_STATE (cpu);
171
  va_list ap;
172
 
173
  va_start (ap, fmt);
174
  sim_io_eprintf (sd, sim_cpu_msg_prefix (cpu));
175
  sim_io_evprintf (sd, fmt, ap);
176
  va_end (ap);
177
}
178
 
179
/* Turn VALUE into a string with commas.  */
180
 
181
char *
182
sim_add_commas (char *buf, int sizeof_buf, unsigned long value)
183
{
184
  int comma = 3;
185
  char *endbuf = buf + sizeof_buf - 1;
186
 
187
  *--endbuf = '\0';
188
  do {
189
    if (comma-- == 0)
190
      {
191
        *--endbuf = ',';
192
        comma = 2;
193
      }
194
 
195
    *--endbuf = (value % 10) + '0';
196
  } while ((value /= 10) != 0);
197
 
198
  return endbuf;
199
}
200
 
201
/* Analyze PROG_NAME/PROG_BFD and set these fields in the state struct:
202
   STATE_ARCHITECTURE, if not set already and can be determined from the bfd
203
   STATE_PROG_BFD
204
   STATE_START_ADDR
205
   STATE_TEXT_SECTION
206
   STATE_TEXT_START
207
   STATE_TEXT_END
208
 
209
   PROG_NAME is the file name of the executable or NULL.
210
   PROG_BFD is its bfd or NULL.
211
 
212
   If both PROG_NAME and PROG_BFD are NULL, this function returns immediately.
213
   If PROG_BFD is not NULL, PROG_NAME is ignored.
214
 
215
   Implicit inputs: STATE_MY_NAME(sd), STATE_TARGET(sd),
216
                    STATE_ARCHITECTURE(sd).
217
 
218
   A new bfd is created so the app isn't required to keep its copy of the
219
   bfd open.  */
220
 
221
SIM_RC
222
sim_analyze_program (sd, prog_name, prog_bfd)
223
     SIM_DESC sd;
224
     char *prog_name;
225
     bfd *prog_bfd;
226
{
227
  asection *s;
228
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
229
 
230
  if (prog_bfd != NULL)
231
    {
232
      if (prog_bfd == STATE_PROG_BFD (sd))
233
        /* already analyzed */
234
        return SIM_RC_OK;
235
      else
236
        /* duplicate needed, save the name of the file to be re-opened */
237
        prog_name = bfd_get_filename (prog_bfd);
238
    }
239
 
240
  /* do we need to duplicate anything? */
241
  if (prog_name == NULL)
242
    return SIM_RC_OK;
243
 
244
  /* open a new copy of the prog_bfd */
245
  prog_bfd = bfd_openr (prog_name, STATE_TARGET (sd));
246
  if (prog_bfd == NULL)
247
    {
248
      sim_io_eprintf (sd, "%s: can't open \"%s\": %s\n",
249
                      STATE_MY_NAME (sd),
250
                      prog_name,
251
                      bfd_errmsg (bfd_get_error ()));
252
      return SIM_RC_FAIL;
253
    }
254
  if (!bfd_check_format (prog_bfd, bfd_object))
255
    {
256
      sim_io_eprintf (sd, "%s: \"%s\" is not an object file: %s\n",
257
                      STATE_MY_NAME (sd),
258
                      prog_name,
259
                      bfd_errmsg (bfd_get_error ()));
260
      bfd_close (prog_bfd);
261
      return SIM_RC_FAIL;
262
    }
263
  if (STATE_ARCHITECTURE (sd) != NULL)
264
    bfd_set_arch_info (prog_bfd, STATE_ARCHITECTURE (sd));
265
  else
266
    {
267
      if (bfd_get_arch (prog_bfd) != bfd_arch_unknown
268
          && bfd_get_arch (prog_bfd) != bfd_arch_obscure)
269
        {
270
          STATE_ARCHITECTURE (sd) = bfd_get_arch_info (prog_bfd);
271
        }
272
    }
273
 
274
  /* update the sim structure */
275
  if (STATE_PROG_BFD (sd) != NULL)
276
    bfd_close (STATE_PROG_BFD (sd));
277
  STATE_PROG_BFD (sd) = prog_bfd;
278
  STATE_START_ADDR (sd) = bfd_get_start_address (prog_bfd);
279
 
280
  for (s = prog_bfd->sections; s; s = s->next)
281
    if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
282
      {
283
        STATE_TEXT_SECTION (sd) = s;
284
        STATE_TEXT_START (sd) = bfd_get_section_vma (prog_bfd, s);
285
        STATE_TEXT_END (sd) = STATE_TEXT_START (sd) + bfd_section_size (prog_bfd, s);
286
        break;
287
      }
288
 
289
  bfd_cache_close (prog_bfd);
290
 
291
  return SIM_RC_OK;
292
}
293
 
294
/* Simulator timing support.  */
295
 
296
/* Called before sim_elapsed_time_since to get a reference point.  */
297
 
298
SIM_ELAPSED_TIME
299
sim_elapsed_time_get ()
300
{
301
#ifdef HAVE_GETRUSAGE
302
  struct rusage mytime;
303
  if (getrusage (RUSAGE_SELF, &mytime) == 0)
304
    return 1 + (SIM_ELAPSED_TIME) (((double) mytime.ru_utime.tv_sec * 1000) + (((double) mytime.ru_utime.tv_usec + 500) / 1000));
305
  return 1;
306
#else
307
#ifdef HAVE_TIME
308
  return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0);
309
#else
310
  return 1;
311
#endif
312
#endif
313
}
314
 
315
/* Return the elapsed time in milliseconds since START.
316
   The actual time may be cpu usage (preferred) or wall clock.  */
317
 
318
unsigned long
319
sim_elapsed_time_since (start)
320
     SIM_ELAPSED_TIME start;
321
{
322
#ifdef HAVE_GETRUSAGE
323
  return sim_elapsed_time_get () - start;
324
#else
325
#ifdef HAVE_TIME
326
  return (sim_elapsed_time_get () - start) * 1000;
327
#else
328
  return 0;
329
#endif
330
#endif
331
}
332
 
333
 
334
 
335
/* do_command but with printf style formatting of the arguments */
336
void
337
sim_do_commandf (SIM_DESC sd,
338
                 const char *fmt,
339
                 ...)
340
{
341
  va_list ap;
342
  char *buf;
343
  va_start (ap, fmt);
344
  vasprintf (&buf, fmt, ap);
345
  sim_do_command (sd, buf);
346
  va_end (ap);
347
  free (buf);
348
}
349
 
350
 
351
/* sim-basics.h defines a number of enumerations, convert each of them
352
   to a string representation */
353
const char *
354
map_to_str (unsigned map)
355
{
356
  switch (map)
357
    {
358
    case read_map: return "read";
359
    case write_map: return "write";
360
    case exec_map: return "exec";
361
    case io_map: return "io";
362
    default:
363
      {
364
        static char str[10];
365
        sprintf (str, "(%ld)", (long) map);
366
        return str;
367
      }
368
    }
369
}
370
 
371
const char *
372
access_to_str (unsigned access)
373
{
374
  switch (access)
375
    {
376
    case access_invalid: return "invalid";
377
    case access_read: return "read";
378
    case access_write: return "write";
379
    case access_exec: return "exec";
380
    case access_io: return "io";
381
    case access_read_write: return "read_write";
382
    case access_read_exec: return "read_exec";
383
    case access_write_exec: return "write_exec";
384
    case access_read_write_exec: return "read_write_exec";
385
    case access_read_io: return "read_io";
386
    case access_write_io: return "write_io";
387
    case access_read_write_io: return "read_write_io";
388
    case access_exec_io: return "exec_io";
389
    case access_read_exec_io: return "read_exec_io";
390
    case access_write_exec_io: return "write_exec_io";
391
    case access_read_write_exec_io: return "read_write_exec_io";
392
    default:
393
      {
394
        static char str[10];
395
        sprintf (str, "(%ld)", (long) access);
396
        return str;
397
      }
398
    }
399
}
400
 
401
const char *
402
transfer_to_str (unsigned transfer)
403
{
404
  switch (transfer)
405
    {
406
    case read_transfer: return "read";
407
    case write_transfer: return "write";
408
    default: return "(error)";
409
    }
410
}
411
 
412
 

powered by: WebSVN 2.1.0

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