1 /* Miscellaneous simulator utilities.
2 Copyright (C) 1997-2021 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/>. */
20 /* This must come before any other includes. */
24 #include "sim-assert.h"
28 #include <sys/time.h> /* needed by sys/resource.h */
30 #ifdef HAVE_SYS_RESOURCE_H
31 #include <sys/resource.h>
35 #include "libiberty.h"
37 #include "sim-utils.h"
39 /* Allocate zero filled memory with xcalloc - xcalloc aborts if the
43 zalloc (unsigned long size
)
45 return xcalloc (1, size
);
48 /* Allocate a sim_state struct. */
51 sim_state_alloc_extra (SIM_OPEN_KIND kind
, host_callback
*callback
,
54 SIM_DESC sd
= ZALLOC (struct sim_state
);
56 STATE_MAGIC (sd
) = SIM_MAGIC_NUMBER
;
57 STATE_CALLBACK (sd
) = callback
;
58 STATE_OPEN_KIND (sd
) = kind
;
60 #ifdef SIM_HAVE_COMMON_SIM_STATE
62 STATE_ARCH_DATA (sd
) = zalloc (extra_bytes
);
69 /* Initialize the back link from the cpu struct to the state struct. */
70 /* ??? I can envision a design where the state struct contains an array
71 of pointers to cpu structs, rather than an array of structs themselves.
72 Implementing this is trickier as one may not know what to allocate until
73 one has parsed the args. Parsing the args twice wouldn't be unreasonable,
74 IMHO. If the state struct ever does contain an array of pointers then we
76 ??? See also sim_post_argv_init*/
77 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
79 CPU_STATE (STATE_CPU (sd
, cpu_nr
)) = sd
;
80 CPU_INDEX (STATE_CPU (sd
, cpu_nr
)) = cpu_nr
;
92 /* Free a sim_state struct. */
95 sim_state_free (SIM_DESC sd
)
97 ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
106 /* Return a pointer to the cpu data for CPU_NAME, or NULL if not found. */
109 sim_cpu_lookup (SIM_DESC sd
, const char *cpu_name
)
113 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
114 if (strcmp (cpu_name
, CPU_NAME (STATE_CPU (sd
, i
))) == 0)
115 return STATE_CPU (sd
, i
);
119 /* Return the prefix to use for a CPU specific message (typically an
123 sim_cpu_msg_prefix (sim_cpu
*cpu
)
125 #if MAX_NR_PROCESSORS == 1
133 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
135 int len
= strlen (CPU_NAME (STATE_CPU (sd
, i
)));
139 prefix
= (char *) xmalloc (maxlen
+ 5);
141 sprintf (prefix
, "%s: ", CPU_NAME (cpu
));
146 /* Cover fn to sim_io_eprintf. */
149 sim_io_eprintf_cpu (sim_cpu
*cpu
, const char *fmt
, ...)
151 SIM_DESC sd
= CPU_STATE (cpu
);
155 sim_io_eprintf (sd
, "%s", sim_cpu_msg_prefix (cpu
));
156 sim_io_evprintf (sd
, fmt
, ap
);
160 /* Turn VALUE into a string with commas. */
163 sim_add_commas (char *buf
, int sizeof_buf
, unsigned long value
)
166 char *endbuf
= buf
+ sizeof_buf
- 1;
176 *--endbuf
= (value
% 10) + '0';
177 } while ((value
/= 10) != 0);
182 /* Analyze PROG_NAME/PROG_BFD and set these fields in the state struct:
183 STATE_ARCHITECTURE, if not set already and can be determined from the bfd
190 PROG_NAME is the file name of the executable or NULL.
191 PROG_BFD is its bfd or NULL.
193 If both PROG_NAME and PROG_BFD are NULL, this function returns immediately.
194 If PROG_BFD is not NULL, PROG_NAME is ignored.
196 Implicit inputs: STATE_MY_NAME(sd), STATE_TARGET(sd),
197 STATE_ARCHITECTURE(sd).
199 A new bfd is created so the app isn't required to keep its copy of the
203 sim_analyze_program (SIM_DESC sd
, const char *prog_name
, bfd
*prog_bfd
)
206 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
208 if (prog_bfd
!= NULL
)
210 if (prog_bfd
== STATE_PROG_BFD (sd
))
211 /* already analyzed */
214 /* duplicate needed, save the name of the file to be re-opened */
215 prog_name
= bfd_get_filename (prog_bfd
);
218 /* do we need to duplicate anything? */
219 if (prog_name
== NULL
)
222 /* open a new copy of the prog_bfd */
223 prog_bfd
= bfd_openr (prog_name
, STATE_TARGET (sd
));
224 if (prog_bfd
== NULL
)
226 sim_io_eprintf (sd
, "%s: can't open \"%s\": %s\n",
229 bfd_errmsg (bfd_get_error ()));
232 if (!bfd_check_format (prog_bfd
, bfd_object
))
234 sim_io_eprintf (sd
, "%s: \"%s\" is not an object file: %s\n",
237 bfd_errmsg (bfd_get_error ()));
238 bfd_close (prog_bfd
);
241 if (STATE_ARCHITECTURE (sd
) != NULL
)
242 bfd_set_arch_info (prog_bfd
, STATE_ARCHITECTURE (sd
));
245 if (bfd_get_arch (prog_bfd
) != bfd_arch_unknown
246 && bfd_get_arch (prog_bfd
) != bfd_arch_obscure
)
248 STATE_ARCHITECTURE (sd
) = bfd_get_arch_info (prog_bfd
);
252 /* update the sim structure */
253 if (STATE_PROG_BFD (sd
) != NULL
)
254 bfd_close (STATE_PROG_BFD (sd
));
255 STATE_PROG_BFD (sd
) = prog_bfd
;
256 STATE_START_ADDR (sd
) = bfd_get_start_address (prog_bfd
);
258 for (s
= prog_bfd
->sections
; s
; s
= s
->next
)
259 if (strcmp (bfd_section_name (s
), ".text") == 0)
261 STATE_TEXT_SECTION (sd
) = s
;
262 STATE_TEXT_START (sd
) = bfd_section_vma (s
);
263 STATE_TEXT_END (sd
) = STATE_TEXT_START (sd
) + bfd_section_size (s
);
267 bfd_cache_close (prog_bfd
);
272 /* Simulator timing support. */
274 /* Called before sim_elapsed_time_since to get a reference point. */
277 sim_elapsed_time_get (void)
279 #ifdef HAVE_GETRUSAGE
280 struct rusage mytime
;
281 if (getrusage (RUSAGE_SELF
, &mytime
) == 0)
282 return 1 + (SIM_ELAPSED_TIME
) (((double) mytime
.ru_utime
.tv_sec
* 1000) + (((double) mytime
.ru_utime
.tv_usec
+ 500) / 1000));
286 return 1 + (SIM_ELAPSED_TIME
) time ((time_t) 0);
293 /* Return the elapsed time in milliseconds since START.
294 The actual time may be cpu usage (preferred) or wall clock. */
297 sim_elapsed_time_since (SIM_ELAPSED_TIME start
)
299 #ifdef HAVE_GETRUSAGE
300 return sim_elapsed_time_get () - start
;
303 return (sim_elapsed_time_get () - start
) * 1000;
312 /* do_command but with printf style formatting of the arguments */
314 sim_do_commandf (SIM_DESC sd
,
323 ret
= vasprintf (&buf
, fmt
, ap
);
328 sim_io_eprintf (sd
, "%s: asprintf failed for `%s'\n",
329 STATE_MY_NAME (sd
), fmt
);
333 sim_do_command (sd
, buf
);
338 /* sim-basics.h defines a number of enumerations, convert each of them
339 to a string representation */
341 map_to_str (unsigned map
)
345 case read_map
: return "read";
346 case write_map
: return "write";
347 case exec_map
: return "exec";
348 case io_map
: return "io";
352 snprintf (str
, sizeof(str
), "(%ld)", (long) map
);
359 access_to_str (unsigned access
)
363 case access_invalid
: return "invalid";
364 case access_read
: return "read";
365 case access_write
: return "write";
366 case access_exec
: return "exec";
367 case access_io
: return "io";
368 case access_read_write
: return "read_write";
369 case access_read_exec
: return "read_exec";
370 case access_write_exec
: return "write_exec";
371 case access_read_write_exec
: return "read_write_exec";
372 case access_read_io
: return "read_io";
373 case access_write_io
: return "write_io";
374 case access_read_write_io
: return "read_write_io";
375 case access_exec_io
: return "exec_io";
376 case access_read_exec_io
: return "read_exec_io";
377 case access_write_exec_io
: return "write_exec_io";
378 case access_read_write_exec_io
: return "read_write_exec_io";
382 snprintf (str
, sizeof(str
), "(%ld)", (long) access
);
389 transfer_to_str (unsigned transfer
)
393 case read_transfer
: return "read";
394 case write_transfer
: return "write";
395 default: return "(error)";