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