Commit | Line | Data |
---|---|---|
c906108c | 1 | /* run front end support for all the simulators. |
32d0add0 | 2 | Copyright (C) 1992-2015 Free Software Foundation, Inc. |
c906108c SS |
3 | |
4 | This program is free software; you can redistribute it and/or modify | |
5 | it under the terms of the GNU General Public License as published by | |
4744ac1b JB |
6 | the Free Software Foundation; either version 3 of the License, or |
7 | (at your option) any later version. | |
c906108c SS |
8 | |
9 | This program is distributed in the hope that it will be useful, | |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | GNU General Public License for more details. | |
13 | ||
4744ac1b JB |
14 | You should have received a copy of the GNU General Public License |
15 | along with this program. If not, see <http://www.gnu.org/licenses/>. */ | |
c906108c SS |
16 | |
17 | /* Steve Chamberlain sac@cygnus.com, | |
18 | and others at Cygnus. */ | |
19 | ||
41ee5402 DJ |
20 | #ifdef HAVE_CONFIG_H |
21 | #include "cconfig.h" | |
41ee5402 | 22 | #endif |
c906108c SS |
23 | |
24 | #include <signal.h> | |
25 | #include <stdio.h> | |
26 | #ifdef __STDC__ | |
27 | #include <stdarg.h> | |
28 | #else | |
29 | #include <varargs.h> | |
30 | #endif | |
31 | ||
32 | #ifdef HAVE_STDLIB_H | |
33 | #include <stdlib.h> | |
34 | #endif | |
35 | ||
36 | #ifdef HAVE_STRING_H | |
37 | #include <string.h> | |
38 | #else | |
39 | #ifdef HAVE_STRINGS_H | |
40 | #include <strings.h> | |
41 | #endif | |
42 | #endif | |
43 | ||
44 | #include "libiberty.h" | |
45 | #include "bfd.h" | |
3c25f8c7 AC |
46 | #include "gdb/callback.h" |
47 | #include "gdb/remote-sim.h" | |
6d358e86 | 48 | #include "ansidecl.h" |
de4112fa | 49 | #include "run-sim.h" |
6efef468 | 50 | #include "version.h" |
c906108c | 51 | |
465fb143 MF |
52 | #ifdef SIM_USE_DEPRECATED_RUN_FRONTEND |
53 | # warning "This sim is using the deprecated run.c; please migrate to nrun.c." | |
54 | #else | |
55 | # error "Please do not create new sim ports using run.c; use nrun.c instead." \ | |
56 | "New submissions using run.c will not be accepted." | |
57 | #endif | |
58 | ||
bdca5ee4 TT |
59 | static void usage (int help); |
60 | static void print_version (void); | |
c906108c SS |
61 | extern int optind; |
62 | extern char *optarg; | |
63 | ||
64 | extern host_callback default_callback; | |
65 | ||
66 | static char *myname; | |
67 | ||
c906108c SS |
68 | extern int getopt (); |
69 | ||
7a292a7a | 70 | #ifdef NEED_UI_LOOP_HOOK |
dbec3bef | 71 | /* Gdb foolery. This is only needed for gdb using a gui. */ |
bdca5ee4 | 72 | int (*deprecated_ui_loop_hook) (int signo); |
7a292a7a SS |
73 | #endif |
74 | ||
c906108c SS |
75 | static SIM_DESC sd; |
76 | ||
77 | static RETSIGTYPE | |
6d358e86 | 78 | cntrl_c (int sig ATTRIBUTE_UNUSED) |
c906108c SS |
79 | { |
80 | if (! sim_stop (sd)) | |
81 | { | |
82 | fprintf (stderr, "Quit!\n"); | |
83 | exit (1); | |
84 | } | |
85 | } | |
86 | ||
87 | int | |
6cd5ace4 | 88 | main (int ac, char **av) |
c906108c SS |
89 | { |
90 | RETSIGTYPE (*prev_sigint) (); | |
91 | bfd *abfd; | |
92 | int i; | |
93 | int verbose = 0; | |
94 | int trace = 0; | |
baa7ae6f AC |
95 | #ifdef SIM_HAVE_ENVIRONMENT |
96 | int operating_p = 0; | |
97 | #endif | |
c906108c SS |
98 | char *name; |
99 | static char *no_args[4]; | |
100 | char **sim_argv = &no_args[0]; | |
101 | char **prog_args; | |
102 | enum sim_stop reason; | |
103 | int sigrc; | |
104 | ||
105 | myname = av[0] + strlen (av[0]); | |
106 | while (myname > av[0] && myname[-1] != '/') | |
107 | --myname; | |
108 | ||
109 | /* The first element of sim_open's argv is the program name. */ | |
110 | no_args[0] = av[0]; | |
111 | #ifdef SIM_HAVE_BIENDIAN | |
112 | no_args[1] = "-E"; | |
113 | no_args[2] = "set-later"; | |
114 | #endif | |
115 | ||
116 | /* FIXME: This is currently being migrated into sim_open. | |
117 | Simulators that use functions such as sim_size() still require | |
dbec3bef | 118 | this. */ |
c906108c SS |
119 | default_callback.init (&default_callback); |
120 | sim_set_callbacks (&default_callback); | |
121 | ||
de4112fa NC |
122 | #ifdef SIM_TARGET_SWITCHES |
123 | ac = sim_target_parse_command_line (ac, av); | |
124 | #endif | |
125 | ||
6efef468 JM |
126 | for (i = 1; av[i]; ++i) |
127 | { | |
128 | if (strcmp (av[i], "--help") == 0) | |
129 | { | |
130 | usage (1); | |
131 | } | |
132 | else if (strcmp (av[i], "--version") == 0) | |
133 | { | |
134 | print_version (); | |
135 | return 0; | |
136 | } | |
137 | } | |
138 | ||
c906108c SS |
139 | /* FIXME: This is currently being rewritten to have each simulator |
140 | do all argv processing. */ | |
141 | ||
dbec3bef | 142 | while ((i = getopt (ac, av, "a:c:m:op:s:tv")) != EOF) |
c906108c SS |
143 | switch (i) |
144 | { | |
145 | case 'a': | |
146 | /* FIXME: Temporary hack. */ | |
147 | { | |
148 | int len = strlen (av[0]) + strlen (optarg); | |
149 | char *argbuf = (char *) alloca (len + 2 + 50); | |
150 | sprintf (argbuf, "%s %s", av[0], optarg); | |
151 | #ifdef SIM_HAVE_BIENDIAN | |
152 | /* The desired endianness must be passed to sim_open. | |
153 | The value for "set-later" is set when we know what it is. | |
154 | -E support isn't yet part of the published interface. */ | |
155 | strcat (argbuf, " -E set-later"); | |
156 | #endif | |
157 | sim_argv = buildargv (argbuf); | |
158 | } | |
159 | break; | |
160 | #ifdef SIM_HAVE_SIMCACHE | |
161 | case 'c': | |
162 | sim_set_simcache_size (atoi (optarg)); | |
163 | break; | |
164 | #endif | |
165 | case 'm': | |
166 | /* FIXME: Rename to sim_set_mem_size. */ | |
167 | sim_size (atoi (optarg)); | |
168 | break; | |
baa7ae6f AC |
169 | #ifdef SIM_HAVE_ENVIRONMENT |
170 | case 'o': | |
171 | /* Operating enironment where any signals are delivered to the | |
dbec3bef | 172 | target. */ |
baa7ae6f AC |
173 | operating_p = 1; |
174 | break; | |
d25b1553 | 175 | #endif |
c906108c SS |
176 | #ifdef SIM_HAVE_PROFILE |
177 | case 'p': | |
178 | sim_set_profile (atoi (optarg)); | |
179 | break; | |
180 | case 's': | |
181 | sim_set_profile_size (atoi (optarg)); | |
182 | break; | |
183 | #endif | |
184 | case 't': | |
185 | trace = 1; | |
c906108c SS |
186 | break; |
187 | case 'v': | |
188 | /* Things that are printed with -v are the kinds of things that | |
189 | gcc -v prints. This is not meant to include detailed tracing | |
190 | or debugging information, just summaries. */ | |
191 | verbose = 1; | |
192 | /* sim_set_verbose (1); */ | |
193 | break; | |
194 | /* FIXME: Quick hack, to be replaced by more general facility. */ | |
c906108c | 195 | default: |
6efef468 | 196 | usage (0); |
c906108c SS |
197 | } |
198 | ||
199 | ac -= optind; | |
200 | av += optind; | |
201 | if (ac <= 0) | |
6efef468 | 202 | usage (0); |
c906108c SS |
203 | |
204 | name = *av; | |
205 | prog_args = av; | |
206 | ||
207 | if (verbose) | |
208 | { | |
209 | printf ("%s %s\n", myname, name); | |
210 | } | |
211 | ||
212 | abfd = bfd_openr (name, 0); | |
dbec3bef | 213 | if (!abfd) |
c906108c | 214 | { |
dbec3bef | 215 | fprintf (stderr, "%s: can't open %s: %s\n", |
c906108c SS |
216 | myname, name, bfd_errmsg (bfd_get_error ())); |
217 | exit (1); | |
218 | } | |
219 | ||
220 | if (!bfd_check_format (abfd, bfd_object)) | |
221 | { | |
222 | fprintf (stderr, "%s: can't load %s: %s\n", | |
223 | myname, name, bfd_errmsg (bfd_get_error ())); | |
224 | exit (1); | |
225 | } | |
226 | ||
227 | #ifdef SIM_HAVE_BIENDIAN | |
228 | /* The endianness must be passed to sim_open because one may wish to | |
229 | examine/set registers before calling sim_load [which is the other | |
230 | place where one can determine endianness]. We previously passed the | |
231 | endianness via global `target_byte_order' but that's not a clean | |
232 | interface. */ | |
233 | for (i = 1; sim_argv[i + 1] != NULL; ++i) | |
234 | continue; | |
235 | if (bfd_big_endian (abfd)) | |
236 | sim_argv[i] = "big"; | |
237 | else | |
238 | sim_argv[i] = "little"; | |
239 | #endif | |
240 | ||
241 | /* Ensure that any run-time initialisation that needs to be | |
dbec3bef | 242 | performed by the simulator can occur. */ |
c906108c SS |
243 | sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, abfd, sim_argv); |
244 | if (sd == 0) | |
245 | exit (1); | |
246 | ||
247 | if (sim_load (sd, name, abfd, 0) == SIM_RC_FAIL) | |
248 | exit (1); | |
249 | ||
250 | if (sim_create_inferior (sd, abfd, prog_args, NULL) == SIM_RC_FAIL) | |
251 | exit (1); | |
252 | ||
baa7ae6f AC |
253 | #ifdef SIM_HAVE_ENVIRONMENT |
254 | /* NOTE: An old simulator supporting the operating environment MUST | |
255 | provide sim_set_trace() and not sim_trace(). That way | |
dbec3bef | 256 | sim_stop_reason() can be used to determine any stop reason. */ |
baa7ae6f AC |
257 | if (trace) |
258 | sim_set_trace (); | |
781c552e | 259 | sigrc = 0; |
baa7ae6f AC |
260 | do |
261 | { | |
262 | prev_sigint = signal (SIGINT, cntrl_c); | |
263 | sim_resume (sd, 0, sigrc); | |
264 | signal (SIGINT, prev_sigint); | |
265 | sim_stop_reason (sd, &reason, &sigrc); | |
266 | } | |
267 | while (operating_p && reason == sim_stopped && sigrc != SIGINT); | |
268 | #else | |
c906108c SS |
269 | if (trace) |
270 | { | |
271 | int done = 0; | |
7fc5b5ad | 272 | prev_sigint = signal (SIGINT, cntrl_c); |
c906108c SS |
273 | while (!done) |
274 | { | |
275 | done = sim_trace (sd); | |
276 | } | |
7fc5b5ad | 277 | signal (SIGINT, prev_sigint); |
baa7ae6f | 278 | sim_stop_reason (sd, &reason, &sigrc); |
c906108c SS |
279 | } |
280 | else | |
281 | { | |
baa7ae6f | 282 | prev_sigint = signal (SIGINT, cntrl_c); |
781c552e | 283 | sigrc = 0; |
baa7ae6f AC |
284 | sim_resume (sd, 0, sigrc); |
285 | signal (SIGINT, prev_sigint); | |
286 | sim_stop_reason (sd, &reason, &sigrc); | |
c906108c | 287 | } |
baa7ae6f | 288 | #endif |
c906108c SS |
289 | |
290 | if (verbose) | |
291 | sim_info (sd, 0); | |
c906108c SS |
292 | sim_close (sd, 0); |
293 | ||
294 | /* If reason is sim_exited, then sigrc holds the exit code which we want | |
295 | to return. If reason is sim_stopped or sim_signalled, then sigrc holds | |
296 | the signal that the simulator received; we want to return that to | |
297 | indicate failure. */ | |
298 | ||
c906108c SS |
299 | /* Why did we stop? */ |
300 | switch (reason) | |
301 | { | |
302 | case sim_signalled: | |
303 | case sim_stopped: | |
304 | if (sigrc != 0) | |
dbec3bef | 305 | fprintf (stderr, "program stopped with signal %d.\n", sigrc); |
c906108c SS |
306 | break; |
307 | ||
308 | case sim_exited: | |
309 | break; | |
310 | ||
311 | case sim_running: | |
dbec3bef | 312 | case sim_polling: /* These indicate a serious problem. */ |
c906108c SS |
313 | abort (); |
314 | break; | |
315 | ||
316 | } | |
c906108c SS |
317 | |
318 | return sigrc; | |
319 | } | |
320 | ||
321 | static void | |
6efef468 | 322 | usage (int help) |
c906108c | 323 | { |
6efef468 JM |
324 | FILE *stream = help ? stdout : stderr; |
325 | ||
326 | fprintf (stream, "Usage: %s [options] program [program args]\n", myname); | |
327 | fprintf (stream, "Options:\n"); | |
328 | fprintf (stream, "-a args Pass `args' to simulator.\n"); | |
c906108c | 329 | #ifdef SIM_HAVE_SIMCACHE |
6efef468 | 330 | fprintf (stream, "-c size Set simulator cache size to `size'.\n"); |
c906108c | 331 | #endif |
6efef468 | 332 | fprintf (stream, "-m size Set memory size of simulator, in bytes.\n"); |
baa7ae6f | 333 | #ifdef SIM_HAVE_ENVIRONMENT |
6efef468 | 334 | fprintf (stream, "-o Select operating (kernel) environment.\n"); |
baa7ae6f | 335 | #endif |
c906108c | 336 | #ifdef SIM_HAVE_PROFILE |
6efef468 JM |
337 | fprintf (stream, "-p freq Set profiling frequency.\n"); |
338 | fprintf (stream, "-s size Set profiling size.\n"); | |
c906108c | 339 | #endif |
6efef468 JM |
340 | fprintf (stream, "-t Perform instruction tracing.\n"); |
341 | fprintf (stream, " Note: Very few simulators support tracing.\n"); | |
342 | fprintf (stream, "-v Verbose output.\n"); | |
343 | fprintf (stream, "\n"); | |
344 | fprintf (stream, "program args Arguments to pass to simulated program.\n"); | |
345 | fprintf (stream, " Note: Very few simulators support this.\n"); | |
de4112fa | 346 | #ifdef SIM_TARGET_SWITCHES |
6efef468 JM |
347 | fprintf (stream, "\nTarget specific options:\n"); |
348 | sim_target_display_usage (help); | |
de4112fa | 349 | #endif |
6efef468 JM |
350 | |
351 | if (help && REPORT_BUGS_TO[0]) | |
352 | printf ("Report bugs to %s\n", REPORT_BUGS_TO); | |
353 | ||
354 | exit (help ? 0 : 1); | |
355 | } | |
356 | ||
028f6515 | 357 | static void |
6cd5ace4 | 358 | print_version (void) |
6efef468 JM |
359 | { |
360 | printf ("GNU simulator %s%s\n", PKGVERSION, version); | |
c906108c | 361 | } |