xref: /netbsd-src/external/gpl3/gdb/dist/sim/rx/main.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /* main.c --- main function for stand-alone RX simulator.
2 
3 Copyright (C) 2005-2014 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 }
229