1 /* Simulator option handling. 2 Copyright (C) 1996-2020 Free Software Foundation, Inc. 3 Contributed by Cygnus Support. 4 5 This file is part of GDB, the GNU debugger. 6 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. 11 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. 16 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/>. */ 19 20 #include "config.h" 21 #include "sim-main.h" 22 #ifdef HAVE_STRING_H 23 #include <string.h> 24 #else 25 #ifdef HAVE_STRINGS_H 26 #include <strings.h> 27 #endif 28 #endif 29 #ifdef HAVE_STDLIB_H 30 #include <stdlib.h> 31 #endif 32 #include <ctype.h> 33 #include <stdio.h> 34 #include "libiberty.h" 35 #include "sim-options.h" 36 #include "sim-io.h" 37 #include "sim-assert.h" 38 #include "version.h" 39 40 #include "bfd.h" 41 42 /* Add a set of options to the simulator. 43 TABLE is an array of OPTIONS terminated by a NULL `opt.name' entry. 44 This is intended to be called by modules in their `install' handler. */ 45 46 SIM_RC 47 sim_add_option_table (SIM_DESC sd, sim_cpu *cpu, const OPTION *table) 48 { 49 struct option_list *ol = ((struct option_list *) 50 xmalloc (sizeof (struct option_list))); 51 52 /* Note: The list is constructed in the reverse order we're called so 53 later calls will override earlier ones (in case that ever happens). 54 This is the intended behaviour. */ 55 56 if (cpu) 57 { 58 ol->next = CPU_OPTIONS (cpu); 59 ol->options = table; 60 CPU_OPTIONS (cpu) = ol; 61 } 62 else 63 { 64 ol->next = STATE_OPTIONS (sd); 65 ol->options = table; 66 STATE_OPTIONS (sd) = ol; 67 } 68 69 return SIM_RC_OK; 70 } 71 72 /* Standard option table. 73 Modules may specify additional ones. 74 The caller of sim_parse_args may also specify additional options 75 by calling sim_add_option_table first. */ 76 77 static DECLARE_OPTION_HANDLER (standard_option_handler); 78 79 /* FIXME: We shouldn't print in --help output options that aren't usable. 80 Some fine tuning will be necessary. One can either move less general 81 options to another table or use a HAVE_FOO macro to ifdef out unavailable 82 options. */ 83 84 /* ??? One might want to conditionally compile out the entries that 85 aren't enabled. There's a distinction, however, between options a 86 simulator can't support and options that haven't been configured in. 87 Certainly options a simulator can't support shouldn't appear in the 88 output of --help. Whether the same thing applies to options that haven't 89 been configured in or not isn't something I can get worked up over. 90 [Note that conditionally compiling them out might simply involve moving 91 the option to another table.] 92 If you decide to conditionally compile them out as well, delete this 93 comment and add a comment saying that that is the rule. */ 94 95 typedef enum { 96 OPTION_DEBUG_INSN = OPTION_START, 97 OPTION_DEBUG_FILE, 98 OPTION_DO_COMMAND, 99 OPTION_ARCHITECTURE, 100 OPTION_TARGET, 101 OPTION_ARCHITECTURE_INFO, 102 OPTION_ENVIRONMENT, 103 OPTION_ALIGNMENT, 104 OPTION_VERBOSE, 105 OPTION_ENDIAN, 106 OPTION_DEBUG, 107 OPTION_HELP, 108 OPTION_VERSION, 109 OPTION_LOAD_LMA, 110 OPTION_LOAD_VMA, 111 OPTION_SYSROOT 112 } STANDARD_OPTIONS; 113 114 static const OPTION standard_options[] = 115 { 116 { {"verbose", no_argument, NULL, OPTION_VERBOSE}, 117 'v', NULL, "Verbose output", 118 standard_option_handler, NULL }, 119 120 { {"endian", required_argument, NULL, OPTION_ENDIAN}, 121 'E', "big|little", "Set endianness", 122 standard_option_handler, NULL }, 123 124 /* This option isn't supported unless all choices are supported in keeping 125 with the goal of not printing in --help output things the simulator can't 126 do [as opposed to things that just haven't been configured in]. */ 127 { {"environment", required_argument, NULL, OPTION_ENVIRONMENT}, 128 '\0', "user|virtual|operating", "Set running environment", 129 standard_option_handler }, 130 131 { {"alignment", required_argument, NULL, OPTION_ALIGNMENT}, 132 '\0', "strict|nonstrict|forced", "Set memory access alignment", 133 standard_option_handler }, 134 135 { {"debug", no_argument, NULL, OPTION_DEBUG}, 136 'D', NULL, "Print debugging messages", 137 standard_option_handler }, 138 { {"debug-insn", no_argument, NULL, OPTION_DEBUG_INSN}, 139 '\0', NULL, "Print instruction debugging messages", 140 standard_option_handler }, 141 { {"debug-file", required_argument, NULL, OPTION_DEBUG_FILE}, 142 '\0', "FILE NAME", "Specify debugging output file", 143 standard_option_handler }, 144 145 { {"do-command", required_argument, NULL, OPTION_DO_COMMAND}, 146 '\0', "COMMAND", ""/*undocumented*/, 147 standard_option_handler }, 148 149 { {"help", no_argument, NULL, OPTION_HELP}, 150 'H', NULL, "Print help information", 151 standard_option_handler }, 152 { {"version", no_argument, NULL, OPTION_VERSION}, 153 '\0', NULL, "Print version information", 154 standard_option_handler }, 155 156 { {"architecture", required_argument, NULL, OPTION_ARCHITECTURE}, 157 '\0', "MACHINE", "Specify the architecture to use", 158 standard_option_handler }, 159 { {"architecture-info", no_argument, NULL, OPTION_ARCHITECTURE_INFO}, 160 '\0', NULL, "List supported architectures", 161 standard_option_handler }, 162 { {"info-architecture", no_argument, NULL, OPTION_ARCHITECTURE_INFO}, 163 '\0', NULL, NULL, 164 standard_option_handler }, 165 166 { {"target", required_argument, NULL, OPTION_TARGET}, 167 '\0', "BFDNAME", "Specify the object-code format for the object files", 168 standard_option_handler }, 169 170 { {"load-lma", no_argument, NULL, OPTION_LOAD_LMA}, 171 '\0', NULL, 172 "Use VMA or LMA addresses when loading image (default LMA)", 173 standard_option_handler, "load-{lma,vma}" }, 174 { {"load-vma", no_argument, NULL, OPTION_LOAD_VMA}, 175 '\0', NULL, "", standard_option_handler, "" }, 176 177 { {"sysroot", required_argument, NULL, OPTION_SYSROOT}, 178 '\0', "SYSROOT", 179 "Root for system calls with absolute file-names and cwd at start", 180 standard_option_handler, NULL }, 181 182 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL, NULL } 183 }; 184 185 static SIM_RC 186 standard_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, 187 char *arg, int is_command) 188 { 189 int i,n; 190 191 switch ((STANDARD_OPTIONS) opt) 192 { 193 case OPTION_VERBOSE: 194 STATE_VERBOSE_P (sd) = 1; 195 break; 196 197 case OPTION_ENDIAN: 198 if (strcmp (arg, "big") == 0) 199 { 200 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_LITTLE) 201 { 202 sim_io_eprintf (sd, "Simulator compiled for little endian only.\n"); 203 return SIM_RC_FAIL; 204 } 205 /* FIXME:wip: Need to set something in STATE_CONFIG. */ 206 current_target_byte_order = BFD_ENDIAN_BIG; 207 } 208 else if (strcmp (arg, "little") == 0) 209 { 210 if (WITH_TARGET_BYTE_ORDER == BFD_ENDIAN_BIG) 211 { 212 sim_io_eprintf (sd, "Simulator compiled for big endian only.\n"); 213 return SIM_RC_FAIL; 214 } 215 /* FIXME:wip: Need to set something in STATE_CONFIG. */ 216 current_target_byte_order = BFD_ENDIAN_LITTLE; 217 } 218 else 219 { 220 sim_io_eprintf (sd, "Invalid endian specification `%s'\n", arg); 221 return SIM_RC_FAIL; 222 } 223 break; 224 225 case OPTION_ENVIRONMENT: 226 if (strcmp (arg, "user") == 0) 227 STATE_ENVIRONMENT (sd) = USER_ENVIRONMENT; 228 else if (strcmp (arg, "virtual") == 0) 229 STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT; 230 else if (strcmp (arg, "operating") == 0) 231 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT; 232 else 233 { 234 sim_io_eprintf (sd, "Invalid environment specification `%s'\n", arg); 235 return SIM_RC_FAIL; 236 } 237 if (WITH_ENVIRONMENT != ALL_ENVIRONMENT 238 && WITH_ENVIRONMENT != STATE_ENVIRONMENT (sd)) 239 { 240 const char *type; 241 switch (WITH_ENVIRONMENT) 242 { 243 case USER_ENVIRONMENT: type = "user"; break; 244 case VIRTUAL_ENVIRONMENT: type = "virtual"; break; 245 case OPERATING_ENVIRONMENT: type = "operating"; break; 246 } 247 sim_io_eprintf (sd, "Simulator compiled for the %s environment only.\n", 248 type); 249 return SIM_RC_FAIL; 250 } 251 break; 252 253 case OPTION_ALIGNMENT: 254 if (strcmp (arg, "strict") == 0) 255 { 256 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == STRICT_ALIGNMENT) 257 { 258 current_alignment = STRICT_ALIGNMENT; 259 break; 260 } 261 } 262 else if (strcmp (arg, "nonstrict") == 0) 263 { 264 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == NONSTRICT_ALIGNMENT) 265 { 266 current_alignment = NONSTRICT_ALIGNMENT; 267 break; 268 } 269 } 270 else if (strcmp (arg, "forced") == 0) 271 { 272 if (WITH_ALIGNMENT == 0 || WITH_ALIGNMENT == FORCED_ALIGNMENT) 273 { 274 current_alignment = FORCED_ALIGNMENT; 275 break; 276 } 277 } 278 else 279 { 280 sim_io_eprintf (sd, "Invalid alignment specification `%s'\n", arg); 281 return SIM_RC_FAIL; 282 } 283 switch (WITH_ALIGNMENT) 284 { 285 case STRICT_ALIGNMENT: 286 sim_io_eprintf (sd, "Simulator compiled for strict alignment only.\n"); 287 break; 288 case NONSTRICT_ALIGNMENT: 289 sim_io_eprintf (sd, "Simulator compiled for nonstrict alignment only.\n"); 290 break; 291 case FORCED_ALIGNMENT: 292 sim_io_eprintf (sd, "Simulator compiled for forced alignment only.\n"); 293 break; 294 } 295 return SIM_RC_FAIL; 296 297 case OPTION_DEBUG: 298 if (! WITH_DEBUG) 299 sim_io_eprintf (sd, "Debugging not compiled in, `-D' ignored\n"); 300 else 301 { 302 for (n = 0; n < MAX_NR_PROCESSORS; ++n) 303 for (i = 0; i < MAX_DEBUG_VALUES; ++i) 304 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[i] = 1; 305 } 306 break; 307 308 case OPTION_DEBUG_INSN : 309 if (! WITH_DEBUG) 310 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-insn' ignored\n"); 311 else 312 { 313 for (n = 0; n < MAX_NR_PROCESSORS; ++n) 314 CPU_DEBUG_FLAGS (STATE_CPU (sd, n))[DEBUG_INSN_IDX] = 1; 315 } 316 break; 317 318 case OPTION_DEBUG_FILE : 319 if (! WITH_DEBUG) 320 sim_io_eprintf (sd, "Debugging not compiled in, `--debug-file' ignored\n"); 321 else 322 { 323 FILE *f = fopen (arg, "w"); 324 325 if (f == NULL) 326 { 327 sim_io_eprintf (sd, "Unable to open debug output file `%s'\n", arg); 328 return SIM_RC_FAIL; 329 } 330 for (n = 0; n < MAX_NR_PROCESSORS; ++n) 331 CPU_DEBUG_FILE (STATE_CPU (sd, n)) = f; 332 } 333 break; 334 335 case OPTION_DO_COMMAND: 336 sim_do_command (sd, arg); 337 break; 338 339 case OPTION_ARCHITECTURE: 340 { 341 const struct bfd_arch_info *ap = bfd_scan_arch (arg); 342 if (ap == NULL) 343 { 344 sim_io_eprintf (sd, "Architecture `%s' unknown\n", arg); 345 return SIM_RC_FAIL; 346 } 347 STATE_ARCHITECTURE (sd) = ap; 348 break; 349 } 350 351 case OPTION_ARCHITECTURE_INFO: 352 { 353 const char **list = bfd_arch_list (); 354 const char **lp; 355 if (list == NULL) 356 abort (); 357 sim_io_printf (sd, "Possible architectures:"); 358 for (lp = list; *lp != NULL; lp++) 359 sim_io_printf (sd, " %s", *lp); 360 sim_io_printf (sd, "\n"); 361 free (list); 362 break; 363 } 364 365 case OPTION_TARGET: 366 { 367 STATE_TARGET (sd) = xstrdup (arg); 368 break; 369 } 370 371 case OPTION_LOAD_LMA: 372 { 373 STATE_LOAD_AT_LMA_P (sd) = 1; 374 break; 375 } 376 377 case OPTION_LOAD_VMA: 378 { 379 STATE_LOAD_AT_LMA_P (sd) = 0; 380 break; 381 } 382 383 case OPTION_HELP: 384 sim_print_help (sd, is_command); 385 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 386 exit (0); 387 /* FIXME: 'twould be nice to do something similar if gdb. */ 388 break; 389 390 case OPTION_VERSION: 391 sim_io_printf (sd, "GNU simulator %s%s\n", PKGVERSION, version); 392 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 393 exit (0); 394 break; 395 396 case OPTION_SYSROOT: 397 /* Don't leak memory in the odd event that there's lots of 398 --sysroot=... options. We treat "" specially since this 399 is the statically initialized value and cannot free it. */ 400 if (simulator_sysroot[0] != '\0') 401 free (simulator_sysroot); 402 if (arg[0] != '\0') 403 simulator_sysroot = xstrdup (arg); 404 else 405 simulator_sysroot = ""; 406 break; 407 } 408 409 return SIM_RC_OK; 410 } 411 412 /* Add the standard option list to the simulator. */ 413 414 SIM_RC 415 standard_install (SIM_DESC sd) 416 { 417 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); 418 if (sim_add_option_table (sd, NULL, standard_options) != SIM_RC_OK) 419 return SIM_RC_FAIL; 420 STATE_LOAD_AT_LMA_P (sd) = 1; 421 return SIM_RC_OK; 422 } 423 424 /* Return non-zero if arg is a duplicate argument. 425 If ARG is NULL, initialize. */ 426 427 #define ARG_HASH_SIZE 97 428 #define ARG_HASH(a) ((256 * (unsigned char) a[0] + (unsigned char) a[1]) % ARG_HASH_SIZE) 429 430 static int 431 dup_arg_p (const char *arg) 432 { 433 int hash; 434 static const char **arg_table = NULL; 435 436 if (arg == NULL) 437 { 438 if (arg_table == NULL) 439 arg_table = (const char **) xmalloc (ARG_HASH_SIZE * sizeof (char *)); 440 memset (arg_table, 0, ARG_HASH_SIZE * sizeof (char *)); 441 return 0; 442 } 443 444 hash = ARG_HASH (arg); 445 while (arg_table[hash] != NULL) 446 { 447 if (strcmp (arg, arg_table[hash]) == 0) 448 return 1; 449 /* We assume there won't be more than ARG_HASH_SIZE arguments so we 450 don't check if the table is full. */ 451 if (++hash == ARG_HASH_SIZE) 452 hash = 0; 453 } 454 arg_table[hash] = arg; 455 return 0; 456 } 457 458 /* Called by sim_open to parse the arguments. */ 459 460 SIM_RC 461 sim_parse_args (SIM_DESC sd, char * const *argv) 462 { 463 int c, i, argc, num_opts, save_opterr; 464 char *p, *short_options; 465 /* The `val' option struct entry is dynamically assigned for options that 466 only come in the long form. ORIG_VAL is used to get the original value 467 back. */ 468 int *orig_val; 469 struct option *lp, *long_options; 470 const struct option_list *ol; 471 const OPTION *opt; 472 OPTION_HANDLER **handlers; 473 sim_cpu **opt_cpu; 474 SIM_RC result = SIM_RC_OK; 475 476 /* Count the number of arguments. */ 477 argc = countargv (argv); 478 479 /* Count the number of options. */ 480 num_opts = 0; 481 for (ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next) 482 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 483 ++num_opts; 484 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 485 for (ol = CPU_OPTIONS (STATE_CPU (sd, i)); ol != NULL; ol = ol->next) 486 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 487 ++num_opts; 488 489 /* Initialize duplicate argument checker. */ 490 (void) dup_arg_p (NULL); 491 492 /* Build the option table for getopt. */ 493 494 long_options = NZALLOC (struct option, num_opts + 1); 495 lp = long_options; 496 short_options = NZALLOC (char, num_opts * 3 + 1); 497 p = short_options; 498 handlers = NZALLOC (OPTION_HANDLER *, OPTION_START + num_opts); 499 orig_val = NZALLOC (int, OPTION_START + num_opts); 500 opt_cpu = NZALLOC (sim_cpu *, OPTION_START + num_opts); 501 502 /* Set '+' as first char so argument permutation isn't done. This 503 is done to stop getopt_long returning options that appear after 504 the target program. Such options should be passed unchanged into 505 the program image. */ 506 *p++ = '+'; 507 508 for (i = OPTION_START, ol = STATE_OPTIONS (sd); ol != NULL; ol = ol->next) 509 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 510 { 511 if (dup_arg_p (opt->opt.name)) 512 continue; 513 if (opt->shortopt != 0) 514 { 515 *p++ = opt->shortopt; 516 if (opt->opt.has_arg == required_argument) 517 *p++ = ':'; 518 else if (opt->opt.has_arg == optional_argument) 519 { *p++ = ':'; *p++ = ':'; } 520 handlers[(unsigned char) opt->shortopt] = opt->handler; 521 if (opt->opt.val != 0) 522 orig_val[(unsigned char) opt->shortopt] = opt->opt.val; 523 else 524 orig_val[(unsigned char) opt->shortopt] = opt->shortopt; 525 } 526 if (opt->opt.name != NULL) 527 { 528 *lp = opt->opt; 529 /* Dynamically assign `val' numbers for long options. */ 530 lp->val = i++; 531 handlers[lp->val] = opt->handler; 532 orig_val[lp->val] = opt->opt.val; 533 opt_cpu[lp->val] = NULL; 534 ++lp; 535 } 536 } 537 538 for (c = 0; c < MAX_NR_PROCESSORS; ++c) 539 { 540 sim_cpu *cpu = STATE_CPU (sd, c); 541 for (ol = CPU_OPTIONS (cpu); ol != NULL; ol = ol->next) 542 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 543 { 544 #if 0 /* Each option is prepended with --<cpuname>- so this greatly cuts down 545 on the need for dup_arg_p checking. Maybe in the future it'll be 546 needed so this is just commented out, and not deleted. */ 547 if (dup_arg_p (opt->opt.name)) 548 continue; 549 #endif 550 /* Don't allow short versions of cpu specific options for now. */ 551 if (opt->shortopt != 0) 552 { 553 sim_io_eprintf (sd, "internal error, short cpu specific option"); 554 result = SIM_RC_FAIL; 555 break; 556 } 557 if (opt->opt.name != NULL) 558 { 559 char *name; 560 *lp = opt->opt; 561 /* Prepend --<cpuname>- to the option. */ 562 if (asprintf (&name, "%s-%s", CPU_NAME (cpu), lp->name) < 0) 563 { 564 sim_io_eprintf (sd, "internal error, out of memory"); 565 result = SIM_RC_FAIL; 566 break; 567 } 568 lp->name = name; 569 /* Dynamically assign `val' numbers for long options. */ 570 lp->val = i++; 571 handlers[lp->val] = opt->handler; 572 orig_val[lp->val] = opt->opt.val; 573 opt_cpu[lp->val] = cpu; 574 ++lp; 575 } 576 } 577 } 578 579 /* Terminate the short and long option lists. */ 580 *p = 0; 581 lp->name = NULL; 582 583 /* Ensure getopt is initialized. */ 584 optind = 0; 585 586 /* Do not lot getopt throw errors for us. But don't mess with the state for 587 any callers higher up by saving/restoring it. */ 588 save_opterr = opterr; 589 opterr = 0; 590 591 while (1) 592 { 593 int longind, optc; 594 595 optc = getopt_long (argc, argv, short_options, long_options, &longind); 596 if (optc == -1) 597 { 598 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 599 STATE_PROG_ARGV (sd) = dupargv (argv + optind); 600 break; 601 } 602 if (optc == '?') 603 { 604 /* If getopt rejects a short option, optopt is set to the bad char. 605 If it rejects a long option, we have to look at optind. In the 606 short option case, argv could be multiple short options. */ 607 const char *badopt; 608 char optbuf[3]; 609 610 if (optopt) 611 { 612 sprintf (optbuf, "-%c", optopt); 613 badopt = optbuf; 614 } 615 else 616 badopt = argv[optind - 1]; 617 618 sim_io_eprintf (sd, 619 "%s: unrecognized option '%s'\n" 620 "Use --help for a complete list of options.\n", 621 STATE_MY_NAME (sd), badopt); 622 623 result = SIM_RC_FAIL; 624 break; 625 } 626 627 if ((*handlers[optc]) (sd, opt_cpu[optc], orig_val[optc], optarg, 0/*!is_command*/) == SIM_RC_FAIL) 628 { 629 result = SIM_RC_FAIL; 630 break; 631 } 632 } 633 634 opterr = save_opterr; 635 636 free (long_options); 637 free (short_options); 638 free (handlers); 639 free (opt_cpu); 640 free (orig_val); 641 return result; 642 } 643 644 /* Utility of sim_print_help to print a list of option tables. */ 645 646 static void 647 print_help (SIM_DESC sd, sim_cpu *cpu, const struct option_list *ol, int is_command) 648 { 649 const OPTION *opt; 650 651 for ( ; ol != NULL; ol = ol->next) 652 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 653 { 654 const int indent = 30; 655 int comma, len; 656 const OPTION *o; 657 658 if (dup_arg_p (opt->opt.name)) 659 continue; 660 661 if (opt->doc == NULL) 662 continue; 663 664 if (opt->doc_name != NULL && opt->doc_name [0] == '\0') 665 continue; 666 667 sim_io_printf (sd, " "); 668 669 comma = 0; 670 len = 2; 671 672 /* list any short options (aliases) for the current OPT */ 673 if (!is_command) 674 { 675 o = opt; 676 do 677 { 678 if (o->shortopt != '\0') 679 { 680 sim_io_printf (sd, "%s-%c", comma ? ", " : "", o->shortopt); 681 len += (comma ? 2 : 0) + 2; 682 if (o->arg != NULL) 683 { 684 if (o->opt.has_arg == optional_argument) 685 { 686 sim_io_printf (sd, "[%s]", o->arg); 687 len += 1 + strlen (o->arg) + 1; 688 } 689 else 690 { 691 sim_io_printf (sd, " %s", o->arg); 692 len += 1 + strlen (o->arg); 693 } 694 } 695 comma = 1; 696 } 697 ++o; 698 } 699 while (OPTION_VALID_P (o) && o->doc == NULL); 700 } 701 702 /* list any long options (aliases) for the current OPT */ 703 o = opt; 704 do 705 { 706 const char *name; 707 const char *cpu_prefix = cpu ? CPU_NAME (cpu) : NULL; 708 if (o->doc_name != NULL) 709 name = o->doc_name; 710 else 711 name = o->opt.name; 712 if (name != NULL) 713 { 714 sim_io_printf (sd, "%s%s%s%s%s", 715 comma ? ", " : "", 716 is_command ? "" : "--", 717 cpu ? cpu_prefix : "", 718 cpu ? "-" : "", 719 name); 720 len += ((comma ? 2 : 0) 721 + (is_command ? 0 : 2) 722 + strlen (name)); 723 if (o->arg != NULL) 724 { 725 if (o->opt.has_arg == optional_argument) 726 { 727 sim_io_printf (sd, "[=%s]", o->arg); 728 len += 2 + strlen (o->arg) + 1; 729 } 730 else 731 { 732 sim_io_printf (sd, " %s", o->arg); 733 len += 1 + strlen (o->arg); 734 } 735 } 736 comma = 1; 737 } 738 ++o; 739 } 740 while (OPTION_VALID_P (o) && o->doc == NULL); 741 742 if (len >= indent) 743 { 744 sim_io_printf (sd, "\n%*s", indent, ""); 745 } 746 else 747 sim_io_printf (sd, "%*s", indent - len, ""); 748 749 /* print the description, word wrap long lines */ 750 { 751 const char *chp = opt->doc; 752 unsigned doc_width = 80 - indent; 753 while (strlen (chp) >= doc_width) /* some slack */ 754 { 755 const char *end = chp + doc_width - 1; 756 while (end > chp && !isspace (*end)) 757 end --; 758 if (end == chp) 759 end = chp + doc_width - 1; 760 /* The cast should be ok - its distances between to 761 points in a string. */ 762 sim_io_printf (sd, "%.*s\n%*s", (int) (end - chp), chp, indent, 763 ""); 764 chp = end; 765 while (isspace (*chp) && *chp != '\0') 766 chp++; 767 } 768 sim_io_printf (sd, "%s\n", chp); 769 } 770 } 771 } 772 773 /* Print help messages for the options. */ 774 775 void 776 sim_print_help (SIM_DESC sd, int is_command) 777 { 778 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 779 sim_io_printf (sd, "Usage: %s [options] program [program args]\n", 780 STATE_MY_NAME (sd)); 781 782 /* Initialize duplicate argument checker. */ 783 (void) dup_arg_p (NULL); 784 785 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 786 sim_io_printf (sd, "Options:\n"); 787 else 788 sim_io_printf (sd, "Commands:\n"); 789 790 print_help (sd, NULL, STATE_OPTIONS (sd), is_command); 791 sim_io_printf (sd, "\n"); 792 793 /* Print cpu-specific options. */ 794 { 795 int i; 796 797 for (i = 0; i < MAX_NR_PROCESSORS; ++i) 798 { 799 sim_cpu *cpu = STATE_CPU (sd, i); 800 if (CPU_OPTIONS (cpu) == NULL) 801 continue; 802 sim_io_printf (sd, "CPU %s specific options:\n", CPU_NAME (cpu)); 803 print_help (sd, cpu, CPU_OPTIONS (cpu), is_command); 804 sim_io_printf (sd, "\n"); 805 } 806 } 807 808 sim_io_printf (sd, "Note: Depending on the simulator configuration some %ss\n", 809 STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE ? "option" : "command"); 810 sim_io_printf (sd, " may not be applicable\n"); 811 812 if (STATE_OPEN_KIND (sd) == SIM_OPEN_STANDALONE) 813 { 814 sim_io_printf (sd, "\n"); 815 sim_io_printf (sd, "program args Arguments to pass to simulated program.\n"); 816 sim_io_printf (sd, " Note: Very few simulators support this.\n"); 817 } 818 } 819 820 /* Utility of sim_args_command to find the closest match for a command. 821 Commands that have "-" in them can be specified as separate words. 822 e.g. sim memory-region 0x800000,0x4000 823 or sim memory region 0x800000,0x4000 824 If CPU is non-null, use its option table list, otherwise use the main one. 825 *PARGI is where to start looking in ARGV. It is updated to point past 826 the found option. */ 827 828 static const OPTION * 829 find_match (SIM_DESC sd, sim_cpu *cpu, char *argv[], int *pargi) 830 { 831 const struct option_list *ol; 832 const OPTION *opt; 833 /* most recent option match */ 834 const OPTION *matching_opt = NULL; 835 int matching_argi = -1; 836 837 if (cpu) 838 ol = CPU_OPTIONS (cpu); 839 else 840 ol = STATE_OPTIONS (sd); 841 842 /* Skip passed elements specified by *PARGI. */ 843 argv += *pargi; 844 845 for ( ; ol != NULL; ol = ol->next) 846 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 847 { 848 int argi = 0; 849 const char *name = opt->opt.name; 850 if (name == NULL) 851 continue; 852 while (argv [argi] != NULL 853 && strncmp (name, argv [argi], strlen (argv [argi])) == 0) 854 { 855 name = &name [strlen (argv[argi])]; 856 if (name [0] == '-') 857 { 858 /* leading match ...<a-b-c>-d-e-f - continue search */ 859 name ++; /* skip `-' */ 860 argi ++; 861 continue; 862 } 863 else if (name [0] == '\0') 864 { 865 /* exact match ...<a-b-c-d-e-f> - better than before? */ 866 if (argi > matching_argi) 867 { 868 matching_argi = argi; 869 matching_opt = opt; 870 } 871 break; 872 } 873 else 874 break; 875 } 876 } 877 878 *pargi = matching_argi; 879 return matching_opt; 880 } 881 882 static char ** 883 complete_option_list (char **ret, size_t *cnt, const struct option_list *ol, 884 const char *text, const char *word) 885 { 886 const OPTION *opt = NULL; 887 int argi; 888 size_t len = strlen (word); 889 890 for ( ; ol != NULL; ol = ol->next) 891 for (opt = ol->options; OPTION_VALID_P (opt); ++opt) 892 { 893 const char *name = opt->opt.name; 894 895 /* A long option to match against? */ 896 if (!name) 897 continue; 898 899 /* Does this option actually match? */ 900 if (strncmp (name, word, len)) 901 continue; 902 903 ret = xrealloc (ret, ++*cnt * sizeof (ret[0])); 904 ret[*cnt - 2] = xstrdup (name); 905 } 906 907 return ret; 908 } 909 910 /* All leading text is stored in @text, while the current word being 911 completed is stored in @word. Trailing text of @word is not. */ 912 913 char ** 914 sim_complete_command (SIM_DESC sd, const char *text, const char *word) 915 { 916 char **ret = NULL; 917 size_t cnt = 1; 918 sim_cpu *cpu; 919 920 /* Only complete first word for now. */ 921 if (text != word) 922 return ret; 923 924 cpu = STATE_CPU (sd, 0); 925 if (cpu) 926 ret = complete_option_list (ret, &cnt, CPU_OPTIONS (cpu), text, word); 927 ret = complete_option_list (ret, &cnt, STATE_OPTIONS (sd), text, word); 928 929 if (ret) 930 ret[cnt - 1] = NULL; 931 return ret; 932 } 933 934 SIM_RC 935 sim_args_command (SIM_DESC sd, const char *cmd) 936 { 937 /* something to do? */ 938 if (cmd == NULL) 939 return SIM_RC_OK; /* FIXME - perhaps help would be better */ 940 941 if (cmd [0] == '-') 942 { 943 /* user specified -<opt> ... form? */ 944 char **argv = buildargv (cmd); 945 SIM_RC rc = sim_parse_args (sd, argv); 946 freeargv (argv); 947 return rc; 948 } 949 else 950 { 951 char **argv = buildargv (cmd); 952 const OPTION *matching_opt = NULL; 953 int matching_argi; 954 sim_cpu *cpu; 955 956 if (argv [0] == NULL) 957 { 958 freeargv (argv); 959 return SIM_RC_OK; /* FIXME - perhaps help would be better */ 960 } 961 962 /* First check for a cpu selector. */ 963 { 964 char *cpu_name = xstrdup (argv[0]); 965 char *hyphen = strchr (cpu_name, '-'); 966 if (hyphen) 967 *hyphen = 0; 968 cpu = sim_cpu_lookup (sd, cpu_name); 969 if (cpu) 970 { 971 /* If <cpuname>-<command>, point argv[0] at <command>. */ 972 if (hyphen) 973 { 974 matching_argi = 0; 975 argv[0] += hyphen - cpu_name + 1; 976 } 977 else 978 matching_argi = 1; 979 matching_opt = find_match (sd, cpu, argv, &matching_argi); 980 /* If hyphen found restore argv[0]. */ 981 if (hyphen) 982 argv[0] -= hyphen - cpu_name + 1; 983 } 984 free (cpu_name); 985 } 986 987 /* If that failed, try the main table. */ 988 if (matching_opt == NULL) 989 { 990 matching_argi = 0; 991 matching_opt = find_match (sd, NULL, argv, &matching_argi); 992 } 993 994 if (matching_opt != NULL) 995 { 996 switch (matching_opt->opt.has_arg) 997 { 998 case no_argument: 999 if (argv [matching_argi + 1] == NULL) 1000 matching_opt->handler (sd, cpu, matching_opt->opt.val, 1001 NULL, 1/*is_command*/); 1002 else 1003 sim_io_eprintf (sd, "Command `%s' takes no arguments\n", 1004 matching_opt->opt.name); 1005 break; 1006 case optional_argument: 1007 if (argv [matching_argi + 1] == NULL) 1008 matching_opt->handler (sd, cpu, matching_opt->opt.val, 1009 NULL, 1/*is_command*/); 1010 else if (argv [matching_argi + 2] == NULL) 1011 matching_opt->handler (sd, cpu, matching_opt->opt.val, 1012 argv [matching_argi + 1], 1/*is_command*/); 1013 else 1014 sim_io_eprintf (sd, "Command `%s' requires no more than one argument\n", 1015 matching_opt->opt.name); 1016 break; 1017 case required_argument: 1018 if (argv [matching_argi + 1] == NULL) 1019 sim_io_eprintf (sd, "Command `%s' requires an argument\n", 1020 matching_opt->opt.name); 1021 else if (argv [matching_argi + 2] == NULL) 1022 matching_opt->handler (sd, cpu, matching_opt->opt.val, 1023 argv [matching_argi + 1], 1/*is_command*/); 1024 else 1025 sim_io_eprintf (sd, "Command `%s' requires only one argument\n", 1026 matching_opt->opt.name); 1027 } 1028 freeargv (argv); 1029 return SIM_RC_OK; 1030 } 1031 1032 freeargv (argv); 1033 } 1034 1035 /* didn't find anything that remotly matched */ 1036 return SIM_RC_FAIL; 1037 } 1038