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