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