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