1 /* Miscellaneous simulator utilities.
2 Copyright (C) 1997, 1998, 2007 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
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.
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.
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/>. */
21 #include "sim-assert.h"
31 #ifdef HAVE_SYS_TIME_H
32 #include <sys/time.h> /* needed by sys/resource.h */
35 #ifdef HAVE_SYS_RESOURCE_H
36 #include <sys/resource.h>
47 #include "libiberty.h"
49 #include "sim-utils.h"
51 /* Global pointer to all state data.
53 struct sim_state *current_state;
55 /* Allocate zero filled memory with xmalloc - xmalloc aborts of the
59 zalloc (unsigned long size)
61 void *memory = (void *) xmalloc (size);
62 memset (memory, 0, size);
72 /* Allocate a sim_state struct. */
75 sim_state_alloc (SIM_OPEN_KIND kind,
76 host_callback *callback)
78 SIM_DESC sd = ZALLOC (struct sim_state);
80 STATE_MAGIC (sd) = SIM_MAGIC_NUMBER;
81 STATE_CALLBACK (sd) = callback;
82 STATE_OPEN_KIND (sd) = kind;
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
95 ??? See also sim_post_argv_init*/
96 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
98 CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd;
99 CPU_INDEX (STATE_CPU (sd, cpu_nr)) = cpu_nr;
104 #ifdef SIM_STATE_INIT
111 /* Free a sim_state struct. */
114 sim_state_free (SIM_DESC sd)
116 ASSERT (sd->base.magic == SIM_MAGIC_NUMBER);
118 #ifdef SIM_STATE_FREE
125 /* Return a pointer to the cpu data for CPU_NAME, or NULL if not found. */
128 sim_cpu_lookup (SIM_DESC sd, const char *cpu_name)
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);
138 /* Return the prefix to use for a CPU specific message (typically an
142 sim_cpu_msg_prefix (sim_cpu *cpu)
144 #if MAX_NR_PROCESSORS == 1
152 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
154 int len = strlen (CPU_NAME (STATE_CPU (sd, i)));
158 prefix = (char *) xmalloc (maxlen + 5);
160 sprintf (prefix, "%s: ", CPU_NAME (cpu));
165 /* Cover fn to sim_io_eprintf. */
168 sim_io_eprintf_cpu (sim_cpu *cpu, const char *fmt, ...)
170 SIM_DESC sd = CPU_STATE (cpu);
174 sim_io_eprintf (sd, sim_cpu_msg_prefix (cpu));
175 sim_io_evprintf (sd, fmt, ap);
179 /* Turn VALUE into a string with commas. */
182 sim_add_commas (char *buf, int sizeof_buf, unsigned long value)
185 char *endbuf = buf + sizeof_buf - 1;
195 *--endbuf = (value % 10) + '0';
196 } while ((value /= 10) != 0);
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
209 PROG_NAME is the file name of the executable or NULL.
210 PROG_BFD is its bfd or NULL.
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.
215 Implicit inputs: STATE_MY_NAME(sd), STATE_TARGET(sd),
216 STATE_ARCHITECTURE(sd).
218 A new bfd is created so the app isn't required to keep its copy of the
222 sim_analyze_program (sd, prog_name, prog_bfd)
228 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
230 if (prog_bfd != NULL)
232 if (prog_bfd == STATE_PROG_BFD (sd))
233 /* already analyzed */
236 /* duplicate needed, save the name of the file to be re-opened */
237 prog_name = bfd_get_filename (prog_bfd);
240 /* do we need to duplicate anything? */
241 if (prog_name == NULL)
244 /* open a new copy of the prog_bfd */
245 prog_bfd = bfd_openr (prog_name, STATE_TARGET (sd));
246 if (prog_bfd == NULL)
248 sim_io_eprintf (sd, "%s: can't open \"%s\": %s\n",
251 bfd_errmsg (bfd_get_error ()));
254 if (!bfd_check_format (prog_bfd, bfd_object))
256 sim_io_eprintf (sd, "%s: \"%s\" is not an object file: %s\n",
259 bfd_errmsg (bfd_get_error ()));
260 bfd_close (prog_bfd);
263 if (STATE_ARCHITECTURE (sd) != NULL)
264 bfd_set_arch_info (prog_bfd, STATE_ARCHITECTURE (sd));
267 if (bfd_get_arch (prog_bfd) != bfd_arch_unknown
268 && bfd_get_arch (prog_bfd) != bfd_arch_obscure)
270 STATE_ARCHITECTURE (sd) = bfd_get_arch_info (prog_bfd);
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);
280 for (s = prog_bfd->sections; s; s = s->next)
281 if (strcmp (bfd_get_section_name (prog_bfd, s), ".text") == 0)
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);
289 bfd_cache_close (prog_bfd);
294 /* Simulator timing support. */
296 /* Called before sim_elapsed_time_since to get a reference point. */
299 sim_elapsed_time_get ()
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));
308 return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0);
315 /* Return the elapsed time in milliseconds since START.
316 The actual time may be cpu usage (preferred) or wall clock. */
319 sim_elapsed_time_since (start)
320 SIM_ELAPSED_TIME start;
322 #ifdef HAVE_GETRUSAGE
323 return sim_elapsed_time_get () - start;
326 return (sim_elapsed_time_get () - start) * 1000;
335 /* do_command but with printf style formatting of the arguments */
337 sim_do_commandf (SIM_DESC sd,
344 vasprintf (&buf, fmt, ap);
345 sim_do_command (sd, buf);
351 /* sim-basics.h defines a number of enumerations, convert each of them
352 to a string representation */
354 map_to_str (unsigned map)
358 case read_map: return "read";
359 case write_map: return "write";
360 case exec_map: return "exec";
361 case io_map: return "io";
365 sprintf (str, "(%ld)", (long) map);
372 access_to_str (unsigned access)
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";
395 sprintf (str, "(%ld)", (long) access);
402 transfer_to_str (unsigned transfer)
406 case read_transfer: return "read";
407 case write_transfer: return "write";
408 default: return "(error)";