1 /* Simulator option handling.
2 Copyright (C) 1996, 1997 Free Software Foundation, Inc.
3 Contributed by Cygnus Support.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
29 #include "libiberty.h"
30 #include "../libiberty/alloca-conf.h"
31 #include "sim-options.h"
34 /* This is defined in sim-config.h. */
35 #ifndef MAX_NR_PROCESSORS
36 #define MAX_NR_PROCESSORS 1
39 /* Add a set of options to the simulator.
40 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
41 This is intended to be called by modules in their `install' handler. */
44 sim_add_option_table (sd
, table
)
48 struct option_list
*ol
= ((struct option_list
*)
49 xmalloc (sizeof (struct option_list
)));
51 /* Note: The list is constructed in the reverse order we're called so
52 later calls will override earlier ones (in case that ever happens).
53 This is the intended behaviour. */
54 ol
->next
= STATE_OPTIONS (sd
);
56 STATE_OPTIONS (sd
) = ol
;
61 /* Standard option table.
62 Modules may specify additional ones.
63 The caller of sim_parse_args may also specify additional options
64 by calling sim_add_option_table first. */
66 static DECLARE_OPTION_HANDLER (standard_option_handler
);
68 /* FIXME: We shouldn't print in --help output options that aren't usable.
69 Some fine tuning will be necessary. One can either move less general
70 options to another table or use a HAVE_FOO macro to ifdef out unavailable
73 #define OPTION_DEBUG_INSN (OPTION_START + 0)
74 #define OPTION_DEBUG_FILE (OPTION_START + 1)
75 #define OPTION_TRACE_INSN (OPTION_START + 2)
76 #define OPTION_TRACE_DECODE (OPTION_START + 3)
77 #define OPTION_TRACE_EXTRACT (OPTION_START + 4)
78 #define OPTION_TRACE_LINENUM (OPTION_START + 5)
79 #define OPTION_TRACE_MEMORY (OPTION_START + 6)
80 #define OPTION_TRACE_MODEL (OPTION_START + 7)
81 #define OPTION_TRACE_ALU (OPTION_START + 8)
82 #define OPTION_TRACE_FILE (OPTION_START + 9)
83 #define OPTION_PROFILE_INSN (OPTION_START + 10)
84 #define OPTION_PROFILE_MEMORY (OPTION_START + 11)
85 #define OPTION_PROFILE_MODEL (OPTION_START + 12)
86 #define OPTION_PROFILE_SIMCACHE (OPTION_START + 13)
87 #define OPTION_PROFILE_FILE (OPTION_START + 14)
89 static const OPTION standard_options
[] =
91 { {"verbose", no_argument
, NULL
, 'v'},
92 'v', NULL
, "Verbose output",
93 standard_option_handler
},
95 { {"debug", no_argument
, NULL
, 'D'},
96 'D', NULL
, "Print debugging messages",
97 standard_option_handler
},
98 { {"debug-insn", no_argument
, NULL
, OPTION_DEBUG_INSN
},
99 '\0', NULL
, "Print instruction debugging messages",
100 standard_option_handler
},
101 { {"debug-file", required_argument
, NULL
, OPTION_DEBUG_FILE
},
102 '\0', "FILE NAME", "Specify debugging output file",
103 standard_option_handler
},
105 { {"trace", no_argument
, NULL
, 't'},
106 't', NULL
, "Perform tracing",
107 standard_option_handler
},
108 { {"trace-insn", no_argument
, NULL
, OPTION_TRACE_INSN
},
109 '\0', NULL
, "Perform instruction tracing",
110 standard_option_handler
},
111 { {"trace-decode", no_argument
, NULL
, OPTION_TRACE_DECODE
},
112 '\0', NULL
, "Perform instruction decoding tracing",
113 standard_option_handler
},
114 { {"trace-extract", no_argument
, NULL
, OPTION_TRACE_EXTRACT
},
115 '\0', NULL
, "Perform instruction extraction tracing",
116 standard_option_handler
},
117 { {"trace-linenum", no_argument
, NULL
, OPTION_TRACE_LINENUM
},
118 '\0', NULL
, "Perform line number tracing",
119 standard_option_handler
},
120 { {"trace-memory", no_argument
, NULL
, OPTION_TRACE_MEMORY
},
121 '\0', NULL
, "Perform memory tracing",
122 standard_option_handler
},
123 { {"trace-model", no_argument
, NULL
, OPTION_TRACE_MODEL
},
124 '\0', NULL
, "Perform model tracing",
125 standard_option_handler
},
126 { {"trace-alu", no_argument
, NULL
, OPTION_TRACE_ALU
},
127 '\0', NULL
, "Perform ALU tracing",
128 standard_option_handler
},
129 { {"trace-file", required_argument
, NULL
, OPTION_TRACE_FILE
},
130 '\0', "FILE NAME", "Specify tracing output file",
131 standard_option_handler
},
133 #ifdef SIM_H8300 /* FIXME: Should be movable to h8300 dir. */
134 { {"h8300h", no_argument
, NULL
, 'h'},
135 'h', NULL
, "Indicate the CPU is h8/300h or h8/300s",
136 standard_option_handler
},
139 #ifdef SIM_HAVE_SIMCACHE
140 { {"simcache-size", required_argument
, NULL
, 'c'},
141 'c', "SIM CACHE SIZE", "Specify size of simulator instruction cache",
142 standard_option_handler
},
145 #ifdef SIM_HAVE_FLATMEM
146 { {"mem-size", required_argument
, NULL
, 'm'},
147 'm', "MEMORY SIZE", "Specify memory size",
148 standard_option_handler
},
151 #ifdef SIM_HAVE_MAX_INSNS
152 { {"max-insns", required_argument
, NULL
, 'M'},
153 'M', "MAX INSNS", "Specify maximum instructions to execute",
154 standard_option_handler
},
157 #ifdef SIM_HAVE_PROFILE
158 { {"profile", no_argument
, NULL
, 'p'},
159 'p', NULL
, "Perform profiling",
160 standard_option_handler
},
161 { {"profile-insn", no_argument
, NULL
, OPTION_PROFILE_INSN
},
162 '\0', NULL
, "Perform instruction profiling",
163 standard_option_handler
},
164 { {"profile-memory", no_argument
, NULL
, OPTION_PROFILE_MEMORY
},
165 '\0', NULL
, "Perform memory profiling",
166 standard_option_handler
},
167 { {"profile-model", no_argument
, NULL
, OPTION_PROFILE_MODEL
},
168 '\0', NULL
, "Perform model profiling",
169 standard_option_handler
},
170 { {"profile-simcache", no_argument
, NULL
, OPTION_PROFILE_SIMCACHE
},
171 '\0', NULL
, "Perform simulator execution cache profiling",
172 standard_option_handler
},
173 { {"profile-file", required_argument
, NULL
, OPTION_PROFILE_FILE
},
174 '\0', "FILE NAME", "Specify profile output file",
175 standard_option_handler
},
176 #ifdef SIM_HAVE_PROFILE_PC
177 { {"profile-pc-frequency", required_argument
, NULL
, 'F'},
178 'F', "PC PROFILE FREQUENCY", "Turn on PC profiling at specified frequency",
179 standard_option_handler
},
180 { {"profile-pc-size", required_argument
, NULL
, 'S'},
181 'S', "PC PROFILE SIZE", "Specify PC profiling size",
182 standard_option_handler
},
184 #endif /* SIM_HAVE_PROFILE */
186 { {"help", no_argument
, NULL
, 'H'},
187 'H', NULL
, "Print help information",
188 standard_option_handler
},
190 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
194 standard_option_handler (sd
, opt
, arg
)
205 STATE_VERBOSE_P (sd
) = 1;
210 sim_io_eprintf (sd
, "Debugging not compiled in, `-D' ignored\n");
213 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
214 for (i
= 0; i
< MAX_DEBUG_VALUES
; ++i
)
215 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
219 case OPTION_DEBUG_INSN
:
221 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-insn' ignored\n");
224 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
225 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[DEBUG_INSN_IDX
] = 1;
229 case OPTION_DEBUG_FILE
:
231 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-file' ignored\n");
234 FILE *f
= fopen (arg
, "w");
238 sim_io_eprintf (sd
, "Unable to open debug output file `%s'\n", arg
);
241 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
242 CPU_DEBUG_FILE (STATE_CPU (sd
, n
)) = f
;
248 sim_io_eprintf (sd
, "Tracing not compiled in, `-t' ignored\n");
251 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
252 for (i
= 0; i
< MAX_TRACE_VALUES
; ++i
)
253 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
257 case OPTION_TRACE_INSN
:
258 if (! (WITH_TRACE
& (1 << TRACE_INSN_IDX
)))
259 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-insn' ignored\n");
262 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
263 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_INSN_IDX
] = 1;
267 case OPTION_TRACE_DECODE
:
268 if (! (WITH_TRACE
& (1 << TRACE_DECODE_IDX
)))
269 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-decode' ignored\n");
272 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
273 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_DECODE_IDX
] = 1;
277 case OPTION_TRACE_EXTRACT
:
278 if (! (WITH_TRACE
& (1 << TRACE_EXTRACT_IDX
)))
279 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-extract' ignored\n");
282 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
283 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_EXTRACT_IDX
] = 1;
287 case OPTION_TRACE_LINENUM
:
288 if (! (WITH_TRACE
& (1 << TRACE_LINENUM_IDX
)))
289 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-linenum' ignored\n");
292 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
293 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_LINENUM_IDX
] = 1;
297 case OPTION_TRACE_MEMORY
:
298 if (! (WITH_TRACE
& (1 << TRACE_MEMORY_IDX
)))
299 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-memory' ignored\n");
302 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
303 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MEMORY_IDX
] = 1;
307 case OPTION_TRACE_MODEL
:
308 if (! (WITH_TRACE
& (1 << TRACE_MODEL_IDX
)))
309 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-model' ignored\n");
312 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
313 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_MODEL_IDX
] = 1;
317 case OPTION_TRACE_ALU
:
318 if (! (WITH_TRACE
& (1 << TRACE_ALU_IDX
)))
319 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-alu' ignored\n");
322 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
323 CPU_TRACE_FLAGS (STATE_CPU (sd
, n
))[TRACE_ALU_IDX
] = 1;
327 case OPTION_TRACE_FILE
:
329 sim_io_eprintf (sd
, "Tracing not compiled in, `--trace-file' ignored\n");
332 FILE *f
= fopen (arg
, "w");
336 sim_io_eprintf (sd
, "Unable to open trace output file `%s'\n", arg
);
339 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
340 CPU_TRACE_FILE (STATE_CPU (sd
, n
)) = f
;
344 #ifdef SIM_H8300 /* FIXME: Can be moved to h8300 dir. */
350 #ifdef SIM_HAVE_SIMCACHE
352 n
= strtol (arg
, NULL
, 0);
355 sim_io_eprintf (sd
, "Invalid simulator cache size: %d", n
);
358 STATE_SIMCACHE_SIZE (sd
) = n
;
362 #ifdef SIM_HAVE_FLATMEM
364 ul
= strtol (arg
, NULL
, 0);
365 /* 16384: some minimal amount */
366 if (! isdigit (arg
[0]) || ul
< 16384)
368 sim_io_eprintf (sd
, "Invalid memory size `%s'", arg
);
371 STATE_MEM_SIZE (sd
) = ul
;
375 #ifdef SIM_HAVE_MAX_INSNS
377 ul
= strtoul (arg
, NULL
, 0);
378 if (! isdigit (arg
[0]))
380 sim_io_eprintf (sd
, "Invalid maximum instruction count: `%s'", arg
);
383 STATE_MAX_INSNS (sd
) = ul
;
387 #ifdef SIM_HAVE_PROFILE
390 sim_io_eprintf (sd
, "Profile not compiled in, -p option ignored\n");
393 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
394 for (i
= 0; i
< MAX_PROFILE_VALUES
; ++i
)
395 CPU_PROFILE_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
399 case OPTION_PROFILE_INSN
:
400 if (! (WITH_PROFILE
& (1 << PROFILE_INSN_IDX
)))
401 sim_io_eprintf (sd
, "Profiling not compiled in, `--profile-insn' ignored\n");
404 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
405 CPU_PROFILE_FLAGS (STATE_CPU (sd
, n
))[PROFILE_INSN_IDX
] = 1;
409 case OPTION_PROFILE_MEMORY
:
410 if (! (WITH_PROFILE
& (1 << PROFILE_MEMORY_IDX
)))
411 sim_io_eprintf (sd
, "Profiling not compiled in, `--profile-memory' ignored\n");
414 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
415 CPU_PROFILE_FLAGS (STATE_CPU (sd
, n
))[PROFILE_MEMORY_IDX
] = 1;
419 case OPTION_PROFILE_MODEL
:
420 if (! (WITH_PROFILE
& (1 << PROFILE_MODEL_IDX
)))
421 sim_io_eprintf (sd
, "Profiling not compiled in, `--profile-model' ignored\n");
424 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
425 CPU_PROFILE_FLAGS (STATE_CPU (sd
, n
))[PROFILE_MODEL_IDX
] = 1;
429 case OPTION_PROFILE_SIMCACHE
:
430 if (! (WITH_PROFILE
& (1 << PROFILE_SIMCACHE_IDX
)))
431 sim_io_eprintf (sd
, "Profiling not compiled in, `--profile-simcache' ignored\n");
434 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
435 CPU_PROFILE_FLAGS (STATE_CPU (sd
, n
))[PROFILE_SIMCACHE_IDX
] = 1;
439 case OPTION_PROFILE_FILE
:
440 /* FIXME: Might want this to apply to pc profiling only,
441 or have two profile file options. */
443 sim_io_eprintf (sd
, "Profiling not compiled in, `--profile-file' ignored\n");
446 FILE *f
= fopen (arg
, "w");
450 sim_io_eprintf (sd
, "Unable to open profile output file `%s'\n", arg
);
453 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
454 CPU_PROFILE_FILE (STATE_CPU (sd
, n
)) = f
;
458 #ifdef SIM_HAVE_PROFILE_PC
460 STATE_PROFILE_PC_FREQUENCY (sd
) = atoi (arg
);
461 /* FIXME: Validate arg. */
464 STATE_PROFILE_PC_SIZE (sd
) = atoi (arg
);
465 /* FIXME: Validate arg. */
468 #endif /* SIM_HAVE_PROFILE */
472 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
474 /* FIXME: 'twould be nice to do something similar if gdb. */
481 /* Initialize common parts before argument processing.
482 Called by sim_open. */
485 sim_pre_argv_init (sd
, myname
)
489 STATE_MY_NAME (sd
) = myname
+ strlen (myname
);
490 while (STATE_MY_NAME (sd
) > myname
&& STATE_MY_NAME (sd
)[-1] != '/')
491 --STATE_MY_NAME (sd
);
493 if (sim_add_option_table (sd
, standard_options
) != SIM_RC_OK
)
499 /* Return non-zero if arg is a duplicate argument.
500 If ARG is NULL, initialize. */
502 #define ARG_HASH_SIZE 97
503 #define ARG_HASH(a) ((256 * (unsigned char) a[0] + (unsigned char) a[1]) % ARG_HASH_SIZE)
510 static char **arg_table
= NULL
;
514 if (arg_table
== NULL
)
515 arg_table
= (char **) xmalloc (ARG_HASH_SIZE
* sizeof (char *));
516 memset (arg_table
, 0, ARG_HASH_SIZE
* sizeof (char *));
520 hash
= ARG_HASH (arg
);
521 while (arg_table
[hash
] != NULL
)
523 if (strcmp (arg
, arg_table
[hash
]) == 0)
525 /* We assume there won't be more than ARG_HASH_SIZE arguments so we
526 don't check if the table is full. */
527 if (++hash
== ARG_HASH_SIZE
)
530 arg_table
[hash
] = arg
;
534 /* Called by sim_open to parse the arguments. */
537 sim_parse_args (sd
, argv
)
541 int i
, argc
, num_opts
;
542 char *p
, *short_options
;
543 /* The `val' option struct entry is dynamically assigned for options that
544 only come in the long form. ORIG_VAL is used to get the original value
547 struct option
*lp
, *long_options
;
548 const struct option_list
*ol
;
550 OPTION_HANDLER
**handlers
;
552 /* Count the number of arguments. */
553 for (argc
= 0; argv
[argc
] != NULL
; ++argc
)
556 /* Count the number of options. */
558 for (ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
559 for (opt
= ol
->options
; opt
->opt
.name
!= NULL
; ++opt
)
562 /* Initialize duplicate argument checker. */
563 (void) dup_arg_p (NULL
);
565 /* Build the option table for getopt. */
566 long_options
= (struct option
*) alloca ((num_opts
+ 1) * sizeof (struct option
));
568 short_options
= (char *) alloca (num_opts
* 3 + 1);
570 #if 0 /* ??? necessary anymore? */
571 /* Set '+' as first char so argument permutation isn't done. This is done
572 to workaround a problem with invoking getopt_long in run.c.: optind gets
573 decremented when the program name is reached. */
576 handlers
= (OPTION_HANDLER
**) alloca (256 * sizeof (OPTION_HANDLER
*));
577 memset (handlers
, 0, 256 * sizeof (OPTION_HANDLER
*));
578 orig_val
= (char *) alloca (256);
579 for (i
= OPTION_START
, ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
580 for (opt
= ol
->options
; opt
->opt
.name
!= NULL
; ++opt
)
582 if (dup_arg_p (opt
->opt
.name
))
584 if (opt
->shortopt
!= 0)
586 *p
++ = opt
->shortopt
;
587 if (opt
->opt
.has_arg
== required_argument
)
589 else if (opt
->opt
.has_arg
== optional_argument
)
590 { *p
++ = ':'; *p
++ = ':'; }
593 /* Dynamically assign `val' numbers for long options that don't have
594 a short option equivalent. */
595 if (OPTION_LONG_ONLY_P (opt
->opt
.val
))
597 handlers
[(unsigned char) lp
->val
] = opt
->handler
;
598 orig_val
[(unsigned char) lp
->val
] = opt
->opt
.val
;
604 /* Ensure getopt is initialized. */
610 optc
= getopt_long (argc
, argv
, short_options
, long_options
, &longind
);
613 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
614 STATE_PROG_ARGV (sd
) = argv
+ optind
;
620 if ((*handlers
[optc
]) (sd
, orig_val
[optc
], optarg
) == SIM_RC_FAIL
)
627 /* Print help messages for the options. */
633 const struct option_list
*ol
;
636 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
637 sim_io_printf (sd
, "Usage: %s [options] program [program args]\n",
640 /* Initialize duplicate argument checker. */
641 (void) dup_arg_p (NULL
);
643 sim_io_printf (sd
, "Options:\n");
644 for (ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
645 for (opt
= ol
->options
; opt
->opt
.name
!= NULL
; ++opt
)
650 if (dup_arg_p (opt
->opt
.name
))
653 if (opt
->doc
== NULL
)
656 sim_io_printf (sd
, " ");
664 if (o
->shortopt
!= '\0')
666 sim_io_printf (sd
, "%s-%c", comma
? ", " : "", o
->shortopt
);
667 len
+= (comma
? 2 : 0) + 2;
670 if (o
->opt
.has_arg
!= optional_argument
)
672 sim_io_printf (sd
, " ");
675 sim_io_printf (sd
, "%s", o
->arg
);
676 len
+= strlen (o
->arg
);
682 while (o
->opt
.name
!= NULL
&& o
->doc
== NULL
);
687 if (o
->opt
.name
!= NULL
)
689 sim_io_printf (sd
, "%s--%s",
692 len
+= ((comma
? 2 : 0)
694 + strlen (o
->opt
.name
));
697 sim_io_printf (sd
, " %s", o
->arg
);
698 len
+= 1 + strlen (o
->arg
);
704 while (o
->opt
.name
!= NULL
&& o
->doc
== NULL
);
708 sim_io_printf (sd
, "\n");
712 for (; len
< 30; len
++)
713 sim_io_printf (sd
, " ");
715 sim_io_printf (sd
, "%s\n", opt
->doc
);
718 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
720 sim_io_printf (sd
, "\n");
721 sim_io_printf (sd
, "program args Arguments to pass to simulated program.\n");
722 sim_io_printf (sd
, " Note: Very few simulators support this.\n");
This page took 0.046733 seconds and 5 git commands to generate.