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