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

Subversion Repositories openrisc

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

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

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

powered by: WebSVN 2.1.0

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