]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/rx/main.c
cd778d751a2ab902253be9add43f90331b929230
[thirdparty/binutils-gdb.git] / sim / rx / main.c
1 /* main.c --- main function for stand-alone RX simulator.
2
3 Copyright (C) 2005-2020 Free Software Foundation, Inc.
4 Contributed by Red Hat, Inc.
5
6 This file is part of the GNU simulators.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21
22 #include "config.h"
23 #include <stdio.h>
24 #include <string.h>
25 #ifdef HAVE_STDLIB_H
26 #include <stdlib.h>
27 #endif
28 #ifdef HAVE_UNISTD_H
29 #include <unistd.h>
30 #endif
31 #include <assert.h>
32 #include <setjmp.h>
33 #include <signal.h>
34 #ifdef HAVE_GETOPT_H
35 #include <getopt.h>
36 #endif
37
38 #include "bfd.h"
39
40 #include "cpu.h"
41 #include "mem.h"
42 #include "misc.h"
43 #include "load.h"
44 #include "trace.h"
45 #include "err.h"
46
47 static int disassemble = 0;
48
49 /* This must be higher than any other option index. */
50 #define OPT_ACT 400
51
52 #define ACT(E,A) (OPT_ACT + SIM_ERR_##E * SIM_ERRACTION_NUM_ACTIONS + SIM_ERRACTION_##A)
53
54 static struct option sim_options[] =
55 {
56 { "end-sim-args", 0, NULL, 'E' },
57 { "exit-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,EXIT) },
58 { "warn-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,WARN) },
59 { "ignore-null-deref", 0, NULL, ACT(NULL_POINTER_DEREFERENCE,IGNORE) },
60 { "exit-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,EXIT) },
61 { "warn-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,WARN) },
62 { "ignore-unwritten-pages", 0, NULL, ACT(READ_UNWRITTEN_PAGES,IGNORE) },
63 { "exit-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,EXIT) },
64 { "warn-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,WARN) },
65 { "ignore-unwritten-bytes", 0, NULL, ACT(READ_UNWRITTEN_BYTES,IGNORE) },
66 { "exit-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,EXIT) },
67 { "warn-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,WARN) },
68 { "ignore-corrupt-stack", 0, NULL, ACT(CORRUPT_STACK,IGNORE) },
69 { 0, 0, 0, 0 }
70 };
71
72 static void
73 done (int exit_code)
74 {
75 if (verbose)
76 {
77 stack_heap_stats ();
78 mem_usage_stats ();
79 /* Only use comma separated numbers when being very verbose.
80 Comma separated numbers are hard to parse in awk scripts. */
81 if (verbose > 1)
82 printf ("insns: %14s\n", comma (rx_cycles));
83 else
84 printf ("insns: %u\n", rx_cycles);
85
86 pipeline_stats ();
87 }
88 exit (exit_code);
89 }
90
91 int
92 main (int argc, char **argv)
93 {
94 int o;
95 int save_trace;
96 bfd *prog;
97 int rc;
98
99 /* By default, we exit when an execution error occurs. */
100 execution_error_init_standalone ();
101
102 while ((o = getopt_long (argc, argv, "tvdeEwi", sim_options, NULL)) != -1)
103 {
104 if (o == 'E')
105 /* Stop processing the command line. This is so that any remaining
106 words on the command line that look like arguments will be passed
107 on to the program being simulated. */
108 break;
109
110 if (o >= OPT_ACT)
111 {
112 int e, a;
113
114 o -= OPT_ACT;
115 e = o / SIM_ERRACTION_NUM_ACTIONS;
116 a = o % SIM_ERRACTION_NUM_ACTIONS;
117 execution_error_set_action (e, a);
118 }
119 else switch (o)
120 {
121 case 't':
122 trace++;
123 break;
124 case 'v':
125 verbose++;
126 break;
127 case 'd':
128 disassemble++;
129 break;
130 case 'e':
131 execution_error_init_standalone ();
132 break;
133 case 'w':
134 execution_error_warn_all ();
135 break;
136 case 'i':
137 execution_error_ignore_all ();
138 break;
139 case '?':
140 {
141 int i;
142 fprintf (stderr,
143 "usage: run [options] program [arguments]\n");
144 fprintf (stderr,
145 "\t-v\t- increase verbosity.\n"
146 "\t-t\t- trace.\n"
147 "\t-d\t- disassemble.\n"
148 "\t-E\t- stop processing sim args\n"
149 "\t-e\t- exit on all execution errors.\n"
150 "\t-w\t- warn (do not exit) on all execution errors.\n"
151 "\t-i\t- ignore all execution errors.\n");
152 for (i=0; sim_options[i].name; i++)
153 fprintf (stderr, "\t--%s\n", sim_options[i].name);
154 exit (1);
155 }
156 }
157 }
158
159 prog = bfd_openr (argv[optind], 0);
160 if (!prog)
161 {
162 fprintf (stderr, "Can't read %s\n", argv[optind]);
163 exit (1);
164 }
165
166 if (!bfd_check_format (prog, bfd_object))
167 {
168 fprintf (stderr, "%s not a rx program\n", argv[optind]);
169 exit (1);
170 }
171
172 init_regs ();
173
174 rx_in_gdb = 0;
175 save_trace = trace;
176 trace = 0;
177 rx_load (prog, NULL);
178 trace = save_trace;
179
180 sim_disasm_init (prog);
181
182 enable_counting = verbose;
183
184 rc = setjmp (decode_jmp_buf);
185
186 if (rc == 0)
187 {
188 if (!trace && !disassemble)
189 {
190 /* This will longjmp to the above if an exception
191 happens. */
192 for (;;)
193 decode_opcode ();
194 }
195 else
196 while (1)
197 {
198
199 if (trace)
200 printf ("\n");
201
202 if (disassemble)
203 {
204 enable_counting = 0;
205 sim_disasm_one ();
206 enable_counting = verbose;
207 }
208
209 rc = decode_opcode ();
210
211 if (trace)
212 trace_register_changes ();
213 }
214 }
215
216 if (RX_HIT_BREAK (rc))
217 done (1);
218 else if (RX_EXITED (rc))
219 done (RX_EXIT_STATUS (rc));
220 else if (RX_STOPPED (rc))
221 {
222 if (verbose)
223 printf("Stopped on signal %d\n", RX_STOP_SIG (rc));
224 exit(1);
225 }
226 done (0);
227 exit (0);
228 }