]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/sim-utils.c
sim: invert sim_state storage
[thirdparty/binutils-gdb.git] / sim / common / sim-utils.c
1 /* Miscellaneous simulator utilities.
2 Copyright (C) 1997-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
4
5 This file is part of GDB, the GNU debugger.
6
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.
11
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.
16
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/>. */
19
20 /* This must come before any other includes. */
21 #include "defs.h"
22
23 #include "sim-main.h"
24 #include "sim-assert.h"
25
26 #include <stdlib.h>
27 #include <time.h>
28 #include <sys/time.h> /* needed by sys/resource.h */
29
30 #ifdef HAVE_SYS_RESOURCE_H
31 #include <sys/resource.h>
32 #endif
33 #include <string.h>
34
35 #include "libiberty.h"
36 #include "bfd.h"
37 #include "sim-utils.h"
38
39 /* Allocate zero filled memory with xcalloc - xcalloc aborts if the
40 allocation fails. */
41
42 void *
43 zalloc (unsigned long size)
44 {
45 return xcalloc (1, size);
46 }
47
48 /* Allocate a sim_state struct. */
49
50 SIM_DESC
51 sim_state_alloc_extra (SIM_OPEN_KIND kind, host_callback *callback,
52 size_t extra_bytes)
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
60 #ifdef SIM_HAVE_COMMON_SIM_STATE
61 if (extra_bytes)
62 STATE_ARCH_DATA (sd) = zalloc (extra_bytes);
63 #endif
64
65 #if 0
66 {
67 int cpu_nr;
68
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
75 can't do this here.
76 ??? See also sim_post_argv_init*/
77 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
78 {
79 CPU_STATE (STATE_CPU (sd, cpu_nr)) = sd;
80 CPU_INDEX (STATE_CPU (sd, cpu_nr)) = cpu_nr;
81 }
82 }
83 #endif
84
85 #ifdef SIM_STATE_INIT
86 SIM_STATE_INIT (sd);
87 #endif
88
89 return sd;
90 }
91
92 /* Free a sim_state struct. */
93
94 void
95 sim_state_free (SIM_DESC sd)
96 {
97 ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
98
99 #ifdef SIM_STATE_FREE
100 SIM_STATE_FREE (sd);
101 #endif
102
103 free (sd);
104 }
105
106 /* Return a pointer to the cpu data for CPU_NAME, or NULL if not found. */
107
108 sim_cpu *
109 sim_cpu_lookup (SIM_DESC sd, const char *cpu_name)
110 {
111 int i;
112
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);
116 return NULL;
117 }
118
119 /* Return the prefix to use for a CPU specific message (typically an
120 error message). */
121
122 const char *
123 sim_cpu_msg_prefix (sim_cpu *cpu)
124 {
125 #if MAX_NR_PROCESSORS == 1
126 return "";
127 #else
128 static char *prefix;
129
130 if (prefix == NULL)
131 {
132 int maxlen = 0;
133 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
134 {
135 int len = strlen (CPU_NAME (STATE_CPU (sd, i)));
136 if (len > maxlen)
137 maxlen = len;
138 }
139 prefix = (char *) xmalloc (maxlen + 5);
140 }
141 sprintf (prefix, "%s: ", CPU_NAME (cpu));
142 return prefix;
143 #endif
144 }
145
146 /* Cover fn to sim_io_eprintf. */
147
148 void
149 sim_io_eprintf_cpu (sim_cpu *cpu, const char *fmt, ...)
150 {
151 SIM_DESC sd = CPU_STATE (cpu);
152 va_list ap;
153
154 va_start (ap, fmt);
155 sim_io_eprintf (sd, "%s", sim_cpu_msg_prefix (cpu));
156 sim_io_evprintf (sd, fmt, ap);
157 va_end (ap);
158 }
159
160 /* Turn VALUE into a string with commas. */
161
162 char *
163 sim_add_commas (char *buf, int sizeof_buf, unsigned long value)
164 {
165 int comma = 3;
166 char *endbuf = buf + sizeof_buf - 1;
167
168 *--endbuf = '\0';
169 do {
170 if (comma-- == 0)
171 {
172 *--endbuf = ',';
173 comma = 2;
174 }
175
176 *--endbuf = (value % 10) + '0';
177 } while ((value /= 10) != 0);
178
179 return endbuf;
180 }
181
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
184 STATE_PROG_BFD
185 STATE_START_ADDR
186 STATE_TEXT_SECTION
187 STATE_TEXT_START
188 STATE_TEXT_END
189
190 PROG_NAME is the file name of the executable or NULL.
191 PROG_BFD is its bfd or NULL.
192
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.
195
196 Implicit inputs: STATE_MY_NAME(sd), STATE_TARGET(sd),
197 STATE_ARCHITECTURE(sd).
198
199 A new bfd is created so the app isn't required to keep its copy of the
200 bfd open. */
201
202 SIM_RC
203 sim_analyze_program (SIM_DESC sd, const char *prog_name, bfd *prog_bfd)
204 {
205 asection *s;
206 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
207
208 if (prog_bfd != NULL)
209 {
210 if (prog_bfd == STATE_PROG_BFD (sd))
211 /* already analyzed */
212 return SIM_RC_OK;
213 else
214 /* duplicate needed, save the name of the file to be re-opened */
215 prog_name = bfd_get_filename (prog_bfd);
216 }
217
218 /* do we need to duplicate anything? */
219 if (prog_name == NULL)
220 return SIM_RC_OK;
221
222 /* open a new copy of the prog_bfd */
223 prog_bfd = bfd_openr (prog_name, STATE_TARGET (sd));
224 if (prog_bfd == NULL)
225 {
226 sim_io_eprintf (sd, "%s: can't open \"%s\": %s\n",
227 STATE_MY_NAME (sd),
228 prog_name,
229 bfd_errmsg (bfd_get_error ()));
230 return SIM_RC_FAIL;
231 }
232 if (!bfd_check_format (prog_bfd, bfd_object))
233 {
234 sim_io_eprintf (sd, "%s: \"%s\" is not an object file: %s\n",
235 STATE_MY_NAME (sd),
236 prog_name,
237 bfd_errmsg (bfd_get_error ()));
238 bfd_close (prog_bfd);
239 return SIM_RC_FAIL;
240 }
241 if (STATE_ARCHITECTURE (sd) != NULL)
242 bfd_set_arch_info (prog_bfd, STATE_ARCHITECTURE (sd));
243 else
244 {
245 if (bfd_get_arch (prog_bfd) != bfd_arch_unknown
246 && bfd_get_arch (prog_bfd) != bfd_arch_obscure)
247 {
248 STATE_ARCHITECTURE (sd) = bfd_get_arch_info (prog_bfd);
249 }
250 }
251
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);
257
258 for (s = prog_bfd->sections; s; s = s->next)
259 if (strcmp (bfd_section_name (s), ".text") == 0)
260 {
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);
264 break;
265 }
266
267 bfd_cache_close (prog_bfd);
268
269 return SIM_RC_OK;
270 }
271 \f
272 /* Simulator timing support. */
273
274 /* Called before sim_elapsed_time_since to get a reference point. */
275
276 SIM_ELAPSED_TIME
277 sim_elapsed_time_get (void)
278 {
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));
283 return 1;
284 #else
285 #ifdef HAVE_TIME
286 return 1 + (SIM_ELAPSED_TIME) time ((time_t) 0);
287 #else
288 return 1;
289 #endif
290 #endif
291 }
292
293 /* Return the elapsed time in milliseconds since START.
294 The actual time may be cpu usage (preferred) or wall clock. */
295
296 unsigned long
297 sim_elapsed_time_since (SIM_ELAPSED_TIME start)
298 {
299 #ifdef HAVE_GETRUSAGE
300 return sim_elapsed_time_get () - start;
301 #else
302 #ifdef HAVE_TIME
303 return (sim_elapsed_time_get () - start) * 1000;
304 #else
305 return 0;
306 #endif
307 #endif
308 }
309
310
311
312 /* do_command but with printf style formatting of the arguments */
313 void
314 sim_do_commandf (SIM_DESC sd,
315 const char *fmt,
316 ...)
317 {
318 va_list ap;
319 char *buf;
320 int ret;
321
322 va_start (ap, fmt);
323 ret = vasprintf (&buf, fmt, ap);
324 va_end (ap);
325
326 if (ret < 0)
327 {
328 sim_io_eprintf (sd, "%s: asprintf failed for `%s'\n",
329 STATE_MY_NAME (sd), fmt);
330 return;
331 }
332
333 sim_do_command (sd, buf);
334 free (buf);
335 }
336
337
338 /* sim-basics.h defines a number of enumerations, convert each of them
339 to a string representation */
340 const char *
341 map_to_str (unsigned map)
342 {
343 switch (map)
344 {
345 case read_map: return "read";
346 case write_map: return "write";
347 case exec_map: return "exec";
348 case io_map: return "io";
349 default:
350 {
351 static char str[16];
352 snprintf (str, sizeof(str), "(%ld)", (long) map);
353 return str;
354 }
355 }
356 }
357
358 const char *
359 access_to_str (unsigned access)
360 {
361 switch (access)
362 {
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";
379 default:
380 {
381 static char str[16];
382 snprintf (str, sizeof(str), "(%ld)", (long) access);
383 return str;
384 }
385 }
386 }
387
388 const char *
389 transfer_to_str (unsigned transfer)
390 {
391 switch (transfer)
392 {
393 case read_transfer: return "read";
394 case write_transfer: return "write";
395 default: return "(error)";
396 }
397 }