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