1 /* Simulator option handling.
2 Copyright (C) 1996-2023 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 3 of the License, or
10 (at your option) any later version.
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
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* This must come before any other includes. */
32 #include "libiberty.h"
35 #include "sim-options.h"
37 #include "sim-assert.h"
40 /* Add a set of options to the simulator.
41 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry.
42 This is intended to be called by modules in their `install' handler. */
45 sim_add_option_table (SIM_DESC sd
, sim_cpu
*cpu
, const OPTION
*table
)
47 struct option_list
*ol
= ((struct option_list
*)
48 xmalloc (sizeof (struct option_list
)));
50 /* Note: The list is constructed in the reverse order we're called so
51 later calls will override earlier ones (in case that ever happens).
52 This is the intended behaviour. */
56 ol
->next
= CPU_OPTIONS (cpu
);
58 CPU_OPTIONS (cpu
) = ol
;
62 ol
->next
= STATE_OPTIONS (sd
);
64 STATE_OPTIONS (sd
) = ol
;
70 /* Standard option table.
71 Modules may specify additional ones.
72 The caller of sim_parse_args may also specify additional options
73 by calling sim_add_option_table first. */
75 static DECLARE_OPTION_HANDLER (standard_option_handler
);
77 /* FIXME: We shouldn't print in --help output options that aren't usable.
78 Some fine tuning will be necessary. One can either move less general
79 options to another table or use a HAVE_FOO macro to ifdef out unavailable
82 /* ??? One might want to conditionally compile out the entries that
83 aren't enabled. There's a distinction, however, between options a
84 simulator can't support and options that haven't been configured in.
85 Certainly options a simulator can't support shouldn't appear in the
86 output of --help. Whether the same thing applies to options that haven't
87 been configured in or not isn't something I can get worked up over.
88 [Note that conditionally compiling them out might simply involve moving
89 the option to another table.]
90 If you decide to conditionally compile them out as well, delete this
91 comment and add a comment saying that that is the rule. */
94 OPTION_DEBUG_INSN
= OPTION_START
,
100 OPTION_ARCHITECTURE_INFO
,
117 static const OPTION standard_options
[] =
119 { {"verbose", no_argument
, NULL
, OPTION_VERBOSE
},
120 'v', NULL
, "Verbose output",
121 standard_option_handler
, NULL
},
123 { {"endian", required_argument
, NULL
, OPTION_ENDIAN
},
124 'E', "B|big|L|little", "Set endianness",
125 standard_option_handler
, NULL
},
127 /* This option isn't supported unless all choices are supported in keeping
128 with the goal of not printing in --help output things the simulator can't
129 do [as opposed to things that just haven't been configured in]. */
130 { {"environment", required_argument
, NULL
, OPTION_ENVIRONMENT
},
131 '\0', "user|virtual|operating", "Set running environment",
132 standard_option_handler
},
134 { {"alignment", required_argument
, NULL
, OPTION_ALIGNMENT
},
135 '\0', "strict|nonstrict|forced", "Set memory access alignment",
136 standard_option_handler
},
138 { {"debug", no_argument
, NULL
, OPTION_DEBUG
},
139 'D', NULL
, "Print debugging messages",
140 standard_option_handler
},
141 { {"debug-insn", no_argument
, NULL
, OPTION_DEBUG_INSN
},
142 '\0', NULL
, "Print instruction debugging messages",
143 standard_option_handler
},
144 { {"debug-file", required_argument
, NULL
, OPTION_DEBUG_FILE
},
145 '\0', "FILE NAME", "Specify debugging output file",
146 standard_option_handler
},
148 { {"do-command", required_argument
, NULL
, OPTION_DO_COMMAND
},
149 '\0', "COMMAND", ""/*undocumented*/,
150 standard_option_handler
},
152 { {"help", no_argument
, NULL
, OPTION_HELP
},
153 'h', NULL
, "Print help information",
154 standard_option_handler
},
155 { {"version", no_argument
, NULL
, OPTION_VERSION
},
156 '\0', NULL
, "Print version information",
157 standard_option_handler
},
159 { {"architecture", required_argument
, NULL
, OPTION_ARCHITECTURE
},
160 '\0', "MACHINE", "Specify the architecture to use",
161 standard_option_handler
},
162 { {"architecture-info", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
163 '\0', NULL
, "List supported architectures",
164 standard_option_handler
},
165 { {"info-architecture", no_argument
, NULL
, OPTION_ARCHITECTURE_INFO
},
167 standard_option_handler
},
169 { {"target", required_argument
, NULL
, OPTION_TARGET
},
170 '\0', "BFDNAME", "Specify the object-code format for the object files",
171 standard_option_handler
},
172 { {"target-info", no_argument
, NULL
, OPTION_TARGET_INFO
},
173 '\0', NULL
, "List supported targets", standard_option_handler
},
174 { {"info-target", no_argument
, NULL
, OPTION_TARGET_INFO
},
175 '\0', NULL
, NULL
, standard_option_handler
},
177 { {"load-lma", no_argument
, NULL
, OPTION_LOAD_LMA
},
179 "Use VMA or LMA addresses when loading image (default LMA)",
180 standard_option_handler
, "load-{lma,vma}" },
181 { {"load-vma", no_argument
, NULL
, OPTION_LOAD_VMA
},
182 '\0', NULL
, "", standard_option_handler
, "" },
184 { {"sysroot", required_argument
, NULL
, OPTION_SYSROOT
},
186 "Root for system calls with absolute file-names and cwd at start",
187 standard_option_handler
, NULL
},
189 { {"argv0", required_argument
, NULL
, OPTION_ARGV0
},
190 '\0', "ARGV0", "Set argv[0] to the specified string",
191 standard_option_handler
, NULL
},
193 { {"env-set", required_argument
, NULL
, OPTION_ENV_SET
},
194 '\0', "VAR=VAL", "Set the variable in the program's environment",
195 standard_option_handler
, NULL
},
196 { {"env-unset", required_argument
, NULL
, OPTION_ENV_UNSET
},
197 '\0', "VAR", "Unset the variable in the program's environment",
198 standard_option_handler
, NULL
},
199 { {"env-clear", no_argument
, NULL
, OPTION_ENV_CLEAR
},
200 '\0', NULL
, "Clear the program's environment",
201 standard_option_handler
, NULL
},
203 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
, NULL
}
207 env_set (SIM_DESC sd
, const char *arg
)
213 if (STATE_PROG_ENVP (sd
) == NULL
)
214 STATE_PROG_ENVP (sd
) = dupargv (environ
);
216 eq
= strchr (arg
, '=');
219 sim_io_eprintf (sd
, "invalid syntax when setting env var `%s'"
220 ": missing value", arg
);
223 /* Include the = in the comparison below. */
224 varlen
= eq
- arg
+ 1;
226 /* If we can find an existing variable, replace it. */
227 envp
= STATE_PROG_ENVP (sd
);
228 for (i
= 0; envp
[i
]; ++i
)
230 if (strncmp (envp
[i
], arg
, varlen
) == 0)
233 envp
[i
] = xstrdup (arg
);
238 /* If we didn't find the var, add it. */
241 envp
= xrealloc (envp
, (i
+ 2) * sizeof (char *));
242 envp
[i
] = xstrdup (arg
);
244 STATE_PROG_ENVP (sd
) = envp
;
251 standard_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
,
252 char *arg
, int is_command
)
256 switch ((STANDARD_OPTIONS
) opt
)
259 STATE_VERBOSE_P (sd
) = 1;
263 if (strcmp (arg
, "big") == 0 || strcmp (arg
, "B") == 0)
265 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_LITTLE
)
267 sim_io_eprintf (sd
, "Simulator compiled for little endian only.\n");
270 /* FIXME:wip: Need to set something in STATE_CONFIG. */
271 current_target_byte_order
= BFD_ENDIAN_BIG
;
273 else if (strcmp (arg
, "little") == 0 || strcmp (arg
, "L") == 0)
275 if (WITH_TARGET_BYTE_ORDER
== BFD_ENDIAN_BIG
)
277 sim_io_eprintf (sd
, "Simulator compiled for big endian only.\n");
280 /* FIXME:wip: Need to set something in STATE_CONFIG. */
281 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
285 sim_io_eprintf (sd
, "Invalid endian specification `%s'\n", arg
);
290 case OPTION_ENVIRONMENT
:
291 if (strcmp (arg
, "user") == 0)
292 STATE_ENVIRONMENT (sd
) = USER_ENVIRONMENT
;
293 else if (strcmp (arg
, "virtual") == 0)
294 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
295 else if (strcmp (arg
, "operating") == 0)
296 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
299 sim_io_eprintf (sd
, "Invalid environment specification `%s'\n", arg
);
302 if (WITH_ENVIRONMENT
!= ALL_ENVIRONMENT
303 && WITH_ENVIRONMENT
!= STATE_ENVIRONMENT (sd
))
306 switch (WITH_ENVIRONMENT
)
308 case USER_ENVIRONMENT
: type
= "user"; break;
309 case VIRTUAL_ENVIRONMENT
: type
= "virtual"; break;
310 case OPERATING_ENVIRONMENT
: type
= "operating"; break;
313 sim_io_eprintf (sd
, "Simulator compiled for the %s environment only.\n",
319 case OPTION_ALIGNMENT
:
320 if (strcmp (arg
, "strict") == 0)
322 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== STRICT_ALIGNMENT
)
324 current_alignment
= STRICT_ALIGNMENT
;
328 else if (strcmp (arg
, "nonstrict") == 0)
330 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== NONSTRICT_ALIGNMENT
)
332 current_alignment
= NONSTRICT_ALIGNMENT
;
336 else if (strcmp (arg
, "forced") == 0)
338 if (WITH_ALIGNMENT
== 0 || WITH_ALIGNMENT
== FORCED_ALIGNMENT
)
340 current_alignment
= FORCED_ALIGNMENT
;
346 sim_io_eprintf (sd
, "Invalid alignment specification `%s'\n", arg
);
349 switch (WITH_ALIGNMENT
)
351 case STRICT_ALIGNMENT
:
352 sim_io_eprintf (sd
, "Simulator compiled for strict alignment only.\n");
354 case NONSTRICT_ALIGNMENT
:
355 sim_io_eprintf (sd
, "Simulator compiled for nonstrict alignment only.\n");
357 case FORCED_ALIGNMENT
:
358 sim_io_eprintf (sd
, "Simulator compiled for forced alignment only.\n");
366 sim_io_eprintf (sd
, "Debugging not compiled in, `-D' ignored\n");
369 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
370 for (i
= 0; i
< MAX_DEBUG_VALUES
; ++i
)
371 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[i
] = 1;
375 case OPTION_DEBUG_INSN
:
377 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-insn' ignored\n");
380 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
381 CPU_DEBUG_FLAGS (STATE_CPU (sd
, n
))[DEBUG_INSN_IDX
] = 1;
385 case OPTION_DEBUG_FILE
:
387 sim_io_eprintf (sd
, "Debugging not compiled in, `--debug-file' ignored\n");
390 FILE *f
= fopen (arg
, "w");
394 sim_io_eprintf (sd
, "Unable to open debug output file `%s'\n", arg
);
397 for (n
= 0; n
< MAX_NR_PROCESSORS
; ++n
)
398 CPU_DEBUG_FILE (STATE_CPU (sd
, n
)) = f
;
402 case OPTION_DO_COMMAND
:
403 sim_do_command (sd
, arg
);
406 case OPTION_ARCHITECTURE
:
408 const struct bfd_arch_info
*ap
= bfd_scan_arch (arg
);
411 sim_io_eprintf (sd
, "Architecture `%s' unknown\n", arg
);
414 STATE_ARCHITECTURE (sd
) = ap
;
418 case OPTION_ARCHITECTURE_INFO
:
420 const char **list
= bfd_arch_list ();
424 sim_io_printf (sd
, "Possible architectures:");
425 for (lp
= list
; *lp
!= NULL
; lp
++)
426 sim_io_printf (sd
, " %s", *lp
);
427 sim_io_printf (sd
, "\n");
434 STATE_TARGET (sd
) = xstrdup (arg
);
438 case OPTION_TARGET_INFO
:
440 const char **list
= bfd_target_list ();
444 sim_io_printf (sd
, "Possible targets:");
445 for (lp
= list
; *lp
!= NULL
; lp
++)
446 sim_io_printf (sd
, " %s", *lp
);
447 sim_io_printf (sd
, "\n");
452 case OPTION_LOAD_LMA
:
454 STATE_LOAD_AT_LMA_P (sd
) = 1;
458 case OPTION_LOAD_VMA
:
460 STATE_LOAD_AT_LMA_P (sd
) = 0;
465 sim_print_help (sd
, is_command
);
466 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
468 /* FIXME: 'twould be nice to do something similar if gdb. */
472 sim_print_version (sd
, is_command
);
473 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
478 /* Don't leak memory in the odd event that there's lots of
479 --sysroot=... options. We treat "" specially since this
480 is the statically initialized value and cannot free it. */
481 if (simulator_sysroot
[0] != '\0')
482 free (simulator_sysroot
);
484 simulator_sysroot
= xstrdup (arg
);
486 simulator_sysroot
= "";
490 free (STATE_PROG_ARGV0 (sd
));
491 STATE_PROG_ARGV0 (sd
) = xstrdup (arg
);
495 return env_set (sd
, arg
);
497 case OPTION_ENV_UNSET
:
502 if (STATE_PROG_ENVP (sd
) == NULL
)
503 STATE_PROG_ENVP (sd
) = dupargv (environ
);
505 varlen
= strlen (arg
);
507 /* If we can find an existing variable, replace it. */
508 envp
= STATE_PROG_ENVP (sd
);
509 for (i
= 0; envp
[i
]; ++i
)
513 if (strncmp (env
, arg
, varlen
) == 0
514 && (env
[varlen
] == '\0' || env
[varlen
] == '='))
521 /* If we clear the var, shift the array down. */
523 envp
[i
] = envp
[i
+ 1];
528 case OPTION_ENV_CLEAR
:
529 freeargv (STATE_PROG_ENVP (sd
));
530 STATE_PROG_ENVP (sd
) = xmalloc (sizeof (char *));
531 STATE_PROG_ENVP (sd
)[0] = NULL
;
538 /* Add the standard option list to the simulator. */
541 standard_install (SIM_DESC sd
)
543 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
544 if (sim_add_option_table (sd
, NULL
, standard_options
) != SIM_RC_OK
)
546 STATE_LOAD_AT_LMA_P (sd
) = 1;
550 /* Return non-zero if arg is a duplicate argument.
551 If ARG is NULL, initialize. */
554 dup_arg_p (const char *arg
)
556 static htab_t arg_table
= NULL
;
561 if (arg_table
== NULL
)
562 arg_table
= htab_create_alloc (10, htab_hash_string
,
563 htab_eq_string
, NULL
,
565 htab_empty (arg_table
);
569 slot
= htab_find_slot (arg_table
, arg
, INSERT
);
572 *slot
= (void *) arg
;
576 /* Called by sim_open to parse the arguments. */
579 sim_parse_args (SIM_DESC sd
, char * const *argv
)
581 int c
, i
, argc
, num_opts
, save_opterr
;
582 char *p
, *short_options
;
583 /* The `val' option struct entry is dynamically assigned for options that
584 only come in the long form. ORIG_VAL is used to get the original value
587 struct option
*lp
, *long_options
;
588 const struct option_list
*ol
;
590 OPTION_HANDLER
**handlers
;
592 SIM_RC result
= SIM_RC_OK
;
594 /* Count the number of arguments. */
595 argc
= countargv (argv
);
597 /* Count the number of options. */
599 for (ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
600 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
602 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
603 for (ol
= CPU_OPTIONS (STATE_CPU (sd
, i
)); ol
!= NULL
; ol
= ol
->next
)
604 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
607 /* Initialize duplicate argument checker. */
608 (void) dup_arg_p (NULL
);
610 /* Build the option table for getopt. */
612 long_options
= NZALLOC (struct option
, num_opts
+ 1);
614 short_options
= NZALLOC (char, num_opts
* 3 + 1);
616 handlers
= NZALLOC (OPTION_HANDLER
*, OPTION_START
+ num_opts
);
617 orig_val
= NZALLOC (int, OPTION_START
+ num_opts
);
618 opt_cpu
= NZALLOC (sim_cpu
*, OPTION_START
+ num_opts
);
620 /* Set '+' as first char so argument permutation isn't done. This
621 is done to stop getopt_long returning options that appear after
622 the target program. Such options should be passed unchanged into
623 the program image. */
626 for (i
= OPTION_START
, ol
= STATE_OPTIONS (sd
); ol
!= NULL
; ol
= ol
->next
)
627 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
629 if (dup_arg_p (opt
->opt
.name
))
631 if (opt
->shortopt
!= 0)
633 *p
++ = opt
->shortopt
;
634 if (opt
->opt
.has_arg
== required_argument
)
636 else if (opt
->opt
.has_arg
== optional_argument
)
637 { *p
++ = ':'; *p
++ = ':'; }
638 handlers
[(unsigned char) opt
->shortopt
] = opt
->handler
;
639 if (opt
->opt
.val
!= 0)
640 orig_val
[(unsigned char) opt
->shortopt
] = opt
->opt
.val
;
642 orig_val
[(unsigned char) opt
->shortopt
] = opt
->shortopt
;
644 if (opt
->opt
.name
!= NULL
)
647 /* Dynamically assign `val' numbers for long options. */
649 handlers
[lp
->val
] = opt
->handler
;
650 orig_val
[lp
->val
] = opt
->opt
.val
;
651 opt_cpu
[lp
->val
] = NULL
;
656 for (c
= 0; c
< MAX_NR_PROCESSORS
; ++c
)
658 sim_cpu
*cpu
= STATE_CPU (sd
, c
);
659 for (ol
= CPU_OPTIONS (cpu
); ol
!= NULL
; ol
= ol
->next
)
660 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
662 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down
663 on the need for dup_arg_p checking. Maybe in the future it'll be
664 needed so this is just commented out, and not deleted. */
665 if (dup_arg_p (opt
->opt
.name
))
668 /* Don't allow short versions of cpu specific options for now. */
669 if (opt
->shortopt
!= 0)
671 sim_io_eprintf (sd
, "internal error, short cpu specific option");
672 result
= SIM_RC_FAIL
;
675 if (opt
->opt
.name
!= NULL
)
679 /* Prepend --<cpuname>- to the option. */
680 if (asprintf (&name
, "%s-%s", CPU_NAME (cpu
), lp
->name
) < 0)
682 sim_io_eprintf (sd
, "internal error, out of memory");
683 result
= SIM_RC_FAIL
;
687 /* Dynamically assign `val' numbers for long options. */
689 handlers
[lp
->val
] = opt
->handler
;
690 orig_val
[lp
->val
] = opt
->opt
.val
;
691 opt_cpu
[lp
->val
] = cpu
;
697 /* Terminate the short and long option lists. */
701 /* Ensure getopt is initialized. */
704 /* Do not lot getopt throw errors for us. But don't mess with the state for
705 any callers higher up by saving/restoring it. */
706 save_opterr
= opterr
;
713 optc
= getopt_long (argc
, argv
, short_options
, long_options
, &longind
);
716 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
720 free (STATE_PROG_FILE (sd
));
721 STATE_PROG_FILE (sd
) = NULL
;
723 /* Handle any inline variables if -- wasn't used. */
724 if (argv
[optind
] != NULL
&& optind
> 0
725 && strcmp (argv
[optind
- 1], "--") != 0)
729 const char *arg
= argv
[optind
];
731 if (strchr (arg
, '=') == NULL
)
739 new_argv
= dupargv (argv
+ optind
);
740 freeargv (STATE_PROG_ARGV (sd
));
741 STATE_PROG_ARGV (sd
) = new_argv
;
743 /* Skip steps when argc == 0. */
744 if (argv
[optind
] != NULL
)
746 STATE_PROG_FILE (sd
) = xstrdup (argv
[optind
]);
748 if (STATE_PROG_ARGV0 (sd
) != NULL
)
751 new_argv
[0] = xstrdup (STATE_PROG_ARGV0 (sd
));
759 /* If getopt rejects a short option, optopt is set to the bad char.
760 If it rejects a long option, we have to look at optind. In the
761 short option case, argv could be multiple short options. */
767 sprintf (optbuf
, "-%c", optopt
);
771 badopt
= argv
[optind
- 1];
774 "%s: unrecognized option '%s'\n"
775 "Use --help for a complete list of options.\n",
776 STATE_MY_NAME (sd
), badopt
);
778 result
= SIM_RC_FAIL
;
782 if ((*handlers
[optc
]) (sd
, opt_cpu
[optc
], orig_val
[optc
], optarg
, 0/*!is_command*/) == SIM_RC_FAIL
)
784 result
= SIM_RC_FAIL
;
789 opterr
= save_opterr
;
792 free (short_options
);
799 /* Utility of sim_print_help to print a list of option tables. */
802 print_help (SIM_DESC sd
, sim_cpu
*cpu
, const struct option_list
*ol
, int is_command
)
806 for ( ; ol
!= NULL
; ol
= ol
->next
)
807 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
809 const int indent
= 30;
813 if (dup_arg_p (opt
->opt
.name
))
816 if (opt
->doc
== NULL
)
819 if (opt
->doc_name
!= NULL
&& opt
->doc_name
[0] == '\0')
822 sim_io_printf (sd
, " ");
827 /* list any short options (aliases) for the current OPT */
833 if (o
->shortopt
!= '\0')
835 sim_io_printf (sd
, "%s-%c", comma
? ", " : "", o
->shortopt
);
836 len
+= (comma
? 2 : 0) + 2;
839 if (o
->opt
.has_arg
== optional_argument
)
841 sim_io_printf (sd
, "[%s]", o
->arg
);
842 len
+= 1 + strlen (o
->arg
) + 1;
846 sim_io_printf (sd
, " %s", o
->arg
);
847 len
+= 1 + strlen (o
->arg
);
854 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
857 /* list any long options (aliases) for the current OPT */
862 const char *cpu_prefix
= cpu
? CPU_NAME (cpu
) : NULL
;
863 if (o
->doc_name
!= NULL
)
869 sim_io_printf (sd
, "%s%s%s%s%s",
871 is_command
? "" : "--",
872 cpu
? cpu_prefix
: "",
875 len
+= ((comma
? 2 : 0)
876 + (is_command
? 0 : 2)
880 if (o
->opt
.has_arg
== optional_argument
)
882 sim_io_printf (sd
, "[=%s]", o
->arg
);
883 len
+= 2 + strlen (o
->arg
) + 1;
887 sim_io_printf (sd
, " %s", o
->arg
);
888 len
+= 1 + strlen (o
->arg
);
895 while (OPTION_VALID_P (o
) && o
->doc
== NULL
);
899 sim_io_printf (sd
, "\n%*s", indent
, "");
902 sim_io_printf (sd
, "%*s", indent
- len
, "");
904 /* print the description, word wrap long lines */
906 const char *chp
= opt
->doc
;
907 unsigned doc_width
= 80 - indent
;
908 while (strlen (chp
) >= doc_width
) /* some slack */
910 const char *end
= chp
+ doc_width
- 1;
911 while (end
> chp
&& !isspace (*end
))
914 end
= chp
+ doc_width
- 1;
915 /* The cast should be ok - its distances between to
916 points in a string. */
917 sim_io_printf (sd
, "%.*s\n%*s", (int) (end
- chp
), chp
, indent
,
920 while (isspace (*chp
) && *chp
!= '\0')
923 sim_io_printf (sd
, "%s\n", chp
);
928 /* Print help messages for the options. */
931 sim_print_help (SIM_DESC sd
, int is_command
)
933 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
935 "Usage: %s [options] [VAR=VAL|--] program [program args]\n",
938 /* Initialize duplicate argument checker. */
939 (void) dup_arg_p (NULL
);
941 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
942 sim_io_printf (sd
, "Options:\n");
944 sim_io_printf (sd
, "Commands:\n");
946 print_help (sd
, NULL
, STATE_OPTIONS (sd
), is_command
);
947 sim_io_printf (sd
, "\n");
949 /* Print cpu-specific options. */
953 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
955 sim_cpu
*cpu
= STATE_CPU (sd
, i
);
956 if (CPU_OPTIONS (cpu
) == NULL
)
958 sim_io_printf (sd
, "CPU %s specific options:\n", CPU_NAME (cpu
));
959 print_help (sd
, cpu
, CPU_OPTIONS (cpu
), is_command
);
960 sim_io_printf (sd
, "\n");
964 sim_io_printf (sd
, "Note: Depending on the simulator configuration some %ss\n",
965 STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
? "option" : "command");
966 sim_io_printf (sd
, " may not be applicable\n");
968 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_STANDALONE
)
970 sim_io_printf (sd
, "\n");
972 "VAR=VAL Environment variables to set. "
973 "Ignored if -- is used.\n");
974 sim_io_printf (sd
, "program args Arguments to pass to simulated program.\n");
975 sim_io_printf (sd
, " Note: Very few simulators support this.\n");
979 /* Print version information. */
982 sim_print_version (SIM_DESC sd
, int is_command
)
984 sim_io_printf (sd
, "GNU simulator %s%s\n", PKGVERSION
, version
);
986 sim_io_printf (sd
, "Copyright (C) 2023 Free Software Foundation, Inc.\n");
988 /* Following the copyright is a brief statement that the program is
989 free software, that users are free to copy and change it on
990 certain conditions, that it is covered by the GNU GPL, and that
991 there is no warranty. */
993 sim_io_printf (sd
, "\
994 License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\
995 \nThis is free software: you are free to change and redistribute it.\n\
996 There is NO WARRANTY, to the extent permitted by law.\n");
1001 sim_io_printf (sd
, "This SIM was configured as:\n");
1002 sim_config_print (sd
);
1004 if (REPORT_BUGS_TO
[0])
1006 sim_io_printf (sd
, "For bug reporting instructions, please see:\n\
1010 sim_io_printf (sd
, "Find the SIM homepage & other documentation resources \
1011 online at:\n <https://sourceware.org/gdb/wiki/Sim/>.\n");
1014 /* Utility of sim_args_command to find the closest match for a command.
1015 Commands that have "-" in them can be specified as separate words.
1016 e.g. sim memory-region 0x800000,0x4000
1017 or sim memory region 0x800000,0x4000
1018 If CPU is non-null, use its option table list, otherwise use the main one.
1019 *PARGI is where to start looking in ARGV. It is updated to point past
1020 the found option. */
1022 static const OPTION
*
1023 find_match (SIM_DESC sd
, sim_cpu
*cpu
, char *argv
[], int *pargi
)
1025 const struct option_list
*ol
;
1027 /* most recent option match */
1028 const OPTION
*matching_opt
= NULL
;
1029 int matching_argi
= -1;
1032 ol
= CPU_OPTIONS (cpu
);
1034 ol
= STATE_OPTIONS (sd
);
1036 /* Skip passed elements specified by *PARGI. */
1039 for ( ; ol
!= NULL
; ol
= ol
->next
)
1040 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
1043 const char *name
= opt
->opt
.name
;
1046 while (argv
[argi
] != NULL
1047 && strncmp (name
, argv
[argi
], strlen (argv
[argi
])) == 0)
1049 name
= &name
[strlen (argv
[argi
])];
1050 if (name
[0] == '-')
1052 /* leading match ...<a-b-c>-d-e-f - continue search */
1053 name
++; /* skip `-' */
1057 else if (name
[0] == '\0')
1059 /* exact match ...<a-b-c-d-e-f> - better than before? */
1060 if (argi
> matching_argi
)
1062 matching_argi
= argi
;
1072 *pargi
= matching_argi
;
1073 return matching_opt
;
1077 complete_option_list (char **ret
, size_t *cnt
, const struct option_list
*ol
,
1078 const char *text
, const char *word
)
1080 const OPTION
*opt
= NULL
;
1082 size_t len
= strlen (word
);
1084 for ( ; ol
!= NULL
; ol
= ol
->next
)
1085 for (opt
= ol
->options
; OPTION_VALID_P (opt
); ++opt
)
1087 const char *name
= opt
->opt
.name
;
1089 /* A long option to match against? */
1093 /* Does this option actually match? */
1094 if (strncmp (name
, word
, len
))
1097 ret
= xrealloc (ret
, ++*cnt
* sizeof (ret
[0]));
1098 ret
[*cnt
- 2] = xstrdup (name
);
1104 /* All leading text is stored in @text, while the current word being
1105 completed is stored in @word. Trailing text of @word is not. */
1108 sim_complete_command (SIM_DESC sd
, const char *text
, const char *word
)
1114 /* Only complete first word for now. */
1118 cpu
= STATE_CPU (sd
, 0);
1120 ret
= complete_option_list (ret
, &cnt
, CPU_OPTIONS (cpu
), text
, word
);
1121 ret
= complete_option_list (ret
, &cnt
, STATE_OPTIONS (sd
), text
, word
);
1124 ret
[cnt
- 1] = NULL
;
1129 sim_args_command (SIM_DESC sd
, const char *cmd
)
1131 /* something to do? */
1133 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
1137 /* user specified -<opt> ... form? */
1138 char **argv
= buildargv (cmd
);
1139 SIM_RC rc
= sim_parse_args (sd
, argv
);
1145 char **argv
= buildargv (cmd
);
1146 const OPTION
*matching_opt
= NULL
;
1150 if (argv
[0] == NULL
)
1153 return SIM_RC_OK
; /* FIXME - perhaps help would be better */
1156 /* First check for a cpu selector. */
1158 char *cpu_name
= xstrdup (argv
[0]);
1159 char *hyphen
= strchr (cpu_name
, '-');
1162 cpu
= sim_cpu_lookup (sd
, cpu_name
);
1165 /* If <cpuname>-<command>, point argv[0] at <command>. */
1169 argv
[0] += hyphen
- cpu_name
+ 1;
1173 matching_opt
= find_match (sd
, cpu
, argv
, &matching_argi
);
1174 /* If hyphen found restore argv[0]. */
1176 argv
[0] -= hyphen
- cpu_name
+ 1;
1181 /* If that failed, try the main table. */
1182 if (matching_opt
== NULL
)
1185 matching_opt
= find_match (sd
, NULL
, argv
, &matching_argi
);
1188 if (matching_opt
!= NULL
)
1190 switch (matching_opt
->opt
.has_arg
)
1193 if (argv
[matching_argi
+ 1] == NULL
)
1194 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1195 NULL
, 1/*is_command*/);
1197 sim_io_eprintf (sd
, "Command `%s' takes no arguments\n",
1198 matching_opt
->opt
.name
);
1200 case optional_argument
:
1201 if (argv
[matching_argi
+ 1] == NULL
)
1202 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1203 NULL
, 1/*is_command*/);
1204 else if (argv
[matching_argi
+ 2] == NULL
)
1205 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1206 argv
[matching_argi
+ 1], 1/*is_command*/);
1208 sim_io_eprintf (sd
, "Command `%s' requires no more than one argument\n",
1209 matching_opt
->opt
.name
);
1211 case required_argument
:
1212 if (argv
[matching_argi
+ 1] == NULL
)
1213 sim_io_eprintf (sd
, "Command `%s' requires an argument\n",
1214 matching_opt
->opt
.name
);
1215 else if (argv
[matching_argi
+ 2] == NULL
)
1216 matching_opt
->handler (sd
, cpu
, matching_opt
->opt
.val
,
1217 argv
[matching_argi
+ 1], 1/*is_command*/);
1219 sim_io_eprintf (sd
, "Command `%s' requires only one argument\n",
1220 matching_opt
->opt
.name
);
1229 /* didn't find anything that remotly matched */