Commit | Line | Data |
---|---|---|
6834d493 | 1 | /* run front end support for all the simulators. |
fa21d299 | 2 | Copyright (C) 1992, 1993 1994, 1995, 1996 Free Software Foundation, Inc. |
6834d493 | 3 | |
6834d493 JW |
4 | GNU CC is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by | |
6 | the Free Software Foundation; either version 2, or (at your option) | |
7 | any later version. | |
8 | ||
9 | GNU CC 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 | ||
14 | You should have received a copy of the GNU General Public License | |
15 | along with this program; if not, write to the Free Software | |
16 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | |
17 | ||
fa21d299 AC |
18 | /* Steve Chamberlain sac@cygnus.com, |
19 | and others at Cygnus. */ | |
6834d493 | 20 | |
fa21d299 AC |
21 | #include "config.h" |
22 | #include "tconfig.h" | |
6834d493 JW |
23 | |
24 | #include <signal.h> | |
25 | #include <stdio.h> | |
fa21d299 AC |
26 | #ifdef __STDC__ |
27 | #include <stdarg.h> | |
28 | #else | |
6834d493 | 29 | #include <varargs.h> |
fa21d299 AC |
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" | |
6834d493 | 45 | #include "bfd.h" |
6834d493 | 46 | #include "callback.h" |
fa21d299 | 47 | #include "remote-sim.h" |
6834d493 | 48 | |
bcd1475a DE |
49 | #include "../libiberty/alloca-conf.h" |
50 | ||
fa21d299 | 51 | static void usage PARAMS ((void)); |
6834d493 JW |
52 | extern int optind; |
53 | extern char *optarg; | |
54 | ||
57bc1a72 | 55 | bfd *exec_bfd; |
9b280a86 | 56 | |
6834d493 JW |
57 | int target_byte_order; |
58 | ||
59 | extern host_callback default_callback; | |
fa21d299 AC |
60 | |
61 | static char *myname; | |
62 | ||
63 | ||
64 | /* NOTE: sim_size() and sim_trace() are going away */ | |
65 | extern void sim_size PARAMS ((int i)); | |
66 | extern int sim_trace PARAMS ((SIM_DESC sd)); | |
67 | ||
68 | extern int getopt (); | |
69 | ||
70 | ||
6834d493 JW |
71 | int |
72 | main (ac, av) | |
73 | int ac; | |
74 | char **av; | |
75 | { | |
76 | bfd *abfd; | |
77 | bfd_vma start_address; | |
78 | asection *s; | |
79 | int i; | |
80 | int verbose = 0; | |
81 | int trace = 0; | |
fa21d299 AC |
82 | char *name; |
83 | static char *no_args[2]; | |
84 | char **sim_argv = &no_args[0]; | |
85 | char **prog_args; | |
6834d493 JW |
86 | enum sim_stop reason; |
87 | int sigrc; | |
fa21d299 AC |
88 | SIM_DESC sd; |
89 | ||
90 | myname = av[0] + strlen (av[0]); | |
91 | while (myname > av[0] && myname[-1] != '/') | |
92 | --myname; | |
6834d493 | 93 | |
fa21d299 AC |
94 | /* The first element of sim_open's argv is the program name. */ |
95 | no_args[0] = av[0]; | |
96 | ||
97 | /* FIXME: This is currently being rewritten to have each simulator | |
98 | do all argv processing. */ | |
99 | ||
100 | #ifdef SIM_H8300 /* FIXME: quick hack */ | |
101 | while ((i = getopt (ac, av, "a:c:m:p:s:htv")) != EOF) | |
102 | #else | |
103 | while ((i = getopt (ac, av, "a:c:m:p:s:tv")) != EOF) | |
104 | #endif | |
6834d493 JW |
105 | switch (i) |
106 | { | |
fa21d299 AC |
107 | case 'a': |
108 | /* FIXME: Temporary hack. */ | |
109 | { | |
110 | int len = strlen (av[0]) + strlen (optarg); | |
111 | char *argbuf = (char *) alloca (len + 2); | |
112 | sprintf (argbuf, "%s %s", av[0], optarg); | |
113 | sim_argv = buildargv (argbuf); | |
114 | } | |
115 | break; | |
116 | #ifdef SIM_HAVE_SIMCACHE | |
117 | case 'c': | |
118 | sim_set_simcache_size (atoi (optarg)); | |
119 | break; | |
120 | #endif | |
6834d493 | 121 | case 'm': |
fa21d299 | 122 | /* FIXME: Rename to sim_set_mem_size. */ |
6834d493 JW |
123 | sim_size (atoi (optarg)); |
124 | break; | |
fa21d299 | 125 | #ifdef SIM_HAVE_PROFILE |
6834d493 JW |
126 | case 'p': |
127 | sim_set_profile (atoi (optarg)); | |
128 | break; | |
129 | case 's': | |
130 | sim_set_profile_size (atoi (optarg)); | |
131 | break; | |
fa21d299 | 132 | #endif |
6834d493 JW |
133 | case 't': |
134 | trace = 1; | |
fa21d299 AC |
135 | /* FIXME: need to allow specification of what to trace. */ |
136 | /* sim_set_trace (1); */ | |
6834d493 JW |
137 | break; |
138 | case 'v': | |
fa21d299 AC |
139 | /* Things that are printed with -v are the kinds of things that |
140 | gcc -v prints. This is not meant to include detailed tracing | |
141 | or debugging information, just summaries. */ | |
6834d493 | 142 | verbose = 1; |
fa21d299 | 143 | /* sim_set_verbose (1); */ |
6834d493 | 144 | break; |
fa21d299 AC |
145 | /* FIXME: Quick hack, to be replaced by more general facility. */ |
146 | #ifdef SIM_H8300 | |
147 | case 'h': | |
148 | set_h8300h (1); | |
149 | break; | |
150 | #endif | |
6834d493 | 151 | default: |
fa21d299 | 152 | usage (); |
6834d493 | 153 | } |
fa21d299 | 154 | |
6834d493 JW |
155 | ac -= optind; |
156 | av += optind; | |
157 | ||
6834d493 | 158 | name = *av; |
fa21d299 | 159 | prog_args = av + 1; |
6834d493 JW |
160 | |
161 | if (verbose) | |
162 | { | |
fa21d299 | 163 | printf ("%s %s\n", myname, name); |
6834d493 | 164 | } |
3be50301 | 165 | |
57bc1a72 | 166 | exec_bfd = abfd = bfd_openr (name, 0); |
3be50301 JW |
167 | if (!abfd) |
168 | { | |
fa21d299 AC |
169 | fprintf (stderr, "%s: can't open %s: %s\n", |
170 | myname, name, bfd_errmsg (bfd_get_error ())); | |
3be50301 JW |
171 | exit (1); |
172 | } | |
173 | ||
174 | if (!bfd_check_format (abfd, bfd_object)) | |
175 | { | |
fa21d299 AC |
176 | fprintf (stderr, "%s: can't load %s: %s\n", |
177 | myname, name, bfd_errmsg (bfd_get_error ())); | |
3be50301 JW |
178 | exit (1); |
179 | } | |
180 | ||
fa21d299 AC |
181 | /* This must be set before sim_open is called, because gdb assumes that |
182 | the simulator endianness is known immediately after the sim_open call. */ | |
183 | target_byte_order = bfd_big_endian (abfd) ? 4321 : 1234; | |
184 | ||
185 | sim_set_callbacks (NULL, &default_callback); | |
6834d493 | 186 | default_callback.init (&default_callback); |
3be50301 | 187 | |
9b280a86 MM |
188 | /* Ensure that any run-time initialisation that needs to be |
189 | performed by the simulator can occur. */ | |
bcd1475a | 190 | sd = sim_open (SIM_OPEN_STANDALONE, sim_argv); |
9b280a86 | 191 | |
3be50301 | 192 | for (s = abfd->sections; s; s = s->next) |
6834d493 | 193 | { |
fa21d299 AC |
194 | if (s->flags & SEC_LOAD) |
195 | { | |
196 | unsigned char *buffer = (unsigned char *)malloc ((size_t)(bfd_section_size (abfd, s))); | |
197 | if (buffer != NULL) | |
198 | { | |
199 | bfd_get_section_contents (abfd, | |
200 | s, | |
201 | buffer, | |
202 | 0, | |
203 | bfd_section_size (abfd, s)); | |
204 | sim_write (sd, s->vma, buffer, bfd_section_size (abfd, s)); | |
205 | /* FIXME: How come we don't free buffer? */ | |
206 | } | |
207 | else | |
208 | { | |
209 | fprintf (stderr, "%s: failed to allocate section buffer: %s\n", | |
210 | myname, bfd_errmsg (bfd_get_error ())); | |
211 | exit (1); | |
212 | } | |
213 | } | |
3be50301 JW |
214 | } |
215 | ||
216 | start_address = bfd_get_start_address (abfd); | |
fa21d299 | 217 | sim_create_inferior (sd, start_address, prog_args, NULL); |
6834d493 | 218 | |
3be50301 JW |
219 | if (trace) |
220 | { | |
221 | int done = 0; | |
222 | while (!done) | |
223 | { | |
fa21d299 | 224 | done = sim_trace (sd); |
6834d493 JW |
225 | } |
226 | } | |
3be50301 JW |
227 | else |
228 | { | |
fa21d299 | 229 | sim_resume (sd, 0, 0); |
3be50301 JW |
230 | } |
231 | if (verbose) | |
fa21d299 | 232 | sim_info (sd, 0); |
3be50301 | 233 | |
fa21d299 | 234 | sim_stop_reason (sd, &reason, &sigrc); |
6834d493 | 235 | |
fa21d299 | 236 | sim_close (sd, 0); |
9b280a86 | 237 | |
fa21d299 AC |
238 | /* If reason is sim_exited, then sigrc holds the exit code which we want |
239 | to return. If reason is sim_stopped or sim_signalled, then sigrc holds | |
240 | the signal that the simulator received; we want to return that to | |
241 | indicate failure. */ | |
242 | ||
243 | #ifdef SIM_H8300 /* FIXME: Ugh. grep for SLEEP in compile.c */ | |
244 | if (sigrc == SIGILL) | |
245 | abort (); | |
246 | sigrc = 0; | |
247 | #else | |
57bc1a72 MM |
248 | /* Why did we stop? */ |
249 | switch (reason) | |
250 | { | |
251 | case sim_signalled: | |
252 | case sim_stopped: | |
fa21d299 AC |
253 | if (sigrc != 0) |
254 | fprintf (stderr, "program stopped with signal %d.\n", sigrc); | |
57bc1a72 MM |
255 | break; |
256 | ||
257 | case sim_exited: | |
258 | break; | |
259 | } | |
fa21d299 | 260 | #endif |
57bc1a72 | 261 | |
3be50301 | 262 | return sigrc; |
6834d493 JW |
263 | } |
264 | ||
fa21d299 AC |
265 | static void |
266 | usage () | |
6834d493 | 267 | { |
fa21d299 AC |
268 | fprintf (stderr, "Usage: %s [options] program [program args]\n", myname); |
269 | fprintf (stderr, "Options:\n"); | |
270 | fprintf (stderr, "-a args Pass `args' to simulator.\n"); | |
271 | #ifdef SIM_HAVE_SIMCACHE | |
272 | fprintf (stderr, "-c size Set simulator cache size to `size'.\n"); | |
273 | #endif | |
274 | #ifdef SIM_H8300 | |
275 | fprintf (stderr, "-h Executable is for h8/300h or h8/300s.\n"); | |
276 | #endif | |
277 | fprintf (stderr, "-m size Set memory size of simulator, in bytes.\n"); | |
278 | #ifdef SIM_HAVE_PROFILE | |
279 | fprintf (stderr, "-p freq Set profiling frequency.\n"); | |
280 | fprintf (stderr, "-s size Set profiling size.\n"); | |
281 | #endif | |
282 | fprintf (stderr, "-t Perform instruction tracing.\n"); | |
283 | fprintf (stderr, " Note: Very few simulators support tracing.\n"); | |
284 | fprintf (stderr, "-v Verbose output.\n"); | |
285 | fprintf (stderr, "\n"); | |
286 | fprintf (stderr, "program args Arguments to pass to simulated program.\n"); | |
287 | fprintf (stderr, " Note: Very few simulators support this.\n"); | |
6834d493 JW |
288 | exit (1); |
289 | } |