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