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