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