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