]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - sim/common/nrun.c
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / common / nrun.c
CommitLineData
c906108c
SS
1/* New version of run front end support for simulators.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2, or (at your option)
7any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License along
15with this program; if not, write to the Free Software Foundation, Inc.,
1659 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
17
18#include <signal.h>
19#include "sim-main.h"
20
21#include "bfd.h"
22
23#ifdef HAVE_ENVIRON
24extern char **environ;
25#endif
26
27static void usage (void);
28
29extern host_callback default_callback;
30
31static char *myname;
32
33static SIM_DESC sd;
34
35static RETSIGTYPE
36cntrl_c (int sig)
37{
38 if (! sim_stop (sd))
39 {
40 fprintf (stderr, "Quit!\n");
41 exit (1);
42 }
43}
44
45int
46main (int argc, char **argv)
47{
48 char *name;
49 char **prog_argv = NULL;
50 struct _bfd *prog_bfd;
51 enum sim_stop reason;
52 int sigrc = 0;
53 int single_step = 0;
54 RETSIGTYPE (*prev_sigint) ();
55
56 myname = argv[0] + strlen (argv[0]);
57 while (myname > argv[0] && myname[-1] != '/')
58 --myname;
59
60 /* INTERNAL: When MYNAME is `step', single step the simulator
61 instead of allowing it to run free. The sole purpose of this
62 HACK is to allow the sim_resume interface's step argument to be
63 tested without having to build/run gdb. */
64 if (strlen (myname) > 4 && strcmp (myname - 4, "step") == 0)
65 {
66 single_step = 1;
67 }
68
69 /* Create an instance of the simulator. */
70 default_callback.init (&default_callback);
71 sd = sim_open (SIM_OPEN_STANDALONE, &default_callback, NULL, argv);
72 if (sd == 0)
73 exit (1);
74 if (STATE_MAGIC (sd) != SIM_MAGIC_NUMBER)
75 {
76 fprintf (stderr, "Internal error - bad magic number in simulator struct\n");
77 abort ();
78 }
79
80 /* Was there a program to run? */
81 prog_argv = STATE_PROG_ARGV (sd);
82 prog_bfd = STATE_PROG_BFD (sd);
83 if (prog_argv == NULL || *prog_argv == NULL)
84 usage ();
85
86 name = *prog_argv;
87
88 /* For simulators that don't open prog during sim_open() */
89 if (prog_bfd == NULL)
90 {
91 prog_bfd = bfd_openr (name, 0);
92 if (prog_bfd == NULL)
93 {
94 fprintf (stderr, "%s: can't open \"%s\": %s\n",
95 myname, name, bfd_errmsg (bfd_get_error ()));
96 exit (1);
97 }
98 if (!bfd_check_format (prog_bfd, bfd_object))
99 {
100 fprintf (stderr, "%s: \"%s\" is not an object file: %s\n",
101 myname, name, bfd_errmsg (bfd_get_error ()));
102 exit (1);
103 }
104 }
105
106 if (STATE_VERBOSE_P (sd))
107 printf ("%s %s\n", myname, name);
108
109 /* Load the program into the simulator. */
110 if (sim_load (sd, name, prog_bfd, 0) == SIM_RC_FAIL)
111 exit (1);
112
113 /* Prepare the program for execution. */
114#ifdef HAVE_ENVIRON
115 sim_create_inferior (sd, prog_bfd, prog_argv, environ);
116#else
117 sim_create_inferior (sd, prog_bfd, prog_argv, NULL);
118#endif
119
120 /* Run/Step the program. */
121 if (single_step)
122 {
123 do
124 {
125 prev_sigint = signal (SIGINT, cntrl_c);
126 sim_resume (sd, 1/*step*/, 0);
127 signal (SIGINT, prev_sigint);
128 sim_stop_reason (sd, &reason, &sigrc);
129
130 if ((reason == sim_stopped) &&
131 (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
132 break; /* exit on control-C */
133 }
134 /* remain on breakpoint or signals in oe mode*/
135 while (((reason == sim_signalled) &&
136 (sigrc == sim_signal_to_host (sd, SIM_SIGTRAP))) ||
137 ((reason == sim_stopped) &&
138 (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT)));
139 }
140 else do
141 {
142#if defined (HAVE_SIGACTION) && defined (SA_RESTART)
143 struct sigaction sa, osa;
144 sa.sa_handler = cntrl_c;
145 sigemptyset (&sa.sa_mask);
146 sa.sa_flags = 0;
147 sigaction (SIGINT, &sa, &osa);
148 prev_sigint = osa.sa_handler;
149#else
150 prev_sigint = signal (SIGINT, cntrl_c);
151#endif
152 sim_resume (sd, 0, sigrc);
153 signal (SIGINT, prev_sigint);
154 sim_stop_reason (sd, &reason, &sigrc);
155
156 if ((reason == sim_stopped) &&
157 (sigrc == sim_signal_to_host (sd, SIM_SIGINT)))
158 break; /* exit on control-C */
159
160 /* remain on signals in oe mode */
161 } while ((reason == sim_stopped) &&
162 (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT));
163
164 /* Print any stats the simulator collected. */
165 sim_info (sd, 0);
166
167 /* Shutdown the simulator. */
168 sim_close (sd, 0);
169
170 /* If reason is sim_exited, then sigrc holds the exit code which we want
171 to return. If reason is sim_stopped or sim_signalled, then sigrc holds
172 the signal that the simulator received; we want to return that to
173 indicate failure. */
174
175#ifdef SIM_H8300 /* FIXME: Ugh. grep for SLEEP in compile.c */
176 if (sigrc == SIGILL)
177 abort ();
178 sigrc = 0;
179#else
180 /* Why did we stop? */
181 switch (reason)
182 {
183 case sim_signalled:
184 case sim_stopped:
185 if (sigrc != 0)
186 fprintf (stderr, "program stopped with signal %d.\n", sigrc);
187 break;
188
189 case sim_exited:
190 break;
191
192 default:
193 fprintf (stderr, "program in undefined state (%d:%d)\n", reason, sigrc);
194 break;
195
196 }
197#endif
198
199 return sigrc;
200}
201
202static void
203usage ()
204{
205 fprintf (stderr, "Usage: %s [options] program [program args]\n", myname);
206 fprintf (stderr, "Run `%s --help' for full list of options.\n", myname);
207 exit (1);
208}
209
210
211#ifdef __CYGWIN32__
212/* no-op GUI update hook for standalone sim */
213void (*ui_loop_hook) PARAMS ((int)) = NULL;
214#endif