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