* elf64-ppc.c (dec_dynrel_count): Don't error when elf_gc_sweep_symbol
[external/binutils.git] / sim / rx / main.c
1 /* main.c --- main function for stand-alone RX simulator.
2
3 Copyright (C) 2005-2013 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 }