text: /* **********************************************************
   * Copyright (c) 2003-2009 VMware, Inc.  All rights reserved.
   * **********************************************************/
  
  /*
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions are met:
   * 
   * * Redistributions of source code must retain the above copyright notice,
   *   this list of conditions and the following disclaimer.
   * 
   * * Redistributions in binary form must reproduce the above copyright notice,
   *   this list of conditions and the following disclaimer in the documentation
   *   and/or other materials provided with the distribution.
   * 
   * * Neither the name of VMware, Inc. nor the names of its contributors may be
   *   used to endorse or promote products derived from this software without
   *   specific prior written permission.
   * 
   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
   * DAMAGE.
   */
  
  /* Copyright (c) 2003-2007 Determina Corp. */
  
  /*
   * optionsx.h
   *
   * Options and corresponding command line options
   *
   */
  
  /* This file is included multiple times 
     - in globals.h once for structure definition, 
     - in options.c, four times: for initialization, option parsing and enumeration
     - TODO: should also be included in the GUI
  */
  
  /* Client files that include this header should define the following macro
  #define OPTION_COMMAND(type, name, default_value, command_line_option, \
                         statement, description, dynamic_flag, pcache)
  #include "optionsx.h"
  #undef OPTION_COMMAND
     dynamic_flag takes the values
       DYNAMIC - option can be modified externally
       STATIC  - option cannot be modified externally and changes are ignored
     pcache takes values from op_pcache_t
  */
  
  /* PR 330860: the statement of an OPTION_COMMAND is allowed to read
   * and write to the "options" struct.  It can also change other state
   * but only inside of a check for the bool "for_this_process".
   */
  
  /* The liststring_t type is assumed to contain ;-separated values that are
   * appended to if multiple option instances are specified
   */
  
  /* Shortcuts for the common cases */
  #define OPTION_DEFAULT(type, name, value, description)                  \
      OPTION_COMMAND(type, name, value,       #name, {}, description,     \
                     STATIC, OP_PCACHE_NOP)
  
  #define OPTION_NAME_DEFAULT(type, name, value, option_name, description)\
      OPTION_COMMAND(type, name, value, option_name, {}, description, \
                     STATIC, OP_PCACHE_NOP)
  
  #define OPTION_NAME(type, name, option_name, description)               \
      OPTION_NAME_DEFAULT(type, name,     0, option_name, description)
  
  #define OPTION(type, name, description)                                 \
      OPTION_DEFAULT(type, name, 0, description)
  
  #define PC_OPTION_DEFAULT(type, name, value, description)                  \
      OPTION_COMMAND(type, name, value,       #name, {}, description, \
                     STATIC, OP_PCACHE_GLOBAL)
  
  #define PC_OPTION(type, name, description)                               \
      PC_OPTION_DEFAULT(type, name, 0, description)
  
  #define PCL_OPTION_DEFAULT(type, name, value, description)                 \
      OPTION_COMMAND(type, name, value,       #name, {}, description, \
                     STATIC, OP_PCACHE_LOCAL)
  
  #define PCL_OPTION(type, name, description)                              \
      PCL_OPTION_DEFAULT(type, name, 0, description)
  
  /* Dynamic option shortcut definitions, 
     CHECK: if most options end up being dynamic just add a flag to the above */
  #define DYNAMIC_OPTION_DEFAULT(type, name, value, description)          \
      OPTION_COMMAND(type, name, value, #name, {}, description, DYNAMIC, OP_PCACHE_NOP)
  
  #define DYNAMIC_OPTION(type, name, description)                         \
      DYNAMIC_OPTION_DEFAULT(type, name, 0, description)
  
  #define DYNAMIC_PCL_OPTION_DEFAULT(type, name, value, description)      \
      OPTION_COMMAND(type, name, value, #name, {}, description, DYNAMIC, OP_PCACHE_LOCAL)
  
  #define DYNAMIC_PCL_OPTION(type, name, description)                     \
      DYNAMIC_PCL_OPTION_DEFAULT(type, name, 0, description)
  
  /* Shortcut for defining alias command line options to set another option to a constant value, 
     Note we can't read the real type/description, and aliases are not transitive */
  #define OPTION_ALIAS(new_alias, real_internal_name, real_value, dynamic_flag, pcache)   \
      OPTION_COMMAND(bool, new_alias##_aka_##real_internal_name, false, #new_alias,       \
      { if (options->new_alias##_aka_##real_internal_name)                                \
          options->real_internal_name = real_value;                                       \
      },                                                                                  \
      #new_alias " is an alias for " #real_internal_name, dynamic_flag, pcache) 
  
  /* OPTION_COMMAND_INTERNAL is parsed separately in options.h to 
     define constants with default values that are used by INTERNAL_OPTION */
     /* FIXME: dynamic internal options not yet supported */
  #define OPTION_DEFAULT_INTERNAL(type, name, value, description) \
      OPTION_COMMAND_INTERNAL(type, name, value,       #name, {}, description, \
                              STATIC, OP_PCACHE_NOP)
  #define OPTION_NAME_INTERNAL(type, name, option_name, description) \
      OPTION_COMMAND_INTERNAL(type, name,     0, option_name, {}, description, \
                              STATIC, OP_PCACHE_NOP)
  #define OPTION_INTERNAL(type, name, description) \
      OPTION_DEFAULT_INTERNAL(type, name,     0, description)
  
  #define PC_OPTION_DEFAULT_INTERNAL(type, name, value, description) \
      OPTION_COMMAND_INTERNAL(type, name, value,       #name, {}, description, \
                              STATIC, OP_PCACHE_GLOBAL)
  #define PC_OPTION_INTERNAL(type, name, description) \
      PC_OPTION_DEFAULT_INTERNAL(type, name,     0, description)
  
  /* option helper macros */
  #define DISABLE_RESET(prefix)                           \
  {                                                       \
      (prefix)->enable_reset = false;                     \
      IF_INTERNAL((prefix)->reset_at_fragment_count = 0;) \
      (prefix)->reset_at_nth_thread = 0;                  \
      (prefix)->reset_at_switch_to_os_at_vmm_limit = false;\
      (prefix)->reset_at_vmm_percent_free_limit = 0;      \
      (prefix)->reset_at_vmm_free_limit = 0;              \
      (prefix)->reset_at_vmm_full = false;                \
      (prefix)->reset_at_commit_percent_free_limit = 0;   \
      (prefix)->reset_at_commit_free_limit = 0;           \
      (prefix)->reset_every_nth_pending = 0;              \
      (prefix)->reset_at_nth_bb_unit = 0;                 \
      (prefix)->reset_at_nth_trace_unit = 0;              \
      (prefix)->reset_every_nth_bb_unit = 0;              \
      (prefix)->reset_every_nth_trace_unit = 0;           \
  }
  #define REENABLE_RESET(prefix)                                              \
  {                                                                           \
      (prefix)->enable_reset = true;                                          \
      (prefix)->reset_at_vmm_full =                                           \
                   DEFAULT_OPTION_VALUE(reset_at_vmm_full);                   \
      (prefix)->reset_every_nth_pending =                                     \
                   DEFAULT_OPTION_VALUE(reset_every_nth_pending);             \
      (prefix)->reset_at_switch_to_os_at_vmm_limit =                          \
                   DEFAULT_OPTION_VALUE(reset_at_switch_to_os_at_vmm_limit);  \
      (prefix)->reset_at_vmm_percent_free_limit =                             \
                   DEFAULT_OPTION_VALUE(reset_at_vmm_percent_free_limit);     \
      (prefix)->reset_at_vmm_free_limit =                                     \
                   DEFAULT_OPTION_VALUE(reset_at_vmm_free_limit);             \
      (prefix)->reset_at_commit_percent_free_limit =                          \
                   DEFAULT_OPTION_VALUE(reset_at_commit_percent_free_limit);  \
      (prefix)->reset_at_commit_free_limit =                                  \
                   DEFAULT_OPTION_VALUE(reset_at_commit_free_limit);          \
  }
  /* FIXME: case 9014 reenabling more resets or maybe
   * reset_at_vmm_threshold reset_at_commit_threshold shouldn't be
   * disabled in DISABLE_RESET but left under the master option
   */
  
  #define DISABLE_TRACES(prefix)                          \
  {                                                       \
      (prefix)->disable_traces = true;                    \
      (prefix)->enable_traces = false;                    \
      (prefix)->shared_traces = false;                    \
      (prefix)->shared_trace_ibl_routine = false;         \
      (prefix)->bb_ibl_targets = true;                    \
  }
  #define REENABLE_TRACES(prefix)                         \
  {                                                       \
      (prefix)->disable_traces = false;                   \
      (prefix)->enable_traces = true;                     \
      (prefix)->shared_traces = true;                     \
      (prefix)->shared_trace_ibl_routine = true;          \
      (prefix)->bb_ibl_targets = false;                   \
  }
  
  #define ENABLE_SECURITY(prefix)                                          \
  {                                                                        \
      options->native_exec = true;                                         \
      options->code_origins = true;                                        \
      options->ret_after_call = true;                                      \
                                                                           \
      /* we need to know ib sources */                                     \
      options->indirect_stubs = true;                                      \
                                                                           \
      IF_RCT_IND_BRANCH(options->rct_ind_call = IF_WINDOWS_ELSE            \
                        (OPTION_ENABLED|OPTION_BLOCK|OPTION_REPORT,        \
                         OPTION_DISABLED);)                                \
      IF_RCT_IND_BRANCH(options->rct_ind_jump = IF_WINDOWS_ELSE            \
                        (OPTION_ENABLED|OPTION_BLOCK|OPTION_REPORT,        \
                         OPTION_DISABLED);)                                \
      IF_WINDOWS(options->apc_policy =                                     \
                 OPTION_ENABLED|OPTION_BLOCK|OPTION_REPORT|OPTION_CUSTOM;) \
  }
  
  /* options start here */
      DYNAMIC_OPTION_DEFAULT(bool, dynamic_options, true, "dynamically update options")
  
  #ifdef EXPOSE_INTERNAL_OPTIONS
      OPTION_COMMAND_INTERNAL(bool, dummy_version, 0, "version", {
          if (for_this_process)
              print_file(STDERR, "<%s>\n", dynamorio_version_string);
      }, "print version number", STATIC, OP_PCACHE_NOP)
  #endif /* EXPOSE_INTERNAL_OPTIONS */
  
      PC_OPTION_INTERNAL(bool, nolink, "disable linking")
      PC_OPTION_DEFAULT_INTERNAL(bool, link_ibl, true, "link indirect branches")
      OPTION_INTERNAL(bool, tracedump_binary, "binary dump of traces (after optimization)")
      OPTION_INTERNAL(bool, tracedump_text, "text dump of traces (after optimization)")
      OPTION_INTERNAL(bool, tracedump_origins, "write out original instructions for each trace")
      OPTION(bool, syntax_intel, "use Intel disassembly syntax")
  #ifdef EXPOSE_INTERNAL_OPTIONS
  # ifdef PROFILE_LINKCOUNT
      OPTION(uint, tracedump_threshold, "profile_counts threshold for dumping a trace")
  
        /* threshold is limited to 32-bit integer even if linkcounts
         * are 64 bits -- should be fine, few counts reach that high,
         * purpose of threshold is to weed out the multitudes of
         * wimpy traces to reduce the size of the trace file
         */
  # endif
  #endif /* EXPOSE_INTERNAL_OPTIONS */
      OPTION_INTERNAL(bool, bbdump_tags, "dump tags, sizes, and sharedness of all bbs")
      OPTION_INTERNAL(bool, gendump, "dump generated code")
      OPTION_DEFAULT(bool, global_rstats, true, "enable global release-build statistics")
  
  #ifdef DEBUG /* options that only work for debug build */
      /* we do allow logging for customers for forensics/diagnostics that requires
       * debug build for more information.
       * FIXME: somehow restrict info we dump out to prevent IP leakage for INTERNAL=0?
       * restrict loglevel to <= 2 for INTERNAL=0?
       */
      /* log control fields will be kept in dr_statistics_t structure so they can be updated,
       yet we'll also have the initial value in options_t at the cost of 8 bytes */
      OPTION_COMMAND(uint, stats_logmask, 0, "logmask", {
          if (stats != NULL && for_this_process) 
              stats->logmask = options->stats_logmask; 
      }, "set mask for logging from specified modules", DYNAMIC, OP_PCACHE_NOP)
  
      OPTION_COMMAND(uint, stats_loglevel, 0, "loglevel", {
          if (stats != NULL && for_this_process)
              stats->loglevel = options->stats_loglevel; 
      },"set level of detail for logging", DYNAMIC, OP_PCACHE_NOP)
      /* Note that these are not truly DYNAMIC, and they don't get synchronized before each LOG */
      OPTION_DEFAULT(uint, checklevel, 0, "level of extra consistency checks (PR 211887)")
  
      OPTION_DEFAULT_INTERNAL(bool, thread_stats, true, "enable thread local statistics")
      OPTION_DEFAULT_INTERNAL(bool, global_stats, true, "enable global statistics")
      OPTION_DEFAULT_INTERNAL(uint, thread_stats_interval, 10000,
                     "per-thread statistics dump interval in fragments, 0 to disable periodic dump")
      OPTION_DEFAULT_INTERNAL(uint, global_stats_interval, 5000,
                     "global statistics dump interval in fragments, 0 to disable periodic dump")
  #  ifdef HASHTABLE_STATISTICS
      OPTION_DEFAULT_INTERNAL(bool, hashtable_ibl_stats, true, "enable hashtable statistics for IBL routines")
      /* off by default until non-sharing bug 5846 fixed */
      OPTION_DEFAULT_INTERNAL(bool, hashtable_ibl_entry_stats, false, "enable hashtable statistics per IBL entry")
      OPTION_DEFAULT_INTERNAL(uint, hashtable_ibl_study_interval, 50, "dump stats after some IBL entry additions")
      OPTION_DEFAULT_INTERNAL(bool, stay_on_trace_stats, false, "enable stay on trace statistics")
      OPTION_DEFAULT_INTERNAL(bool, speculate_last_exit_stats, false, "enable speculative last stay_on_trace_stats")
  #  endif
  #endif /* DEBUG */
  #ifdef KSTATS
       /* turn on kstats by default for debug builds */
      OPTION_DEFAULT(bool, kstats, IF_DEBUG_ELSE_0(true), "enable path timing statistics")
  #endif
  
  #ifdef DEADLOCK_AVOIDANCE
      OPTION_DEFAULT_INTERNAL(bool, deadlock_avoidance, true, "enable deadlock avoidance checks")
      OPTION_DEFAULT_INTERNAL(uint, mutex_callstack, 0 /* 0 to disable, 4 recommended, MAX_MUTEX_CALLSTACK */,
                              "collect a callstack up to specified depth when a mutex is locked")
  #endif
  
  #ifdef CALL_PROFILE
      OPTION(uint, prof_caller, /* 0 to disable, 3-5 recommended */
             "collect caller data for instrumented routines to this depth")
  #endif
  
  #ifdef HEAP_ACCOUNTING
      OPTION_DEFAULT_INTERNAL(bool, heap_accounting_assert, true, "enable heap accounting assert")
  #endif
  
  #if defined(LINUX)
      OPTION_NAME_INTERNAL(bool, profile_pcs, "prof_pcs", "pc-sampling profiling")
  #else
  # ifdef WINDOWS_PC_SAMPLE
       OPTION_NAME(bool, profile_pcs, "prof_pcs", "pc-sampling profiling")
  # endif
  #endif
  
  #ifdef EXPOSE_INTERNAL_OPTIONS
  # ifdef PROFILE_RDTSC
      OPTION_NAME_INTERNAL(bool, profile_times, "prof_times", "profiling via measuring time"))
  # endif
  
  # ifdef PROFILE_LINKCOUNT
      OPTION_NAME_INTERNAL(bool, profile_counts, "prof_counts", "profiling via counters")
  # endif
  
  # ifdef CLIENT_INTERFACE
      /* FIXME (xref PR 215082): make these external now that our product is our API? */
      OPTION_DEFAULT_INTERNAL(liststring_t, client_lib, EMPTY_STRING, 
                              ";-separated string containing client "
                              "lib paths, IDs, and options")
      /* If we revive hotpatching should use this there as well: but for now
       * don't want to mess up any legacy tools that rely on hotp libs in
       * regular loader list
       */
      /* i#157: Linux private loader is not stable enough yet, so disabled by default. */
      OPTION_DEFAULT_INTERNAL(bool, private_loader, IF_WINDOWS_ELSE(true, false),
                              "use private loader for clients and dependents")
  
  # ifdef WINDOWS
      /* Heap isolation for private dll copies.  Valid only with -private_loader. */
      OPTION_DEFAULT_INTERNAL(bool, privlib_privheap, true,
                              "redirect heap usage by private libraries to DR heap")
      /* PEB and select TEB field isolation for private dll copies (i#249).  
       * Valid only with -private_loader.
       */
      OPTION_DEFAULT_INTERNAL(bool, private_peb, true,
                              "use private PEB + TEB fields for private libraries")
  # endif
  
      /* PR 200418: Code Manipulation API.  This option enables the code
       * manipulation events and sets some default options.  We can't
       * afford to check for this in our exported routines, so we allow
       * ourselves to be used as a utility or standalone library
       * regardless of this option.
       */
      OPTION_COMMAND_INTERNAL(bool, code_api, false, "code_api", {
          if (options->code_api) {
              /* PR 202669: larger stack size since we're saving a 512-byte
               * buffer on the stack when saving fp state.
               */
              options->stack_size = 20*1024;
  
              if (!options->opt_speed) {
                  /* For CI builds we'll disable elision by default since we
                   * expect most CI users will prefer a view of the
                   * instruction stream that's as unmodified as possible.
                   * Also xref PR 214169: eliding calls presents a confusing
                   * view of basic blocks since clients see both the call
                   * and the called function in the same block.  TODO PR
                   * 214169: pass both sides to the client and merge
                   * internally to get the best of both worlds.
                   */
                  options->max_elide_jmp = 0;
                  options->max_elide_call = 0;
  
                  /* indcall2direct causes problems with the code manip API,
                   * so disable by default (xref PR 214051 & PR 214169).
                   * Even if we address those issues, we may want to keep
                   * disabled if we expect users will be confused by this
                   * optimization.
                   */
                  options->indcall2direct = false;
              }
  
              /* To support clients changing syscall numbers we need to
               * be able to swap ignored for non-ignored (xref PR 307284)
               */
              options->inline_ignored_syscalls = false;
  
              /* We want to see all code, performance and bugs be darned! 
               * However the .pexe section thing on Vista is too dangerous so we
               * leave that on. */
              options->native_exec = false;
              IF_WINDOWS_AND_CORE({
                  if (get_os_version() >= WINDOWS_VERSION_VISTA) {
                      /* turn native exec on, but limit it to just the pexe option */
                      options->native_exec = true;
                      options->native_exec_managed_code = false;
                      memset(options->native_exec_default_list, 0,
                             sizeof(options->native_exec_default_list));
                  }})
  
              /* Don't randomize dynamorio.dll */
              IF_WINDOWS(options->aslr_dr = false;)
  
              /* FIXME PR 215179 on getting rid of this tracing restriction. */
              options->pad_jmps_mark_no_trace = true;
          }
       }, "enable Code Manipulation API", STATIC, OP_PCACHE_NOP)
  
      /* PR 200418: Probe API.  Note that the code manip API is off by 
       * default, so -probe_api by itself will give users the lightweight
       * and more restricted version of the probe API.  If users want the
       * flexibility to place a probe anywhere, or if they also want code 
       * manipulation ability, they'll have to enable the code manip API 
       * as well.  For simplicity, we assume they're willing to accept 
       * any associated performance hit (e.g., turning off elision), when
       * enabling the code manip API.
       */
      OPTION_COMMAND_INTERNAL(bool, probe_api, false, "probe_api", {
          if (options->probe_api) { /* else leave alone */
              IF_HOTP(options->hot_patching = true);
              IF_HOTP(options->liveshields = false;)
              IF_GBOP(options->gbop = 0;)
          }
       }, "enable Probe API", STATIC, OP_PCACHE_NOP)
  
      /* PR 326610: provide -opt_speed option.  In future we may want to
       * expose these separately (PR 225139), and fully support their
       * robustness esp in presence of clients: for now we consider this
       * less robust.
       * FIXME: actually we can't turn elision on b/c it violates our
       * translation and client trace building assumptions: plus Tim
       * hit crashes w/ max_elide_call and code_api on in 32-bit linux.
       * So leaving option here for now but not documenting it.
       */
      OPTION_COMMAND(bool, opt_speed, false, "opt_speed", {
          if (options->opt_speed) {
              /* We now have -coarse_units and -indirect_stubs off by default,
               * so elision is the only thing left here, but -indcall2direct
               * is significant on windows server apps.
               */
              /* See comments under -code_api about why these cause problems
               * with clients: but we risk it here.
               */
              options->max_elide_jmp = 16;
              options->max_elide_call = 16;
              options->indcall2direct = true;
          }
       }, "enable high performance at potential loss in client fidelity",
          STATIC, OP_PCACHE_NOP)
  
      /* We turned -coarse_units off by default due to PR 326815 */
      OPTION_COMMAND(bool, opt_memory, false, "opt_memory", {
          if (options->opt_memory) {
              options->coarse_units = true;
              options->indirect_stubs = true; /* required until we fix PR 213262 */
          }
       }, "enable memory savings at potential loss in performance", STATIC, OP_PCACHE_NOP)
  
      PC_OPTION_INTERNAL(bool, bb_prefixes, "give all bbs a prefix")
      /* If a client registers a bb hook, we force a full decode.  This option
       * requests a full decode regardless of whether there is a bb hook. 
       * Note that there is no way to make this available for non-CI builds
       * yet be exposed in non-internal CI builds, so we make it CI-only.
       */
      OPTION_INTERNAL(bool, full_decode, "decode all instrs to level 3 during bb building")
  # endif
  #endif /* EXPOSE_INTERNAL_OPTIONS */
  
  #ifdef WINDOWS_PC_SAMPLE
       OPTION_DEFAULT(uint, prof_pcs_DR, 2, "PC profile dynamorio.dll, value is bit shift to use, < 2 or > 32 disables, requires -prof_pcs")
       OPTION_DEFAULT(uint, prof_pcs_gencode, 2, "PC profile generated code, value is bit shift to use, < 2 or > 32 disables, requires -prof_pcs")
       OPTION_DEFAULT(uint, prof_pcs_fcache, 30, "PC profile fcache units, value is bit shift to use, < 2 or > 32 disables, requires -prof_pcs")
       OPTION_DEFAULT(uint, prof_pcs_stubs, 30,
           "PC profile separate stub units.  Value is bit shift to use: < 2 or > 32 "
           "disables.  Requires -prof_pcs.")
       OPTION_DEFAULT(uint, prof_pcs_ntdll, 30, "PC profile ntdll.dll, value is bit shift to use, < 2 or > 32 disables, requires -prof_pcs")
       OPTION_DEFAULT(uint, prof_pcs_global, 30, "PC profile global, value is bit shift to use, < 8 or > 32 sets to default, requires -prof_pcs")
       OPTION_DEFAULT(uint, prof_pcs_freq, 10000, "Profiling sample frequency in 100's of nanoseconds, requires -prof_pcs")
  #endif
  
      DYNAMIC_OPTION_DEFAULT(uint, msgbox_mask,
           /* Enable for client debug builds so DR ASSERTS are visible (xref PR 232783) */
           /* i#116/PR 394985: for Linux off by default since won't work for all apps */
           IF_WINDOWS_ELSE(IF_CLIENT_INTERFACE_ELSE(IF_DEBUG_ELSE(0xC, 0), 0), 0),
           "show a messagebox for events, use only for demonstration purposes")
  #ifdef WINDOWS
      OPTION_DEFAULT(uint_time, eventlog_timeout, 10000, "gives the timeout (in ms) to use for an eventlog transaction")
  #endif /* WINDOWS */
      DYNAMIC_OPTION_DEFAULT(uint, syslog_mask, 0, /* PR 232126: re-enable: SYSLOG_ALL */
            "log only specified message types")
            /* Example: -syslog_mask 0x4 - error messages
             *          -syslog_mask 0x6 - error and warning messages
             */
      OPTION_DEFAULT_INTERNAL(uint, syslog_internal_mask, 0, /* PR 232126: re-enable: SYSLOG_ALL */
            "log only specified internal message types")
       
      OPTION_DEFAULT(bool, syslog_init, false, "initialize syslog, unnecessary if correctly installed") /* PR 232126: re-enable for product: true */
  #ifdef WINDOWS
      DYNAMIC_OPTION(uint, internal_detach_mask, "indicates what events the core should detach from the app on")
  #endif
      /* Turn on dumpcore by default, even for debug builds, until
       * we decide to provide our ldmp tools externally.
       */
      DYNAMIC_OPTION_DEFAULT(uint, dumpcore_mask,
                             IF_INTERNAL_ELSE(IF_DEBUG_ELSE_0(0x8bff), 0),
                             "indicate events to dump core on")
      IF_LINUX(OPTION_ALIAS(pause_on_error, dumpcore_mask, DUMPCORE_OPTION_PAUSE,
                            STATIC, OP_PCACHE_NOP))
      /* Note that you also won't get more then -report_max violation core dumps */
      DYNAMIC_OPTION_DEFAULT(uint, dumpcore_violation_threshold, 3, "maximum number of violations to core dump on")
  
      DYNAMIC_OPTION_DEFAULT(bool, live_dump,
                             IF_WINDOWS_ELSE(true, IF_VMX86_ELSE(true, false)),
                             "do a live core dump (no outside dependencies) when warranted by the dumpcore_mask")
  #ifdef WINDOWS
      /* FIXME: make a dynamic option */
      OPTION_INTERNAL(bool, external_dump, "do a core dump using an external debugger (specified in the ONCRASH registry value) when warranted by the dumpcore_mask (kills process on win2k or w/ drwtsn32)")
  #endif
  
      /* FIXME: this is really needed in release builds only for our unit tests */
      /* WARNING: on win32 GUI programs can cause problems */
      OPTION_DEFAULT(uint, stderr_mask,
                     /* Enable for client linux debug so ASSERTS are visible (PR 232783) */
                     IF_CLIENT_INTERFACE_ELSE(IF_LINUX_ELSE(IF_DEBUG_ELSE(
                         SYSLOG_ALL, SYSLOG_CRITICAL|SYSLOG_ERROR|SYSLOG_WARNING),
                         SYSLOG_NONE), SYSLOG_NONE),
                     "show messages onto stderr")
  
  #ifdef LINUX
      OPTION_DEFAULT(bool, open_tcsh_fds, true, "at startup open several file descriptors "
                     "to avoid conflicts with hardcoded tcsh assumptions.")
      /* Xref PR 258731 - options to duplicate stdout/stderr for our or client logging if
       * application tries to close them. */
      OPTION_DEFAULT(bool, dup_stdout_on_close, true, "Duplicate stdout for DynamoRIO "
                     "or client usage if app tries to close it.")
      OPTION_DEFAULT(bool, dup_stderr_on_close, true, "Duplicate stderr for DynamoRIO "
                     "or client usage if app tries to close it.")
      OPTION_DEFAULT(bool, dup_stdin_on_close, true, "Duplicate stdin for DynamoRIO "
                     "or client usage if app tries to close it.")
  
      /* Xref PR 308654 where calling dlclose on the client lib at exit time can lead
       * to an app crash. */
      OPTION_DEFAULT(bool, avoid_dlclose, true, "Avoid calling dlclose from DynamoRIO.")
  
      /* PR 304708: we intercept all signals for a better client interface */
      OPTION_DEFAULT(bool, intercept_all_signals, true, "intercept all signals")
  #endif /* LINUX */
  
      /* Disable diagnostics by default. -security turns it on */
      DYNAMIC_OPTION_DEFAULT(bool, diagnostics, false, "enable diagnostic reporting")
  
      OPTION_DEFAULT(uint, max_supported_os_version, 61, 
          /* case 447, defaults to supporting NT, 2000, XP, 2003, and Vista.
           * Windows 7 added with i#218
           */
          "Warn on unsupported (but workable) operating system versions greater than max_supported_os_version")
  
      OPTION_DEFAULT(uint, os_aslr, 
          /* case 8225 - for now we disable our own ASLR and persistent caches */
           0x3 /* OS_ASLR_DISABLE_ASLR_ALL | OS_ASLR_DISABLE_PCACHE_ALL */,
           "disable selectively pcache or our ASLR when OS provides ASLR on most modules")
      OPTION_DEFAULT_INTERNAL(uint, os_aslr_version, 60, /* WINDOWS_VERSION_VISTA, Vista RTM+ */
          "minimal OS version to assume ASLR may be provided by OS")
  
      /* case 10509: we only use this on <= win2k as it significantly impacts boot time */
      OPTION_DEFAULT(uint_time, svchost_timeout, 1000, "timeout (in ms) on an untimely unloaded library on Windows NT or Windows 2000") /* case 374 */
  
      OPTION_DEFAULT(uint_time, deadlock_timeout, 
          IF_DEBUG_ELSE_0(60)*3*1000, /* disabled in release */
          "timeout (in ms) before assuming a deadlock had occurred (0 to disable)")
  
      OPTION_DEFAULT(uint_size, stack_size, IF_X64_ELSE(20*1024,12*1024),
                     "size of thread-private stacks, in KB")
      /* PR 415959: smaller vmm block size makes this both not work and not needed
       * on Linux.
       * FIXME PR 403008: stack_shares_gencode fails on vmkernel
       */
      OPTION_DEFAULT(bool, stack_shares_gencode, IF_LINUX_ELSE(false, true),
          "stack and thread-private generated code share an allocation region")
  
      OPTION_DEFAULT(uint, spinlock_count_on_SMP, 1000U, "spinlock loop cycles on SMP")
          /* This is a true spinlock where on an SMP we check for availability in a tight loop instead 
             of yielding and waiting on a kernel object. 
             See Robbins for a discussion on a good value for the above - 
             it should be based on expectations on how long does it take to finish a task. */
  
       /* INTERNAL options */
       /* These options should be used with a wrapper INTERNAL_OPTION(opt) which in external */
       /* builds is turned into the default value, hence all non-default code is dead.  */
       /* This should be used for experimental internal options */
      PC_OPTION_INTERNAL(bool, nullcalls, "do not take over")
      /* replace dynamorio_app_init & _start w/ empty functions */
  
      OPTION_COMMAND_INTERNAL(uint, trace_threshold, 50U, "trace_threshold",
            { options->disable_traces = options->trace_threshold == 0; }, 
            "hot threshold value for trace creation", STATIC, OP_PCACHE_NOP)
              /* Override the default threshold for hot trace selection. */
      /* PR 200418: Traces are off by default for the BT API.  We now have
       * -enable_traces to turn them on; plus, -probe and -security
       * turn them on.
       * We mark as pcache-affecting though we have other explicit checks
       */
      OPTION_COMMAND(bool, disable_traces, IF_LINUX_KERNEL_ELSE(true, false), "disable_traces", {
          if (options->disable_traces) { /* else leave alone */
              DISABLE_TRACES(options);
          }
       }, "disable trace creation (block fragments only)", STATIC, OP_PCACHE_GLOBAL)
      OPTION_COMMAND(bool, enable_traces, IF_LINUX_KERNEL_ELSE(false, true), "enable_traces", {
          if (options->enable_traces) { /* else leave alone */
              REENABLE_TRACES(options);
          }
       }, "enable trace creation", STATIC, OP_PCACHE_GLOBAL)
      OPTION_DEFAULT_INTERNAL(uint, trace_counter_on_delete, 0U,
          "trace head counter will be reset to this value upon trace deletion")
  
      OPTION_DEFAULT(uint, max_elide_jmp,  16,
          "maximum direct jumps to elide in a basic block")
      OPTION_DEFAULT(uint, max_elide_call, 16,
          "maximum direct calls to elide in a basic block")
      OPTION_DEFAULT(bool, elide_back_jmps, true, "elide backward unconditional jumps in basic blocks?")
      OPTION_DEFAULT(bool, elide_back_calls, true, "elide backward direct calls in basic blocks?")
      /* Xref case 8163, if selfmod_max_writes is too small may cause problems
       * with pattern reverify from case 4020. Though if too big can cause issues
       * with max bb size (even 64 may be too big), xref case 7893. */
      OPTION_DEFAULT(uint, selfmod_max_writes, 5,
          "maximum write instrs per selfmod fragment")
      OPTION_DEFAULT(uint, max_bb_instrs, 1024,
          "maximum instrs per basic block")
      PC_OPTION_DEFAULT(bool, process_SEH_push,
          IF_RETURN_AFTER_CALL_ELSE(true, false),
          "break bb's at an SEH push so we can see the frame pushed on in "
          "interp, required for -borland_SEH_rct")
      OPTION_DEFAULT_INTERNAL(bool, check_for_SEH_push, true,
          "extra debug build checking to ensure -process_SEH_push is catching "
          "all SEH frame pushes")
  
      /* PR 361894: if no TLS available, we fall back to thread-private */
      PC_OPTION_DEFAULT(bool, shared_bbs,
                        IF_LINUX_KERNEL_ELSE(false, IF_HAVE_TLS_ELSE(true, false)),
                        "use thread-shared basic blocks")
      /* Note that if we want traces off by default we would have to turn
       * off -shared_traces to avoid tripping over un-initialized ibl tables
       * PR 361894: if no TLS available, we fall back to thread-private
       */
      OPTION_COMMAND(bool, shared_traces,
                     IF_LINUX_KERNEL_ELSE(false, IF_HAVE_TLS_ELSE(true, false)),
                     "shared_traces", {
          /* for -no_shared_traces, set options back to defaults for private traces: */
          IF_NOT_X64(options->private_ib_in_tls = options->shared_traces;)
          options->atomic_inlined_linking = options->shared_traces;
          options->shared_trace_ibl_routine = options->shared_traces;
          /* private on by default, shared off until proven stable FIXME */
          /* we prefer -no_indirect_stubs to inlining, though should actually
           * measure it: FIXME */
          if (!options->shared_traces && options->indirect_stubs)
              options->inline_trace_ibl = true;
          IF_NOT_X64(IF_WINDOWS(options->shared_fragment_shared_syscalls =
                                (options->shared_traces && options->shared_syscalls);))
       }, "use thread-shared traces", STATIC, OP_PCACHE_GLOBAL)
  
      /* PR 361894: if no TLS available, we fall back to thread-private */
      OPTION_COMMAND(bool, thread_private, IF_HAVE_TLS_ELSE(false, true),
                     "thread_private", {
          options->shared_bbs = !options->thread_private;
          options->shared_traces = !options->thread_private;
          if (options->thread_private && options->indirect_stubs)
              options->coarse_units = true;
          IF_NOT_X64(options->private_ib_in_tls = !options->thread_private;)
          options->atomic_inlined_linking = !options->thread_private;
          options->shared_trace_ibl_routine = !options->thread_private;
          /* we prefer -no_indirect_stubs to inlining, though should actually
           * measure it: FIXME */
          if (options->thread_private && options->indirect_stubs)
              options->inline_trace_ibl = true;
          IF_NOT_X64(IF_WINDOWS(options->shared_fragment_shared_syscalls =
                                (!options->thread_private && options->shared_syscalls);))
       }, "use thread-private code caches", STATIC, OP_PCACHE_GLOBAL)
  
      OPTION_DEFAULT_INTERNAL(bool, remove_shared_trace_heads, true,
          "remove a shared trace head replaced with a trace")
  
      OPTION_DEFAULT(bool, remove_trace_components, false,
          "remove bb components of new traces")
  
      OPTION_DEFAULT(bool, shared_deletion, true, "enable shared fragment deletion")
      OPTION_DEFAULT(bool, syscalls_synch_flush, true, "syscalls are flush synch points (currently for shared_deletion only)")
      OPTION_DEFAULT(uint, lazy_deletion_max_pending, 128,
          "maximum size of lazy shared deletion list before moving to normal list")
  
      OPTION_DEFAULT(bool, free_unmapped_futures, true,
          "free futures on app mem dealloc (potential perf hit)")
  
      /* Default TRUE as it's needed for shared_traces (which is on by default)
       * and for x64 (PR 244737, PR 215396)
       * PR 361894: if no TLS available, we fall back to thread-private
       */
      /* FIXME: private_ib_in_tls option should go away once case 3701 has all
       * ibl using tls when any fragments are shared
       */
      PC_OPTION_DEFAULT(bool, private_ib_in_tls,
                        IF_HAVE_TLS_ELSE(true, IF_X64_ELSE(true, false)),
          "use tls for indirect branch slot in private caches")
  
      OPTION_INTERNAL(bool, single_thread_in_DR, "only one thread in DR at a time")
       /* deprecated: we have finer-grained synch that works now */
  
      OPTION_DEFAULT(bool, separate_private_stubs, IF_LINUX_KERNEL_ELSE(false, true),
          "place private direct exit stubs in a separate area from the code cache")
  
      OPTION_DEFAULT(bool, separate_shared_stubs, IF_LINUX_KERNEL_ELSE(false, true),
          "place shared direct exit stubs in a separate area from the code cache")
  
      OPTION_DEFAULT(bool, free_private_stubs, IF_LINUX_KERNEL_ELSE(false, true),
          "free separated private direct exit stubs when not pointed at")
  
      /* FIXME Freeing shared stubs is currently an unsafe option due to a lack of
       * linking atomicity. (case 2081). */
      OPTION_DEFAULT(bool, unsafe_free_shared_stubs, IF_LINUX_KERNEL_ELSE(false, true),
          "free separated shared direct exit stubs when not pointed at")
  
      OPTION_DEFAULT_INTERNAL(bool, cbr_single_stub, true,
          "both sides of a cbr share a single stub")
  
      /* PR 210990: Improvement is in the noise for spec2k on P4, but is noticeable on
       * Core2, and on IIS on P4.  Note that this gets disabled if
       * coarse_units is on (PR 213262 covers supporting it there).
       */
      OPTION_COMMAND(bool, indirect_stubs, false, "indirect_stubs", {
          /* we put inlining back in place if we have stubs, for private,
           * though should re-measure whether inlining is worthwhile */
          if (options->thread_private && options->indirect_stubs) {
              options->inline_trace_ibl = true;
              /* we also turn coarse on (xref PR 213262) */
              options->coarse_units = true;
          }
       }, "use indirect stubs to keep source information", STATIC, OP_PCACHE_GLOBAL)
  
      /* control inlining of fast path of indirect branch lookup routines */
      /* NOTE : Since linking inline_indirect branches is not atomic (see bug 751)
       * don't turn this on (need atomic linking for trace building in a shared
       * cache) without turning on atomic_inlined_linking, 
       * should be ok for traces since ?think? only need atomic unlinking 
       * there (for flushing), reconsider esp. if we go to a shared trace cache
       */ 
      OPTION_DEFAULT(bool, inline_bb_ibl, false, "inline head of ibl routine in basic blocks")
      /* Default TRUE as it's needed for shared_traces (which is on by default) */
      /* PR 361894: if no TLS available, we fall back to thread-private */
      OPTION_DEFAULT(bool, atomic_inlined_linking, IF_HAVE_TLS_ELSE(true, false),
                     "make linking of inlined_ibls atomic with respect to thread in the cache, required for inline_{bb,traces}_ibl with {bb,traces} being shared, cost is an extra 7 bytes per inlined stub (77 bytes instead of 70)")
      /* Default FALSE since not supported for shared_traces (which is on by default) */
      OPTION_DEFAULT(bool, inline_trace_ibl, false, "inline head of ibl routine in traces")
  
      OPTION_DEFAULT(bool, shared_bb_ibt_tables, false,
          "use thread-shared BB IBT tables")
  
      OPTION_DEFAULT(bool, shared_trace_ibt_tables, false,
          "use thread-shared trace IBT tables")
  
      OPTION_DEFAULT(bool, ref_count_shared_ibt_tables, true,
          "use ref-counting to free thread-shared IBT tables prior to process exit")
  
      /* PR 361894: if no TLS available, we fall back to thread-private */
      OPTION_DEFAULT(bool, ibl_table_in_tls, IF_HAVE_TLS_ELSE(true, false),
          "use TLS to hold IBL table addresses & masks")
  
      OPTION_DEFAULT(bool, bb_ibl_targets, IF_LINUX_KERNEL_ELSE(true, false), "enable BB to BB IBL")
  
       /* IBL code cannot target both single restore prefix and full prefix frags
        * simultaneously since the restore of %eax in the former case means that the
        * 2nd flags restore in the full prefix would be wrong. So if the BB table
        * is including trace targets, bb_single_restore_prefix and
        * trace_single_restore_prefix must be the same value. See options.c for
        * what is currently done for options compatibility.
        */
      OPTION(bool, bb_ibt_table_includes_traces,
          "BB IBT tables holds trace targets also")
  
      PC_OPTION(bool, bb_single_restore_prefix, "BBs use single restore prefixes")
  
      OPTION(bool, trace_single_restore_prefix, "Traces use single restore prefixes")
  
      OPTION_DEFAULT_INTERNAL(uint, rehash_unlinked_threshold, 100,
          "%-age of #unlinked entries to trigger a rehash of a shared BB IBT table")
  
      OPTION_DEFAULT_INTERNAL(bool, rehash_unlinked_always, false,
          "always rehash a shared BB IBT table when # unlinked entries > 0")
  
  #ifdef SHARING_STUDY
      OPTION_COMMAND_INTERNAL(bool, fragment_sharing_study, false,
          "fragment_sharing_study", {
          if (options->fragment_sharing_study) { /* else leave alone */
              options->shared_bbs = false;
              options->shared_traces = false;
              /* undo things that the default-on shared_traces turns on */
              IF_NOT_X64(IF_WINDOWS(options->shared_fragment_shared_syscalls = false;))
              IF_NOT_X64(options->private_ib_in_tls = false;)
              options->shared_trace_ibl_routine = false;
              /* will work w/ wset but let's not clutter creation count stats */
              options->finite_bb_cache = false;
              options->finite_trace_cache = false;
          }
      }, "counts duplication of bbs and traces among threads (requires all-private fragments)", STATIC, OP_PCACHE_NOP)
  #endif
  
      OPTION_COMMAND(bool, shared_bbs_only, false, "shared_bbs_only", {
          if (options->shared_bbs_only) { /* else leave alone */
              DISABLE_TRACES(options);
              options->shared_bbs = true;
              options->private_ib_in_tls = true;
          }
      }, "Run in shared BBs, no traces mode", STATIC, OP_PCACHE_NOP)
  
      /* control sharing of indirect branch lookup routines */
      /* Default TRUE as it's needed for shared_traces (which is on by default) */
      /* PR 361894: if no TLS available, we fall back to thread-private */
      OPTION_DEFAULT(bool, shared_trace_ibl_routine,
                     IF_LINUX_KERNEL_ELSE(false, IF_HAVE_TLS_ELSE(true, false)),
                     "share ibl routine for traces")
      OPTION_DEFAULT(bool, speculate_last_exit, false, 
          "enable speculative linking of trace last IB exit")
  
      OPTION_DEFAULT(uint, max_trace_bbs, 128, "maximum number of basic blocks in a trace")
  
      /* FIXME: case 8023 covers re-enabling on linux */
      OPTION_DEFAULT(uint, protect_mask,
          IF_WINDOWS_ELSE(0x101 /* SELFPROT_DATA_RARE | SELFPROT_GENCODE */, 0/*NYI*/),
          "which memory regions to protect")
      OPTION_INTERNAL(bool, single_privileged_thread, "suspend all other threads when one is out of cache")
  
       /*  1 == HASH_FUNCTION_MULTIPLY_PHI */
      OPTION_DEFAULT_INTERNAL(uint, alt_hash_func, 1, "use to select alternate hashing functions for all fragment tables except those that have in cache lookups")
  
      OPTION_DEFAULT(uint, ibl_hash_func_offset, 0, 
          /* Ignore LSB bits for ret and indjmp hashtables (use ibl_indcall_hash_offset
           * for indcall hashtables).
           * This may change the hash function distribution and for offsets
           * larger than 3 (4 on x64) will add an extra instruction to the IBL hit path.
           */
          "mask out lower bits in IBL table hash function")
  
      /* PR 263331: call* targets on x64 are often 16-byte aligned so ignore LSB 4 */
      OPTION_DEFAULT(uint, ibl_indcall_hash_offset, IF_X64_ELSE(4, 0), 
          /* Ignore LSB bits for indcall hashtables. */
          "mask out lower bits in indcall IBL table hash function")
  
      OPTION_DEFAULT_INTERNAL(uint, shared_bb_load,
          /* FIXME: since resizing is costly (no delete) this used to be up to 65 but that 
           * hurt us lot (case 1677) when we hit a bad hash function distribution - 
           * My current theory is that since modules addresses are 64KB
           * aligned we are doing bad on the 16-bit capacity.
           */
          55, "load factor percent for shared bb hashtable")
      OPTION_DEFAULT_INTERNAL(uint, shared_trace_load,
          /* not used for in-cache lookups */
          55, "load factor percent for shared trace hashtable")
      OPTION_DEFAULT_INTERNAL(uint, shared_future_load,
          /* performance not critical, save some memory */
          60, "load factor percent for shared future hashtable")
  
      OPTION_DEFAULT(uint, shared_after_call_load,
          /* performance not critical */
          /* we use per-module tables despite the name of the option */
          80, "load factor percent for after call hashtables")
  
      OPTION_DEFAULT(uint, global_rct_ind_br_load,
          /* performance not critical */
          /* we use per-module tables despite the name of the option */
          80, "load factor percent for global rct ind branch hashtable")
  
      OPTION_DEFAULT_INTERNAL(uint, private_trace_load,
          /* trace table is no longer used for in-cache lookups
           * we can probably use higher than \alpha = 1/2
           */
          55, "load factor percent for private trace hashtables")
  
      OPTION_DEFAULT(uint, private_ibl_targets_load,
          /* IBL tables are performance critical, so we use a smaller load.
           * we started with \alpha = 1/2,
           * 40 seemed to be the best tradeoff of memory & perf for
           * crafty, which is of course our primary nemesis.
           * Increasing to accommodate IIS for private tables.
           * FIXME: case 4902 this doesn't really control the effective load.
           */
          50, "load factor percent for private ibl target trace hashtables")
  
      OPTION_DEFAULT(uint, private_bb_ibl_targets_load,
          /* BB IBL tables are not proven to be performance critical trying a 1/2
           */
          60, "load factor percent for private ibl hashtables targeting shared bbs")
  
      OPTION_DEFAULT(uint, shared_ibt_table_trace_init,
          7, "Shared trace shared IBT tables initial size, log_2 (in bits)")
  
      OPTION_DEFAULT(uint, shared_ibt_table_bb_init,
          7, "Shared BB shared IBT tables initial size, log_2 (in bits)")
  
      OPTION_DEFAULT(uint, shared_ibt_table_trace_load,
          50, "load factor percent for shared ibl hashtables targeting shared traces")
  
      OPTION_DEFAULT(uint, shared_ibt_table_bb_load,
          70, "load factor percent for shared ibl hashtables targeting shared bbs")
  
      OPTION_DEFAULT(uint, coarse_htable_load,
          /* there is a separate table per module so we keep the load high */
          80, "load factor percent for all coarse module hashtables")
  
      OPTION_DEFAULT(uint, coarse_th_htable_load,
          /* there is a separate table per module so we keep the load high */
          80, "load factor percent for all coarse module trace head hashtables")
  
      OPTION_DEFAULT(uint, coarse_pclookup_htable_load,
          /* there is a separate table per module so we keep the load high */
          80, "load factor percent for all coarse module trace head hashtables")
  
       /* FIXME: case 4814 currently disabled */
      OPTION_DEFAULT(uint, bb_ibt_groom,
          /* Should either be 0 to disable grooming or be <= private_bb_ibl_targets_load */
          0, "groom factor percent for ibl hashtables targeting bb's")
  
      OPTION_DEFAULT(uint, trace_ibt_groom,
          /* Should either be 0 to disable grooming or be <= private_ibl_targets_load
           * since traces are considered hot already, grooming the table may not work as well here
           */
          0, "groom factor percent for ibl hashtables targeting traces")
  
       /* for small table sizes resize is not an expensive operation and we start smaller */
      OPTION_DEFAULT(uint, private_trace_ibl_targets_init,
          7, "Trace IBL tables initial size, log_2 (in bits)")
  
      OPTION_DEFAULT(uint, private_bb_ibl_targets_init,
          6, "BB IBL tables initial size, log_2 (in bits)")
  
       /* maximum size of IBL table - table is reset instead of resized when reaching load factor */
      OPTION_DEFAULT(uint, private_trace_ibl_targets_max,
          0, /* 0 for unlimited */
          "Trace IBL tables maximum size, log_2 (in bits)")
  
      OPTION_DEFAULT(uint, private_bb_ibl_targets_max,
          0, /* 0 for unlimited */
          "BB IBL tables maximum size, log_2 (in bits)")
  
      OPTION_DEFAULT_INTERNAL(uint, private_bb_load,
          /* Note there are usually no private bbs when using shared_bbs */
          60, "load factor percent for private bb hashtables")
      OPTION_DEFAULT_INTERNAL(uint, private_future_load,
          /* performance not critical, save memory */
          /* This table is suffering from the worst collisions */
          65, "load factor percent for private future hashtables")
  
       /* FIXME: remove this once we are happy with new mutexes */
      OPTION_DEFAULT_INTERNAL(bool, spin_yield_mutex, false, "use old spin-yield mutex implementation")
  
       /* FIXME: remove this once we are happy with new rwlocks */
      OPTION_DEFAULT_INTERNAL(bool, spin_yield_rwlock, false, "use old spin-yield rwlock implementation")
  
      OPTION_INTERNAL(bool, simulate_contention, "simulate lock contention for testing purposes only")
  
      OPTION_DEFAULT_INTERNAL(uint_size, initial_heap_unit_size, 32*1024, "initial private heap unit size")
      OPTION_DEFAULT_INTERNAL(uint_size, initial_global_heap_unit_size, 32*1024, "initial global heap unit size")
      OPTION_DEFAULT_INTERNAL(uint_size, max_heap_unit_size, 64*1024, "maximum heap unit size")
      OPTION_DEFAULT(uint_size, heap_commit_increment, 4*1024, "heap commit increment")
      OPTION_DEFAULT(uint, cache_commit_increment, 4*1024, "cache commit increment")
  
      /* cache capacity control
       * FIXME: these are external for now while we study the right way to
       * tune them for server apps as well as desktop apps
       * Should we make then internal again once we're happy with the defaults?
       *
       * FIXME: unit params aren't that user-friendly -- there's an ordering required:
       * init < quadruple < max && init < upgrade < max
       * We complain if that's violated, but if you just set max we make you go and
       * set the others instead of forcing the others to be ==max.
       *
       * FIXME: now that we have cache commit-on-demand we should make the
       * private-configuration caches larger.  We could even get rid of the
       * fcache shifting.
       */
       /* Note that with guard pages any size of 64KB or bigger will get 8KB less than specified
        * to make sure we don't waste virtual memory in the address space
        */
      OPTION(uint_size, cache_bb_max, "max size of bb cache, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
       /* for default configuration of all-shared we want a tiny bb cache for
        * our temp private bbs
        */
      /* x64 does not support resizing individual cache units so start at 64 */
      OPTION_DEFAULT(uint_size, cache_bb_unit_init, (IF_X64_ELSE(64,4)*1024),
          "initial bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_bb_unit_max, (64*1024),
          "maximum bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
       /* w/ init at 4, we quadruple to 16 and then to 64 */
      OPTION_DEFAULT(uint_size, cache_bb_unit_quadruple, (64*1024),
          "bb cache units are grown by 4X until this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      OPTION(uint_size, cache_trace_max, "max size of trace cache, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      /* x64 does not support resizing individual cache units so start at 64 */
      OPTION_DEFAULT(uint_size, cache_trace_unit_init, (IF_X64_ELSE(64,8)*1024),
          "initial trace cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_trace_unit_max, (64*1024),
          "maximum trace cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_trace_unit_quadruple, (IF_X64_ELSE(64,32)*1024),
          "trace cache units are grown by 4X until this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      OPTION(uint_size, cache_shared_bb_max, "max size of shared bb cache, in KB or MB")
              /* override the default shared bb fragment cache size */
              /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_bb_unit_init, (64*1024),
          /* FIXME: cannot handle resizing of cache setting to unit_max, FIXME: should be 32*1024 */
          "initial shared bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_bb_unit_max, (64*1024),
          "maximum shared bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_bb_unit_quadruple, (64*1024), /* FIXME: should be 32*1024 */
          "shared bb cache units are grown by 4X until this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      OPTION(uint_size, cache_shared_trace_max, "max size of shared trace cache, in KB or MB")
              /* override the default shared trace fragment cache size */
              /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_trace_unit_init, (64*1024),
          /* FIXME: cannot handle resizing of cache setting to unit_max, FIXME: should be 32*1024 */
          "initial shared trace cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_trace_unit_max, (64*1024),
          "maximum shared trace cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_trace_unit_quadruple, (64*1024), /* FIXME: should be 32*1024 */
          "shared trace cache units are grown by 4X until this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      OPTION(uint_size, cache_coarse_bb_max, "max size of coarse bb cache, in KB or MB")
              /* override the default coarse bb fragment cache size */
              /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_coarse_bb_unit_init, (64*1024),
          /* FIXME: cannot handle resizing of cache setting to unit_max, FIXME: should be 32*1024 */
          "initial coarse bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_coarse_bb_unit_max, (64*1024),
          "maximum coarse bb cache unit size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_coarse_bb_unit_quadruple, (64*1024), /* FIXME: should be 32*1024 */
          "coarse bb cache units are grown by 4X until this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      /* adaptive working set */
      OPTION_DEFAULT(bool, finite_bb_cache, IF_LINUX_KERNEL_ELSE(false, true), "adaptive working set bb cache management")
      OPTION_DEFAULT(bool, finite_trace_cache, true, "adaptive working set trace cache management")
      OPTION_DEFAULT(bool, finite_shared_bb_cache, false, 
          "adaptive working set shared bb cache management")
      OPTION_DEFAULT(bool, finite_shared_trace_cache, false, 
          "adaptive working set shared trace cache management")
      OPTION_DEFAULT(bool, finite_coarse_bb_cache, false, 
          "adaptive working set shared bb cache management")
      OPTION_DEFAULT(uint_size, cache_bb_unit_upgrade, (64*1024),
          "bb cache units are always upgraded to this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_trace_unit_upgrade, (64*1024),
          "trace cache units are always upgraded to this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_bb_unit_upgrade, (64*1024),
          "shared bb cache units are always upgraded to this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_shared_trace_unit_upgrade, (64*1024),
          "shared trace cache units are always upgraded to this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
      OPTION_DEFAULT(uint_size, cache_coarse_bb_unit_upgrade, (64*1024),
          "shared coarse cache units are always upgraded to this size, in KB or MB")
          /* default size is in Kilobytes, Examples: 4, 4k, 4m, or 0 for unlimited */
  
      OPTION_DEFAULT(uint, cache_bb_regen, 10,
          "#regen per #replaced ratio for sizing bb cache")
      OPTION_DEFAULT(uint, cache_bb_replace, 50,
          "#regen per #replaced ratio for sizing bb cache")
      OPTION_DEFAULT(uint, cache_trace_regen, 10,
          "#regen per #replaced ratio for sizing trace cache")
      OPTION_DEFAULT(uint, cache_trace_replace, 50,
          "#regen per #replaced ratio for sizing trace cache")
      OPTION_DEFAULT(uint, cache_shared_bb_regen, 20,
          "#regen per #replaced ratio for sizing shared bb cache")
      OPTION_DEFAULT(uint, cache_shared_bb_replace, 100,
          /* doesn't mean much for shared sizing, so default 100 makes
           * regen param a percentage */
          "#regen per #replaced ratio for sizing shared bb cache")
      OPTION_DEFAULT(uint, cache_shared_trace_regen, 10, 
          "#regen per #replaced ratio for sizing shared trace cache")
      OPTION_DEFAULT(uint, cache_shared_trace_replace, 100,
          /* doesn't mean much for shared sizing, so default 100 makes
           * regen param a percentage */
          "#regen per #replaced ratio for sizing shared trace cache")
      OPTION_DEFAULT(uint, cache_coarse_bb_regen, 20,
          "#regen per #replaced ratio for sizing shared coarse cache")
      OPTION_DEFAULT(uint, cache_coarse_bb_replace, 100,
          /* doesn't mean much for shared sizing, so default 100 makes
           * regen param a percentage */
          "#regen per #replaced ratio for sizing shared coarse cache")
  
      OPTION_DEFAULT(uint, cache_trace_align, 8, "alignment of trace cache slots")
      OPTION_DEFAULT(uint, cache_bb_align, 4, "alignment of bb cache slots")
      OPTION_DEFAULT(uint, cache_coarse_align, 1, "alignment of coarse bb cache slots")
  
      OPTION_DEFAULT(uint, ro2sandbox_threshold, 10,
          "#write faults in a region before switching to sandboxing, 0 to disable")
      OPTION_DEFAULT(uint, sandbox2ro_threshold, 20,
          "#executions in a sandboxed region before switching to page prot, 0 to disable")
  
      OPTION_COMMAND(bool, sandbox_writable, false, "sandbox_writable", {
          if (options->sandbox_writable) {
              options->sandbox2ro_threshold = 0;
          }
      }, "always sandbox writable regions", STATIC, OP_PCACHE_GLOBAL)
  
      /* FIXME: Do we want to turn this on by default?  If we do end up
       * making this the default for a single process only, we might
       * want to make it OP_PCACHE_NOP.
       */
      OPTION_COMMAND(bool, sandbox_non_text, false, "sandbox_non_text", {
          if (options->sandbox_non_text) {
              options->sandbox2ro_threshold = 0;
          }
      }, "always sandbox non-text writable regions", STATIC, OP_PCACHE_GLOBAL)
  
      /* FIXME: separate for bb and trace shared caches? */
      OPTION_DEFAULT(bool, cache_shared_free_list, true,
          "use size-separated free lists to manage empty shared cache slots")
  
      OPTION_COMMAND(bool, enable_reset, true, "enable_reset", {
          if (!options->enable_reset) {
              DISABLE_RESET(options);
          }
      }, "separate persistent memory from non-persistent for resets", STATIC,
      OP_PCACHE_NOP)
  
      OPTION_DEFAULT_INTERNAL(uint, reset_at_fragment_count, 0,
          "reset all caches at a certain fragment count")
      OPTION(uint, reset_at_nth_thread,
          "reset all caches when the nth thread is explicitly created")
      /* FIXME - is potentially using up all the os allocation leaving nothing for the
       * app, however that's prob. better then us spinning (xref 9145). It would be nice
       * to switch back to resetting when the address space is getting low, but there's
       * no easy way to figure that out. */
      OPTION_DEFAULT(bool, switch_to_os_at_vmm_reset_limit,
          IF_LINUX_KERNEL_ELSE(false, true),
          "if we hit the reset_at_vmm_*_limit switch to requesting from the os (so we'll "
          "only actually reset once the os is out and we're at the limit)")
      OPTION_DEFAULT(bool, reset_at_switch_to_os_at_vmm_limit, true, 
          "schedule a reset the first (and only the first) time we switch to the os "
          "allocations from -switch_to_os_at_vmm_reset_limit above")
      OPTION_DEFAULT(uint, reset_at_vmm_percent_free_limit, 10,
          "reset all when vmm heap % free is < reset_at_vmm_percent_free (0 disables)")
      OPTION_DEFAULT(uint_size, reset_at_vmm_free_limit, 0,
          "reset all when vmm heap has less then reset_at_vmm_free free memory remaining")
      OPTION_DEFAULT(uint, report_reset_vmm_threshold, 3,
          "syslog one thrash warning message after this many resets at low vmm heap free")
      OPTION_DEFAULT(bool, reset_at_vmm_full, true,
          "reset all caches the first time vmm heap runs out of space")
      OPTION_DEFAULT(uint, reset_at_commit_percent_free_limit, 0,
          "reset all less then this % of the commit limit remains free (0 disables)") 
      OPTION_DEFAULT(uint_size, reset_at_commit_free_limit, (32 * 1024 * 1024),
           "reset all when less then this much free committable memory remains")
      OPTION_DEFAULT(uint, report_reset_commit_threshold, 3,
          "syslog one thrash warning message after this many resets at low commit")
      OPTION_DEFAULT(uint, reset_every_nth_pending, 35,
          "reset all caches when pending deletion has this many entries")
      /* the reset-by-unit options focus on filled units and not created units
       * to avoid being triggered by new, empty, private units for new threads
       */
      OPTION(uint, reset_at_nth_bb_unit,
          "reset all caches once, when the nth new bb cache unit is created/reused")
      OPTION(uint, reset_at_nth_trace_unit,
          "reset all caches once, when the nth new trace cache unit is created/reused")
      /* these options essentially put a ceiling on the size of the cache */
      OPTION(uint, reset_every_nth_bb_unit,
          "reset all caches every nth bb cache unit that is created/reused")
      OPTION(uint, reset_every_nth_trace_unit,
          "reset all caches every nth trace cache unit that is created/reused")
  
      /* virtual memory management */
      /* See case 1990 for examples where we have to fight for virtual address space with the app */
      /* FIXME: due to incomplete implementation for detaching we will leave memory behind */
      OPTION_DEFAULT_INTERNAL(bool, skip_out_of_vm_reserve_curiosity, false,
          "skip the assert curiosity on out of vm_reserve (for regression tests)")
      OPTION_DEFAULT(bool, vm_reserve, true, "reserve virtual memory") 
      /* FIXME - on 64bit probably will need more space */
      OPTION_DEFAULT(uint_size, vm_size, IF_LINUX_KERNEL_ELSE(256, 128)*1024*1024,
          "maximum virtual memory reserved, in KB or MB")
          /* default size is in Kilobytes, Examples: 262144, 1024k, 256m, up to maximum of 512M */
       /* FIXME: default value is currently not good enough for sqlserver, for which we need more than 256MB */
  
      /* We hardcode an address in the mmap_text region here, but verify via
       * in vmk_init().
       */
      OPTION_DEFAULT(uint_addr, vm_base,
                     IF_VMX86_ELSE(IF_X64_ELSE(0x40000000,0x10800000), 0x16000000),
                     "preferred base address hint (ignored for 64-bit linux)")
       /* FIXME: we need to find a good location with no conflict with DLLs or apps allocations */
      OPTION_DEFAULT(uint_addr, vm_max_offset, 
                     IF_VMX86_ELSE(IF_X64_ELSE(0x18000000,0x05800000),0x10000000),
                     "base address maximum random jitter")
      OPTION_DEFAULT(bool, vm_allow_not_at_base, true, "if we can't allocate vm heap at "
                     "preferred base (plus random jitter) allow the os to choose where to "
                     "place it instead of dying")
      OPTION_DEFAULT(bool, vm_allow_smaller, true, "if we can't allocate vm heap of "
                     "requested size, try smaller sizes instead of dying")
  #ifdef X64
      /* For linux, we assume our preferred address gets us <4GB as well: if that
       * has issues we should make them independent (PR 253624).
       */
      OPTION_DEFAULT(bool, heap_in_lower_4GB, IF_LINUX_KERNEL_ELSE(false, true),
                     "on 64bit request that the dr heap "
                     "be allocated entirely within the lower 4GB of address space so that "
                     "it can be accessed directly as a 32bit address. See PR 215395.")
  #endif
       /* FIXME: the lower 16 bits are ignored - so this here gives us
        * 12bits of randomness.  Could make it larger if we verify as
        * collision free the whole range [vm_base, * vm_base+vm_size+vm_max_offset) 
        */
      OPTION_INTERNAL(bool, vm_use_last, "use the vm reservation only as a last resort")
  
      OPTION(uint, silent_oom_mask,
          /* a mask of the oom_source_t constants, usually 12 ==
           * (OOM_COMMIT | OOM_EXTEND) on commit limit either when
           * system running out of pagefile or process hitting job limit
           */
          "silently die when out of memory")
  
       /* FIXME: case 6919 forcing a hardcoded name in the core, this
        * should rather go into a configuration file.  Since
        * per-executable no real need for an append list. */
      OPTION_DEFAULT(liststring_t, silent_commit_oom_list,
          OPTION_STRING("wmiprvse.exe"),
          "silently die on reachinig commit limit in these ;-separated executables")
  
      OPTION_DEFAULT(uint_time, oom_timeout, 
          5*1000, /* 5s */
          /* 5 second x 2 -> adds at least 10 seconds before we terminate
           * when out of memory, but gives us a chance to not die */
          /* case 2294 pagefile resize, or case 7032 where we hope that
           * a memory hog on the machine would die by the time we retry.
           * Applies only to committed memory, for reservations sleeping
           * is futile (other than artificial ballooning).
           * 
           * Note: Two of these timeouts on the same thread's request
           * and we'll terminate - we will also try freeing up our own
           * memory after the first timeout.
           */
          "short sleep (in ms) and retry after a commit failure")
  
      /* The follow children options control when we inject into a child. We inject if 
       * any one of the three says we should, see their descriptions for more details. */
      DYNAMIC_OPTION_DEFAULT(bool, follow_children, IF_LINUX_ELSE(true, false),
          "inject into all spawned processes unless preinjector is set up to inject into them or they have app-specific RUNUNDER_OFF")
      /* not dynamic do to interactions with -early_inject */
      OPTION_DEFAULT(bool, follow_systemwide, true, "inject into all spawned processes that are configured to run under dr (app specific RUNUNDER_ON, or no app specific and RUNUNDER_ALL in the global key), dangerous without either -early_inject or -block_mod_load_list_default preventing double injection")
      DYNAMIC_OPTION_DEFAULT(bool, follow_explicit_children, true, "inject into all spawned processes that have app-specific RUNUNDER_EXPLICIT")
  
      /* FIXME - do we want to make any of the -early_inject* options dynamic?
       * if so be sure we update os.c:early_inject_location on change etc. */
      OPTION_DEFAULT(bool, early_inject, true, "inject early")
      OPTION_DEFAULT(bool, early_inject_map, false, "inject early via map NYI")
      /* see enum definition is os_shared.h for notes on what works with which
       * os version */
      OPTION_DEFAULT(uint, early_inject_location, 4 /* INJECT_LOCATION_LdrDefault */,
          "where to hook for early_injection, LdrDefault picks the best location for this OS version, see enum for rest")
      OPTION_DEFAULT(uint_addr, early_inject_address, 0,
          "specify the address to hook at for INJECT_LOCATION_LdrCustom")
  #ifdef WINDOWS /* probably the surrounding options should also be under this ifdef */
      OPTION_DEFAULT(pathstring_t, early_inject_helper_dll,
          OPTION_STRING(INJECT_HELPER_DLL1_NAME),
          "path to 1st early inject helper dll that is used to auto find LdrpLoadImportModule")
      OPTION_DEFAULT(pathstring_t, early_inject_helper_name,
          OPTION_STRING(INJECT_HELPER_DLL2_NAME),
          "PE name of 2nd early inject helper dll that is used to auto find LdrpLoadImportModule")
  #endif
      OPTION_DEFAULT_INTERNAL(bool, early_inject_stress_helpers, false,
          "When early injected and using early_inject_location LdprLoadImportModule, don't use parent's address, instead always use helper dlls to find it")
      /* FIXME - won't work till we figure out how to get the process parameters
       * in maybe_inject_into_proccess() in os.c (see notes there) */
      OPTION_DEFAULT(bool, inject_at_create_process, false,
          "inject at post create process instead of create first thread, requires early injection")
       /* Separated from above option since on Vista+ we have to inject at create
        * process (there is no separate create first thread).  On vista+ proc
        * params are available at create process so everything works out. */
      OPTION_DEFAULT(bool, vista_inject_at_create_process, true,
          "if os version is vista+, inject at post create (requires early injection)")
  
      OPTION_DEFAULT(bool, inject_primary, false,
          /* case 9347 - we may leave early threads as unknown */
          "check and wait for injection in the primary thread")
  
      /* options for controlling the synch_with_* routines */
      OPTION_DEFAULT(uint, synch_thread_max_loops, 10000, "max number of wait loops in "
          "synch_with_thread before we give up (UINT_MAX loops forever)")
      OPTION_DEFAULT(uint, synch_all_threads_max_loops, 10000, "max number of wait loops "
          "in synch_with_all_threads before we give up (UINT_MAX loops forever)")
      OPTION_DEFAULT(bool, synch_thread_sleep_UP, true, "for uni-proc machines : if true "
          "use sleep in synch_with_* wait loops instead of yield")
      OPTION_DEFAULT(bool, synch_thread_sleep_MP, true, "for multi-proc machines : if "
          "true use sleep in synch_with_* wait loops instead of yield")
      OPTION_DEFAULT(uint_time, synch_with_sleep_time, 5, "time in ms to sleep for each "
          "wait loop in synch_with_* routines")
  #ifdef WINDOWS
      /* FIXME - only an option since late in the release cycle - should always be on */
      OPTION_DEFAULT(bool, suspend_on_synch_failure_for_app_suspend, true, "if we fail "
          "to synch with a thread for an app suspend, suspend anyways to preserved the "
          "apps suspend count")
  #endif
  
      /* see in case 2520 why this is off by default for Windows */
      OPTION_DEFAULT(bool, ignore_syscalls, IF_WINDOWS_ELSE(false, true),
                     "ignore system calls that do not need to be intercepted")
      /* Whether we inline ignoreable syscalls inside of bbs (xref PR 307284) */
      OPTION_DEFAULT(bool, inline_ignored_syscalls, true,
                     "inline ignored system calls in the middle of bbs")
  #ifdef LINUX
      OPTION_DEFAULT(bool, hook_vsyscall, true, "hook vdso vsyscall if possible")
      /* PR 356503: workaround to allow clients to make syscalls */
      OPTION_ALIAS(sysenter_is_int80, hook_vsyscall, false, STATIC, OP_PCACHE_GLOBAL)
  #endif
  
      /* These should be made internal when sufficiently tested */
  #ifdef WINDOWS
      /* FIXME There's gotta be a better name for this. */
      OPTION_DEFAULT(bool, ignore_syscalls_follow_sysenter, true,
          "for ignore_syscalls, continue interp after the sysenter")
      /* Optimize syscall handling for syscalls that don't need to be intercepted
       * by DR by executing them using shared syscall. */
      OPTION_DEFAULT(bool, shared_syscalls, true, "syscalls that do not need to be intercepted are executed by shared syscall")
  
      /* Default TRUE as it's needed for shared_traces (which is on by default) */
      /* PR 361894: if no TLS available, we fall back to thread-private */
      OPTION_DEFAULT(bool, shared_fragment_shared_syscalls, IF_HAVE_TLS_ELSE(true, false),
          "enable fragments that use shared syscall to be share-able")
  
      /* Optimize shared syscall handling by using a faster code sequence if
       * possible. This currently works only w/-disable_traces. */
      OPTION_INTERNAL(bool, shared_syscalls_fastpath,
          "use a faster version of shared syscall")
      /* This option only applies when shared_syscalls is 'true'. 'true' means that
       * only ignorable syscalls can be optimized. 'false' means that a much broader
       * set of syscalls can be optimized -- any syscall that DR doesn't need to
       * intercept, as identified in the syscall_requires_action array in win32/os.c.
       */
      OPTION_INTERNAL(bool, shared_eq_ignore,
          "use ignorable syscall classification for shared_syscalls")
  
      /* We mark as pcache-affecting though we have other explicit checks */
      PC_OPTION_DEFAULT(uint, tls_align, 1, /* case 6770: for disabling alignment */
          /* 0 - use processor cache line */
          /* 1, 2, 4 - no alignment
           * 32 - Pentium III, Pentium M cache line
           * 64 - Pentium 4 cache line
           */
          /* FIXME: if we ever change our -tls_align default from 1 we should
           * consider implications on platform-independence of persisted caches
           */
          "TLS slots preferred alignment")
      /* We mark as pcache-affecting though we have other explicit checks */
      PC_OPTION_DEFAULT(uint, tls_flags, 1|2 /* TLS_FLAG_BITMAP_TOP_DOWN | 
                                            * TLS_FLAG_CACHE_LINE_START */, 
           "TLS allocation choices")
  #endif /* WINDOWS */
      OPTION_DEFAULT(bool, guard_pages, true, "add guard pages to our heap units")
  
  #ifdef PROGRAM_SHEPHERDING
      /* PR 200418: -security_api just turns on the bits of -security needed for the
       * Memory Firewall API */
      OPTION_COMMAND_INTERNAL(bool, security_api, false, "security_api", {
          if (options->security_api) {
              ENABLE_SECURITY(options);
          }
       }, "enable Security API", STATIC, OP_PCACHE_NOP)
  
      /* PR 200418: program shepherding is now runtime-option-controlled. Note - not
       * option_command_internal so that we can use for VPS release builds. */
      OPTION_COMMAND(bool, security, false, "security", {
          if (options->security) {
  
              options->diagnostics = true;
  
              /* xref PR 232126 */
              options->syslog_mask = SYSLOG_ALL;
              options->syslog_init = true;
              IF_INTERNAL(options->syslog_internal_mask = SYSLOG_ALL;)
  
              /* VPS had -use_moduledb by default (and then disabled with -staged) */
  
              ENABLE_SECURITY(options);
  
              /* memory wins over gcc/gap perf issues (PR 326815)
               * (ENABLE_SECURITY turns on -indirect_stubs for us)
               */
              options->coarse_units = true;
          }
       }, "enable Memory Firewall security checking", STATIC, OP_PCACHE_NOP)
  
      /* attack handling options */
      DYNAMIC_PCL_OPTION(bool, detect_mode, "only report security violations - will execute attackers code!")
      OPTION_COMMAND(uint, detect_mode_max, 0, "detect_mode_max", 
                     { options->detect_mode = true; }, 
                    "max number of security violations to allow in detect_mode - will revert to "
                    "next higher-priority handling option after the max", DYNAMIC, 
                    OP_PCACHE_NOP)
      DYNAMIC_OPTION(bool, diagnose_violation_mode, "on a security violations, report whether a trampoline")
      DYNAMIC_OPTION_DEFAULT(uint, report_max, 20, "max number of security violations to report, (0 is infinitely many)")
  
      /* alternatives to kill application */
      DYNAMIC_OPTION(bool, kill_thread, "kill offending thread only, WARNING: application may hang")
      OPTION_COMMAND(uint, kill_thread_max, 10, "kill_thread_max", 
                     { options->kill_thread = true; }, 
                     "max number of threads to kill before killing process", DYNAMIC, 
                     OP_PCACHE_NOP)
      DYNAMIC_OPTION(bool, throw_exception, "throw exception on security violations, WARNING: application may die")
      OPTION_COMMAND(uint, throw_exception_max, 10, "throw_exception_max",
                     { options->throw_exception = true; }, 
                     "max number of exceptions before killing thread or process", DYNAMIC,
                     OP_PCACHE_NOP)
      DYNAMIC_OPTION_DEFAULT(uint, throw_exception_max_per_thread, 10, "max number of exceptions per single thread")
      DYNAMIC_OPTION(uint_time, timeout, "timeout value to throttle down an attack")
      /* FIXME: should this apply to the whole process or the attacked thread only? */
  #  ifdef SIMULATE_ATTACK
      DYNAMIC_OPTION_DEFAULT(pathstring_t, simulate_at, EMPTY_STRING, "fragment count list for simulated attacks")
  #  endif
  
      /* case 280: remove futureexec areas for selfmod regions.
       * Disabled for now since -sandbox2ro_threshold invalidates its assumptions
       * (case 8167)
       */
      OPTION_DEFAULT(bool, selfmod_futureexec, true,
          "leave selfmod areas on the future-exec list")
  
      /* our default policies --- true by default, so you'd use no_ to turn them off
       * example: -no_executable_if_flush
       * note that if_flush and if_alloc use the future list, and so their regions
       * are considered executable until de-allocated -- even if written to!
       * N.B.: any changes in defaults must also change the -X command below!
       */
      /* N.B.: case 9799: any changes in policy or exemption default values may
       * require changing from PC_ to PCL_, and changing whether we mark modules as
       * exempted!
       */
      OPTION(bool, code_origins, "check that code origins meet security policies")
  #  ifdef WINDOWS
      PC_OPTION_DEFAULT(bool, executable_if_flush, true, "allow execution after a region has been NtFlushInstructionCache-d")
      PC_OPTION(bool, executable_after_load, "allow execution from region marked x but modified during load time (normal behavior for relocation or rebinding)")
      PC_OPTION_DEFAULT(bool, emulate_IAT_writes, true, "keep IAT non-w, emulate writes there")
      PC_OPTION_DEFAULT(bool, unsafe_ignore_IAT_writes, false,
         "ignore IAT writes by the loader, assuming nothing else writes at the same time")
  #  endif
      PC_OPTION_DEFAULT(bool, executable_if_rx_text, true, "allow execution from any rx portion of the text section, subsumes -executable_after_load")
      PC_OPTION_DEFAULT(bool, executable_if_alloc, true, "allow execution from certain regions marked x at allocation time")
      PC_OPTION_DEFAULT(bool, executable_if_trampoline, true, "allow execution from pattern-matched trampoline blocks")
      PC_OPTION_DEFAULT(bool, executable_if_hook, true, "allow execution from text section briefly marked rwx")
  
      /* specific trampoline exemptions */
      PC_OPTION_DEFAULT(bool, trampoline_dirjmp, true, "allow direct jmp trampoline")
      PC_OPTION_DEFAULT(bool, trampoline_dircall, true, "allow direct call trampoline")
      /* not needed w/ native_exec but may be needed in the future */
      PC_OPTION(bool, trampoline_com_ret, "allow .NET COM method table ret trampoline")
      /* allow simple hook displacement of original code */
      PC_OPTION_DEFAULT(bool, trampoline_displaced_code, true,
          "allow hook-displaced code trampoline")
      PC_OPTION_DEFAULT(bool, executable_if_driver, true, 
          "allow execution from a kernel-mode address (case 9022)")
      PC_OPTION_DEFAULT(bool, driver_rct, true, 
         /* marked as VM_DRIVER_ADDRESS */
          "allow any RCT if source is from a kernel-mode address (case 9022/9096)")
  
      /* methods to loosen policies */
      PCL_OPTION(bool, executable_if_text,  "allow execution from text sections of modules, subsumes -executable_if_rx_text")
      PCL_OPTION(bool, executable_if_dot_data,  "allow execution from .data sections of modules")
      PCL_OPTION(bool, executable_if_dot_data_x,  "allow execution from .data sections of modulesif marked x")
      /* ..x means care about execute permission, but not read or write; 
       * .-x means care about execute with no write permission. See case 3287.
       */
      PCL_OPTION(bool, executable_if_x, "allow execution from regions marked ..x")
      PCL_OPTION(bool, executable_if_rx, "allow execution from regions marked .-x")
      PCL_OPTION(bool, executable_if_image, "allow execution from any mapped section from an executable or library image")
      OPTION(bool, executable_stack, "allow execution from the stack")
      OPTION(bool, executable_heap, "allow execution from the heap")
      /* Obfuscated options how to suppress security violations of types A and B */
      OPTION_ALIAS(A, executable_stack, true, STATIC, OP_PCACHE_NOP/*no effect on images*/)
      OPTION_ALIAS(B, executable_heap, true, STATIC, OP_PCACHE_NOP/*no effect on images*/)
      /* each exempt list has a corresponding boolean for easy disabling */
      PCL_OPTION_DEFAULT(bool, exempt_text, true, "allow execution from exempt text sections")
      PCL_OPTION_DEFAULT(liststring_t, exempt_text_list, EMPTY_STRING, "allow execution from text sections of these ;-separated modules")
      PC_OPTION_DEFAULT(liststring_t, exempt_mapped_image_text_default_list, 
          /* case 9385 - loaded in unknown thread  */
          OPTION_STRING("LVPrcInj.dll"), 
          "allow execution from text sections in MEM_IMAGE mappings"
          " of these ;-separated modules, default")
      PCL_OPTION_DEFAULT(liststring_t, exempt_mapped_image_text_list, EMPTY_STRING, 
          "allow execution from text sections in MEM_IMAGE mappings"
          " of these ;-separated modules, append")
  
      PCL_OPTION_DEFAULT(bool, exempt_dot_data, true, "allow execution from exempt .data sections")
      /* xref case 4244 on SM2USER.dll */ 
      /* FIXME case 9799: since default not split out, anything on this list
       * by default will not have shared pcaches for any process w/ ANY non-default
       * exemption lists */
      PCL_OPTION_DEFAULT(liststring_t, exempt_dot_data_list, OPTION_STRING("SM2USER.dll"), "allow execution from .data sections of these ;-separated modules")
      PCL_OPTION_DEFAULT(bool, exempt_dot_data_x, true, "allow execution from exempt .data sections if marked x")
      /* Case 7345: allow all kdb*.dlls for shark; later on (porpoise?) implement
       * -executable_if_dot_data_rx, turn it on by default and set this exempt 
       * list to empty.
       */
      /* FIXME case 9799: since default not split out, anything on this list
       * by default will not have shared pcaches for any process w/ ANY non-default
       * exemption lists */
      PCL_OPTION_DEFAULT(liststring_t, exempt_dot_data_x_list, OPTION_STRING("kbd??.dll;kbd???.dll;kbd????.dll;kbd?????.dll"), "allow execution from .data sections of these ;-separated modules if marked x")
      PCL_OPTION_DEFAULT(bool, exempt_image, true, "allow execution from exempt image modules")
      PCL_OPTION_DEFAULT(liststring_t, exempt_image_list, EMPTY_STRING, "allow execution from anywhere in the image of these ;-separated modules")
      OPTION_DEFAULT(bool, exempt_dll2heap, true, "allow execution in heap first targeted by exempt modules")
      OPTION_DEFAULT(liststring_t, exempt_dll2heap_list, EMPTY_STRING, "allow execution in heap first targeted by these ;-separated modules")
      OPTION_DEFAULT(bool, exempt_dll2stack, true, "allow execution in stack first targeted by exempt modules")
      OPTION_DEFAULT(liststring_t, exempt_dll2stack_list, EMPTY_STRING, "allow execution in stack first targeted by these ;-separated modules")
      DYNAMIC_PCL_OPTION_DEFAULT(bool, exempt_threat, true, "allow exempt threat ids")
      DYNAMIC_PCL_OPTION_DEFAULT(liststring_t, exempt_threat_list, EMPTY_STRING, "silently allow these ;-separated threat ids, ? wildcards allowed")
      DYNAMIC_OPTION_DEFAULT(liststring_t, silent_block_threat_list, EMPTY_STRING, "silently block these ;-separated threat ids, ? wildcards allowed")
      /* note that exempt_threat_list takes precedence over silent_block_threat_list */
  
  #  ifdef RETURN_AFTER_CALL
      PC_OPTION_DEFAULT(bool, ret_after_call, false, "return after previous call instructions only")
  
      /* Obfuscated option how to suppress security violations of type C */
      OPTION_ALIAS(C, ret_after_call, false, STATIC, OP_PCACHE_GLOBAL)
  
      PC_OPTION_DEFAULT(bool, vbjmp_allowed, true, "allow execution of VB direct jmp via ret")
      PC_OPTION_DEFAULT(bool, vbpop_rct, true, "allow execution of VB pop via ret")
      PC_OPTION_DEFAULT(bool, fiber_rct, true, "allow execution of fiber initialization")
      PC_OPTION_DEFAULT(bool, mso_rct, true, "allow execution of MSO continuations") /* FIXME: no clue what it is */
      PC_OPTION_DEFAULT(bool, licdll_rct, true, "allow execution of licdll obfuscated call") /* FIXME: no clue what it is */
      PC_OPTION_DEFAULT(bool, seh_rct, true, "allow execution of SEH ret constructs")
      /* xref case 5752 */
      PC_OPTION_DEFAULT(bool, borland_SEH_rct, true,
          "allow execution of borland SEH constructs")
      /* case 7317, from SQL2005 case 6534
       * off by default as case 7266 has us currently running these dlls natively
       */
      PC_OPTION(bool, pushregret_rct, "allow execution of push;ret constructs")
      /* PR 276529: ntdll64!RtlRestoreContext uses iret as a general jmp* */
      PC_OPTION_DEFAULT(bool, iret_rct, IF_X64_ELSE(true, false),
          "allow ntdll64!RtlRestoreContext iret")
      /* case 7319, from SQL2005 cases 6541 and 6534 
       * off by default as case 7266 has us currently running these dlls natively
       */
      PC_OPTION(bool, xdata_rct, "allow ret to .xdata NtFlush targets")
      PC_OPTION_DEFAULT(bool, exempt_rct, true, "allow rct in exempt modules")
      /* case 9725 slsvc.exe->heap .C (software licensing service on Vista) 
       * FIXME slsvc.exe is also in exempt_rct_to_default_list for slsvc.exe -> slsvc.exe
       * .C violations which would be covered here if it weren't for case 285. */
      PC_OPTION_DEFAULT(liststring_t, exempt_rct_default_list,
          OPTION_STRING("dpcdll.dll;licdll.dll;mso.dll;winlogon.exe;sysfer.dll;slsvc.exe"),
          "allow rct within these ;-separated modules or to DGC")
      PCL_OPTION_DEFAULT(liststring_t, exempt_rct_list, EMPTY_STRING,
          "allow rct within these ;-separated modules or to DGC, append")
  
      /* exempt_rct_from_{default,}_list are less strict than exempt_rct_list */
      PCL_OPTION_DEFAULT(liststring_t, exempt_rct_from_default_list, 
          EMPTY_STRING, "allow rct from these ;-separated modules")
      PCL_OPTION_DEFAULT(liststring_t, exempt_rct_from_list, 
          EMPTY_STRING, "allow rct from these ;-separated modules, append")
  
      /* exempt_rct_to_{default,}_list are less strict than exempt_rct_list */
       /* case 1690 dpcdll.dll, licdll.dll; case 1158 mso.dll */
       /* case 1214 winlogon.exe */
       /* case 5912 .F sysfer.dll, 
        * FIXME: should be in exempt_rct_default_list, case 285 */
       /* case 6076 blackd.exe: .F iss-pam1.dll ---> iss-pam1.dll, 
        * FIXME: should be in exempt_rct_default_list, case 285 */
       /* case 5051 w3wp.exe: .C jmail.dll ---> jmail.dll, 
        * FIXME: should be in exempt_rct_default_list, case 285 */
       /* case 6412, 7659: .E msvbvm50.dll;msvbvm60.dll;vbe6.dll */
       /* case 9385 LVPrcInj.dll loaded by unknown thread */
       /* case 9716 slc.dll (software licensing dll) on Vista .C */
       /* case 9724 slsvc.exe->slsvc.exe (software licensing service) on Vista .C
        * FIXME: should be only in exempt_rct_default_list, case 285 */
      PC_OPTION_DEFAULT(liststring_t, exempt_rct_to_default_list, 
          OPTION_STRING("dpcdll.dll;licdll.dll;mso.dll;winlogon.exe;sysfer.dll;iss-pam1.dll;jmail.dll;msvbvm50.dll;msvbvm60.dll;vbe6.dll;LVPrcInj.dll;slc.dll;slsvc.exe"),
          "allow rct to these ;-separated modules")
      PCL_OPTION_DEFAULT(liststring_t, exempt_rct_to_list, 
          EMPTY_STRING, "allow rct to these ;-separated modules, append")
  
       /* case 2144 - FIXME: should we have a general exemption for .A and .B as well? */
       /* note we want to silently handle a .C - and to preserve compatibility with previous
        * releases we use the default attack handling (e.g. kill thread for services)
        */
      OPTION_DEFAULT(uint, rct_ret_unreadable, OPTION_ENABLED|OPTION_BLOCK|OPTION_NO_HANDLING|OPTION_NO_REPORT,
          "alternative handling of return targets in unreadable memory")
      /* note indirect call and indirect jump will always just throw an exception */
  
       /* case 5329 - leaving for bug-compatibility with previous releases */
      PC_OPTION(bool, rct_sticky, 
           "leaves all RCT tables on unmap, potential memory leak")
       /* case 9331 - FIXME: still leaking on DGC */
      PC_OPTION_DEFAULT(bool, rac_dgc_sticky, true,
           "leaves all RAC tables from DGC, potential memory leak")
  
      PC_OPTION_DEFAULT(uint, rct_cache_exempt, 1, /* RCT_CACHE_EXEMPT_MODULES */
          "whether to cache exempted addresses, 0 never, 1 only in modules, 2 always")
  
      PC_OPTION_DEFAULT(uint, rct_section_type, 0x20, /* IMAGE_SCN_CNT_CODE */
          "bitflag to enable RCT checks on module code 0x20,data 0x40, or uninitialized sections 0x80")
      PC_OPTION_DEFAULT(uint, rct_section_type_exclude,
          0x80000020, /* IMAGE_SCN_MEM_WRITE|IMAGE_SCN_CNT_CODE, xref case 8360 */
          "TESTALL bitflag to disable RCT checks for specific module sections sections that are matched by rct_section_type")
  
      PC_OPTION_DEFAULT(bool, rct_modified_entry, true,
          "if not within module, lookup image entry point"
          "in LDR list for already mapped modules, and at MapViewOfSection for late") 
       /* expected to be overwritten by mscoree.dll */
  
  #   ifdef RCT_IND_BRANCH
      /* case 286 */
      /* FIXME: currently OPTION_ENABLED doesn't do much yet, see rct_process_module_mmap() for details */
      /* FIXME: not yet supported on Linux (case 4983) */
      PC_OPTION_DEFAULT(uint, rct_ind_call, OPTION_DISABLED,
          "indirect call policy: address taken instructions only")
      PC_OPTION_DEFAULT(uint, rct_ind_jump, OPTION_DISABLED,
          "indirect jump policy: address taken or return targets")
  
      PC_OPTION_DEFAULT(bool, rct_analyze_at_load, true,
          "analyze modules for ind branch targets at module load time")
  
      PC_OPTION_DEFAULT(bool, rct_reloc, true,
          "use relocation information to find references")
  
      /* PR 215408: even when we have reloc info, we need to scan for rip-rel lea,
       * but only in modules that executed code we didn't see.
       * This option controls whether we proactively scan or only rely on our
       * scan-on-violation (PR 277044/277064).
       */
      PC_OPTION_DEFAULT(bool, rct_scan_at_init, IF_X64_ELSE(true, false),
          "scan modules present at inject time for rip-rel lea even when relocs are present")
      /* PR 275723: RVA-table-based switch statements.  Not on for Linux b/c we
       * don't have per-module RCT tables there.
       */
      PC_OPTION_DEFAULT(bool, rct_exempt_intra_jmp,
          IF_X64_ELSE(IF_WINDOWS_ELSE(true, false), false),
          "allow jmps to target any intra-module address")
  
      /* Obfuscated options to suppress security violations of types E and F */
      OPTION_ALIAS(E, rct_ind_call, OPTION_DISABLED, STATIC, OP_PCACHE_GLOBAL)
      OPTION_ALIAS(F, rct_ind_jump, OPTION_DISABLED, STATIC, OP_PCACHE_GLOBAL)
  #   endif /* RCT_IND_BRANCH */
  #  endif /* RETURN_AFTER_CALL */
  
       /* FIXME: there must be a way to make sure that new security
        * options are added here; and less importantly make sure that
        * when options are turned off by default they are taken out
        */
      OPTION_COMMAND(bool, X, false, "X", {
  IF_RETURN_AFTER_CALL(options->ret_after_call = false;)
  IF_WINDOWS(options->executable_if_flush = false;)
          options->executable_if_alloc = false; 
          options->executable_if_trampoline = false; 
          options->executable_if_hook = false; 
          options->executable_if_x = true;
  IF_RCT_IND_BRANCH(options->rct_ind_call = OPTION_DISABLED;)
  IF_RCT_IND_BRANCH(options->rct_ind_jump = OPTION_DISABLED;)
      }, "duplicate Microsoft's nx: allow x memory only and don't enforce RCT", DYNAMIC, 
      OP_PCACHE_GLOBAL/*since is not only a relaxation*/)
  
  #endif /* PROGRAM_SHEPHERDING */
  
      OPTION_DEFAULT(bool, enable_block_mod_load, true,
           "switch for enabling the block module from being loaded feature, if enabled the modules to block from loading are specified by the block_mod_load_list[_default] options") 
      /* dynamorio.dll : on this list to prevent non early_inject follow
       * children from double injecting if the process is already under dr */
       /* entapi.dll;hidapi.dll : case 2871 for Entercept/VirusScan */
       /* Caution: add to this list only DLLs whose callers don't crash
        * if LdrLoadDll calls fail, e.g. do not use the result for
        * GetProcAddress.
        */
      OPTION_DEFAULT(liststring_t, block_mod_load_list_default,
          OPTION_STRING("dynamorio.dll;entapi.dll;hidapi.dll"),
          "if -enable_block_mod_load block the loading (at LdrLoadDll) of the following ;-separated modules, note that since this is blocking at LdrLoadDll the module match will be based on the filename of module being loaded NOT the PE name (which is used by most other options)")
      OPTION_DEFAULT(liststring_t, block_mod_load_list, EMPTY_STRING,
          "if -enable_block_mod_load, block the loading (at LdrLoadDll) of the following ;-separated modules, note that since this is blocking at LdrLoadDll the module match will be based on the filename of module being loaded NOT the PE name (which is used by most other options)")
  
      OPTION_DEFAULT(uint, handle_DR_modify, 1 /*DR_MODIFY_NOP*/, "specify how to handle app attempts to modify DR memory protection: either halt with an error, turn into a nop (default), or return failure to the app")
  
      OPTION_DEFAULT(uint, handle_ntdll_modify, 1 /*DR_MODIFY_NOP*/, "specify how to handle app attempts to modify ntdll code: either halt with an error, turn into a nop (default), or return failure to the app")
  
      /* generalized DR_MODIFY_NOP for customizable list of modules */
      OPTION_DEFAULT(liststring_t, patch_proof_default_list,
          EMPTY_STRING, "ignore protection changes and writes to text of ;-separated module list, or * for all")
          /* note '*' has to be at first position to mean all modules */
      OPTION_DEFAULT(liststring_t, patch_proof_list,
          EMPTY_STRING, "ignore protection changes and writes to text of ;-separated module list, append, or * for all")
          /* note '*' has to be at first position to mean all modules */
  
      PC_OPTION_DEFAULT(bool, use_moduledb, false, "activate module database")
      OPTION_ALIAS(staged, use_moduledb, false, STATIC, OP_PCACHE_GLOBAL) /* xref case 8924 */
      /* FIXME - can't handle a company name with a ; in it */
      PC_OPTION_DEFAULT(liststring_t, whitelist_company_names_default, OPTION_STRING(COMPANY_LONG_NAME), "don't relax protections as part of moduledb matching for these ; separated company names")
      PC_OPTION_DEFAULT(liststring_t, whitelist_company_names, OPTION_STRING("Microsoft Corporation"), "don't relax protections as part of moduledb matching for these ; separated company names")
      PC_OPTION_DEFAULT(uint, unknown_module_policy, 0xf /*MODULEDB_RCT_EXEMPT_TO|MODULEDB_ALL_SECTIONS_BITS:SECTION_ALLOW|MODULEDB_REPORT_ON_LOAD*/, "module policy control field for non-whitelisted modules")
      OPTION_DEFAULT(uint, unknown_module_load_report_max, 10, "max number of non whitelist modules to log/report at load time")
      OPTION_DEFAULT(uint, moduledb_exemptions_report_max, 3, "max number of moduledb security exemptions to report")
      /* case 9330 detect race in our security policies during DLL
       * unload, and also case 9364 for .C only after unload
       */
      OPTION_DEFAULT(bool, unloaded_target_exception, true,
          "detect and silently handle as exceptions app races during DLL unload")
  
  #ifdef WINDOWS
      OPTION_DEFAULT(bool, hide, true, "remove DR dll from module lists")
      OPTION_DEFAULT(uint, hide_from_query, 
          3 /* HIDE_FROM_QUERY_BASE_SIZE|HIDE_FROM_QUERY_TYPE_PROTECT */, 
          "mask to control what option to take to hide dr when the app does a query virtual memory call on our dll base") 
  
      OPTION_DEFAULT(bool, track_module_filenames, true,
          "track module file names by watching section creation")
  
      /* FIXME: since we have dynamic options this option can be false for most of the time,
       * and the gui should set true only when going to detach to prevent a security risk.
       * The setting should be removed when detach is complete.
       * In vault mode: -no_allow_detach -no_dynamic_options
       */
      DYNAMIC_OPTION_DEFAULT(bool, allow_detach, true, "allow detaching from process")
  #endif
  
      /* turn off critical features, right now for experimentation only */
  #ifdef WINDOWS
      PC_OPTION_INTERNAL(bool, noasynch, "disable asynchronous event interceptions")
  #endif
      PC_OPTION_DEFAULT_INTERNAL(bool, cache_consistency, true, "keep code cache consistent?")
      OPTION_DEFAULT_INTERNAL(bool, sandbox_writes, true, "check each sandboxed write for selfmod?")
      /* FIXME: off by default until dll load perf issues are solved: case 3559 */
      OPTION_DEFAULT_INTERNAL(bool, safe_translate_flushed, false,
          "store info at flush time for safe post-flush translation")
      PC_OPTION_INTERNAL(bool, store_translations,
          "store info at emit time for fragment translation")
  
       /* case 8812 - owner validation possible only on Win32 */
       /* Note that we expect correct ACLs to prevent anyone other than
        * owner to have overwritten the files.
        */
      OPTION_DEFAULT(bool, validate_owner_dir, true,
                     "validate owner of persisted cache or ASLR directory")
      OPTION_DEFAULT(bool, validate_owner_file, false,
                     "validate owner of persisted cache or ASLR, on each file")
  
      /* PR 326815: off until we fix gcc+gap perf */
      OPTION_COMMAND(bool, coarse_units, false, "coarse_units", {
          if (options->coarse_units) {
              /* PR 326610: we turned off -indirect_stubs by default, but
               * -coarse_units doesn't support that yet (that's PR 213262).
               */
              options->indirect_stubs = true;
          }
      }, "use coarse-grain code cache management when possible", STATIC, OP_PCACHE_GLOBAL)
  
      /* Currently a nop, but left in for the future */
      OPTION_ALIAS(enable_full_api, coarse_units, false, STATIC, OP_PCACHE_GLOBAL)
  
      OPTION_DEFAULT(bool, coarse_enable_freeze, false,
                     "enable freezing of coarse units")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_at_exit, false,
                             "freeze coarse units at process exit")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_at_unload, false,
                             "freeze coarse units at module unload or other flush")
      /* Remember that this is a threshold on per-module per-run new generated code.
       * Though bb building time would recommend a fragment count threshold, for
       * sharing benefits we care about code size.
       * Remember also that we get wss and time improvements from RCT table
       * being persisted; yet a large module w/ many RCT targets is likely to have
       * a lot of code, though we may not execute much of it, so we have
       * the coarse_freeze_rct_min option.
       * Xref case 10362 on using pcache files for RCT independently of code caches.
       */
      DYNAMIC_OPTION_DEFAULT(uint_size, coarse_freeze_min_size, 512,
                             "only freeze new coarse code > this cache size (bytes)")
      DYNAMIC_OPTION_DEFAULT(uint_size, coarse_freeze_append_size, 256,
                             "only append new coarse code > this cache size (bytes)")
      DYNAMIC_OPTION_DEFAULT(uint_size, coarse_freeze_rct_min, 2*1024,
                             "freeze a coarse module w/ > this RCT entries")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_clobber, false,
                             "overwrite existing persisted temp files")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_rename, true,
                             "rename existing persisted files when writing new ones")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_clean, true,
                             "delete renamed persisted files")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_freeze_merge, true,
                             "merge unfrozen coarse code with frozen code when persisting")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_lone_merge, true,
                             "merge un-persisted unit w/ disk file when persisting")
      DYNAMIC_OPTION_DEFAULT(bool, coarse_disk_merge, true,
                             "merge persisted unit w/ disk file when persisting")
      /* We have explicit support for mixing elision at gen and use so not PC_ */
      OPTION_DEFAULT(bool, coarse_freeze_elide_ubr, true,
                     "elide fall-through ubr when freezing coarse units")
      /* case 9677: unsafe to elide entire-bb-ubr since creates backmap ambiguity */
      PC_OPTION(bool, unsafe_freeze_elide_sole_ubr,
                     "elide sole-ubr-bb fall-through ubr when freezing coarse units")
      OPTION_DEFAULT(bool, coarse_pclookup_table, true,
                     "use a reverse cache lookup table for faster entry-pc lookup,"
                     "critical for performance of frozen units + trace building")
      OPTION_DEFAULT(bool, persist_per_app, false,
                     "use separate persisted cache per executable")
      OPTION_DEFAULT(bool, persist_per_user, true,
                     "use separate persisted cache per user")
      OPTION_DEFAULT(bool, use_persisted, false,
                     "use persisted cache if it exists")
      /* exemptions are based on canonical DR names (case 3858) */
      OPTION_DEFAULT(liststring_t, persist_exclude_list, EMPTY_STRING,
          "exclude these ;-separated modules from persisted use and generation")
  #ifdef RCT_IND_BRANCH
      OPTION_DEFAULT(bool, persist_rct, true,
                     "persist RCT (call* target) tables; if this option is off, "
                     "we will still persist for Borland modules, but no others")
      OPTION_DEFAULT(bool, persist_rct_entire, true,
                     "if -persist_rct, persist RCT tables for entire module")
      OPTION_DEFAULT(bool, use_persisted_rct, true,
                     "use persisted RCT info, if available, instead of analyzing module")
  #endif
  #ifdef HOT_PATCHING_INTERFACE
      OPTION_DEFAULT(bool, use_persisted_hotp, true,
                     "use persisted hotp info to avoid flushing perscaches")
  #endif
      OPTION_DEFAULT(uint, coarse_fill_ibl,
                     1, /* mask from 1<<IBL_type (1=ret|2=call*|4=jmp*) indicating
                         * which per-type table(s) to fill */
                     "fill 1st thread's ibl tables from persisted RAC/RCT tables")
      /* FIXME case 9599: w/ MEM_MAPPED this option removes COW from the cache */
      /* FIXME: could make PC_ to coexist for separate values */
      OPTION_DEFAULT(bool, persist_map_rw_separate, true,
                     "map persisted read-only sections separately to support sharing"
                     "(option must be on both when generated and when using)")
      OPTION_DEFAULT(bool, persist_lock_file, true,
                     "keep persisted file handle open to prevent writes/deletes")
      /* FIXME: could make PC_ to coexist for separate values */
      /* PR 215036: linux does not support PERSCACHE_MODULE_MD5_AT_LOAD */
      OPTION_DEFAULT(uint, persist_gen_validation, IF_WINDOWS_ELSE(0x1d,0xd),
                     /* PERSCACHE_MODULE_MD5_SHORT | PERSCACHE_MODULE_MD5_AT_LOAD |
                        PERSCACHE_GENFILE_MD5_{SHORT,COMPLETE} */
          "controls md5 values that we store when we persist")
      OPTION_DEFAULT(uint, persist_load_validation, 0x5,
                     /* PERSCACHE_MODULE_MD5_SHORT | PERSCACHE_GENFILE_MD5_SHORT */
          "controls which md5 values we check when we load a persisted file; must "
          "be a subset of -persist_gen_validation, else we won't load anything")
      /* Size of short checksum of file header and footer for PERSCACHE_MODULE_MD5_SHORT.
       * Size must match that in effect at persist time. */
      PC_OPTION_DEFAULT(uint_size, persist_short_digest, (4*1024),
          "size of file header and footer to check, in KB or MB")
      OPTION_DEFAULT(bool, persist_check_options, true,
          "consider pcache-affecting options when using pcaches")
      PC_OPTION_DEFAULT(bool, persist_check_local_options, false,
          "include all local options in -persist_check_options")
      PC_OPTION_DEFAULT(bool, persist_check_exempted_options, true,
          "only check local options for modules affected by exemptions")
      /* FIXME: make this part of -protect_mask? */
      OPTION_DEFAULT(bool, persist_protect_stubs, true,
          "keep persisted cache stubs read-only")
      OPTION_DEFAULT(uint, persist_protect_stubs_limit, 0,
          "stop write-protecting stubs after this many writes (0 protects forever)")
      /* case 10074: we can trade working set to reduce pagefile, strangely */
      OPTION_DEFAULT(bool, persist_touch_stubs, true,
          "touch stubs prior to protecting to avoid pagefile cost")
      /* case 8640: relies on -executable_{if_rx_text,after_load} */
      PC_OPTION_DEFAULT(bool, coarse_merge_iat, true,
          "merge iat page into coarse unit at +rx transition")
      /* PR 214084: avoid push of abs addr in pcache
       * TODO: should auto-enable (on Linux or Vista+ only?) for -coarse_enable_freeze?
       */
      PC_OPTION_DEFAULT(bool, coarse_split_calls, false,
          "make all calls fine-grained and in own bbs")
  #ifdef LINUX
      OPTION_DEFAULT(bool, persist_trust_textrel, true,
          "if textrel flag is not set, assume module has no text relocs")
  #endif
  
      /* case 10339: tuned for boot and memory performance, not steady-state */
      OPTION_COMMAND(bool, desktop, false, "desktop", {
             if (options->desktop) {
                 options->coarse_enable_freeze = true;
                 options->use_persisted = true;
                 options->coarse_freeze_at_unload = true;
                 DISABLE_TRACES(options);
                 options->shared_bb_ibt_tables = true;
                 /* case 10525/8711: reduce # links via single fine-grained vsyscall bb
                  * N.B.: if we re-enable traces we'll want to turn this back on
                  */
                 options->indcall2direct = false;
                 /* case 9686: for now reset is a nop until we decide what it
                  * should do wrt pcaches */
                 DISABLE_RESET(options);
             } else {
                 /* -no_desktop: like -no_client, only use in simple
                  * sequences of -desktop -no_desktop
                  */
                 options->coarse_enable_freeze = false;
                 options->use_persisted = false;
                 options->coarse_freeze_at_unload = false;
                 REENABLE_TRACES(options);
                 options->shared_bb_ibt_tables = false;
                 options->indcall2direct = true;
                 REENABLE_RESET(options);
             }
          }, "desktop process protection",
          STATIC, OP_PCACHE_GLOBAL)
  
       /* should probably always turn on -executable_if_text if turning this on, for
        * modules loaded by natively-executed modules
        * these don't affect pcaches since the trampoline bbs won't be coarse-grain.
        */
      OPTION_DEFAULT(bool, native_exec, true, "attempt to execute certain libraries natively (WARNING: lots of issues with this, use at own risk)")
       /* initially populated w/ all dlls we've needed to get .NET, MS JVM, Sun JVM, 
        * Symantec JVM, and Panda AV working, but with very limited workload testing so far
        */
      OPTION_DEFAULT(liststring_t, native_exec_default_list, 
                     /* case 3453, case 1962 .NET 1.0, 1.1 : mscorsvr.dll;mscorwks.dll;aspnet_isapi.dll */
                     /* case 6189 .NET 2.0: mscorwks_ntdef.dll(PE name of mscorwks.dll);aspnet_isapi.dll */
                     /* case 3453 MS JVM: msjava.dll;msawt.dll, Sun JVM: jvm.dll */
                     /* case 3749 Symantec Java! JIT: symcjit.dll */
                     /* case 3762 Panda AV: pavdll.dll */
                     OPTION_STRING("mscorsvr.dll;mscorwks.dll;aspnet_isapi.dll;mscorwks_ntdef.dll;msjava.dll;msawt.dll;jvm.dll;symcjit.dll;pavdll.dll"),
                     "execute these ;-separated modules natively")
      /* easy way to add dlls w/o having to re-specify default list, while keeping 
       * default list visible and settable at global level 
       */
      OPTION_DEFAULT(liststring_t, native_exec_list, EMPTY_STRING,
                     "execute these ;-separated modules natively")
      OPTION_DEFAULT(bool, native_exec_syscalls, true, "intercept system calls while application is native")
      OPTION_DEFAULT(bool, native_exec_dircalls, true, "check direct calls as gateways to native_exec modules")
      OPTION_DEFAULT(bool, native_exec_callcall, true, "put gateway on 1st call of a pair where 2nd targets a native_exec module")
      OPTION_DEFAULT(bool, native_exec_guess_calls, true, "if TOS looks like a ret addr, assume transition to a new module was via call*")
      /* case 7266: add exes and dlls with managed code to native_exec_areas */
      OPTION_DEFAULT(bool, native_exec_managed_code, true,
          "if module has managed code, execute it natively")
      /* case 10998: add modules with .pexe sections to native_exec_areas,
       * FIXME - for case 6765 turn this into a liststring_t so we can consider native exec
       * for other potentially problematic sections like .aspack, .pcle, and .sforce */
      OPTION_DEFAULT(bool, native_exec_dot_pexe, true,
          "if module has .pexe section (proxy for strange int 3 behavior), execute it natively")    
  
      /* vestiges from our previous life as a dynamic optimizer */
      OPTION_DEFAULT_INTERNAL(bool, inline_calls, true, "inline calls in traces")
  
      /* control-flow optimization to convert indirect calls to direct calls.
       * This is separated from the optimization flags that follow below as it
       * applies to all fragments, not just traces.
       * FIXME Delete the setting after sufficient testing & qualification?
       */
      PC_OPTION_DEFAULT(bool, indcall2direct, true,
          "optimization: convert indirect calls to direct calls")
  
      /* case 85 - for optimization, and case 1948 for its basis for a stronger security check */
      /* similar to both indcall2direct and emulate_IAT_writes */
      PC_OPTION_DEFAULT(bool, IAT_convert, false,
          "convert indirect call or jmp through IAT to direct call or jmp")
      PC_OPTION_DEFAULT(bool, IAT_elide, false,
          "elide indirect call or jmp converted by IAT_convert"
          "unless reached max_elide_{jmp,call}; requires IAT_convert")
      OPTION_DEFAULT_INTERNAL(bool, unsafe_IAT_ignore_hooker, false, "ignore IAT writes")
  
      /* compatibility options */
      OPTION_DEFAULT(uint, thread_policy, 
          OPTION_DISABLED|OPTION_NO_BLOCK|OPTION_NO_REPORT|OPTION_NO_CUSTOM,
           "thread delivered to a writable region allowed or squashed (optionally silently)")
      /* custom bit off restricts thread_policy to VSE shellcode, on makes it general */
  #ifdef WINDOWS
      OPTION_DEFAULT(uint, apc_policy, 
          OPTION_DISABLED|OPTION_NO_BLOCK|OPTION_NO_REPORT|OPTION_NO_CUSTOM,
           "APC delivered to a writable region allowed or squashed (optionally silently)")
      /* custom bit off restricts apc_policy to VSE shellcode, on makes it general */
  
      OPTION_DEFAULT_INTERNAL(bool, hook_image_entry, true, "Allow hooking of the image "
          "entry point when we lose control at a pre-image-entry-point callback return. "
          "Typically it's not needed to regain control if -native_exec_syscalls is on.")
      OPTION_DEFAULT(bool, clean_testalert, true, /* case 9288, 10414 SpywareDoctor etc. */
          "restore NtTestAlert to a pristine state at load by clearing away any hooks")
      OPTION_DEFAULT(uint, hook_conflict, 1 /* HOOKED_TRAMPOLINE_SQUASH */, /* case 2525 */
          "action on conflict with existing non Nt* hooks: die, squash or chain")
      OPTION_DEFAULT(uint, native_exec_hook_conflict, 
          1 /* HOOKED_TRAMPOLINE_SQUASH */,
          "action on conflict with existing Nt* hooks: die, squash, or deeper")
      /* NOTE - be careful about using the default value till the options are
       * read */
      OPTION_DEFAULT(bool, dr_sygate_int, false,
          "Perform dr int system calls in a sygate compatible fashion (indirected via ntdll)")
      OPTION_DEFAULT(bool, dr_sygate_sysenter, false,
          "Perform dr int system calls in a sygate compatible fashion (indirected via ntdll)")
       /* Turn off sygate compatibility int syscall indirection for app system
        * calls.  Dr system calls will still indirect as controlled by 
        * above options. */
      OPTION_DEFAULT(bool, sygate_int, false,
          "Perform app int system calls in Sygate compatible fashion (indirected via ntdll)")
      OPTION_DEFAULT(bool, sygate_sysenter, false,
          "Perform app sysenter system calls in Sygate compatible fashion (indirected via ntdll)")
      OPTION_DEFAULT(bool, native_exec_hook_create_thread, true, 
          "if using native_exec hooks, decides whether or not to hook CreateThread (disable for Sygate compatibility)")
      OPTION_COMMAND(bool, sygate, false, "sygate", {
              options->dr_sygate_int = true;
              options->dr_sygate_sysenter = true;
              options->sygate_int = true;
              options->sygate_sysenter = true;
              options->native_exec_hook_conflict = 3; /* HOOK_CONFLICT_HOOK_DEEPER */
              options->native_exec_hook_create_thread = false;
          }, "Sets necessary options for running in Sygate compatible mode",
          STATIC, OP_PCACHE_NOP)
  
      /* FIXME - disabling for 64bit due to layout considerations xref PR 215395,
       * should re-enable once we have a better solution. xref PR 253621 */
      OPTION_DEFAULT(bool, aslr_dr, IF_X64_ELSE(false, true),
          /* case 5366 randomize location of dynamorio.dll, uses
           * aslr_parent_offset to control randomization padding which
           * currently gives us 8 bits of randomness for wasting 16MB
           * virtual space; breaks sharing for the relocated
           * portions of our DLL
           */
          "randomization needs to be set in parent process")
  
       /* Address Space Layout Randomization */
       /* FIXME: case 2491 for stacks/heaps/PEBs/TEBs, sharing */
      OPTION_DEFAULT(uint, aslr, 0 /* ASLR_DISABLED */, 
          "address space layout randomization, from aslr_option_t")
      OPTION_ALIAS(R, aslr, 0 /* ASLR_DISABLED */, STATIC, OP_PCACHE_NOP)
  
      OPTION_DEFAULT(uint, aslr_action, 0x111,
          /* case 7017 0x111 = ASLR_REPORT | ASLR_DETECT_EXECUTE | ASLR_TRACK_AREAS */
          "address space layout handling and reporting, from aslr_action_t")
  
      OPTION_DEFAULT(uint, aslr_retry, 2,
          /* case 6739 - allow private ASLR to search for a good fit,
           * 1  would allow linear range choice to leapfrog other DLLs
           * 2+ would also have a chance to deal with unlikely races
           */
          "private ASLR attempts for a good fit after failure, 0 fallback to native")
           
      OPTION_DEFAULT(uint, aslr_cache, 0, /* ASLR_DISABLED */
          "address space layout process shared and persistent cache, from aslr_cache_t")
  #endif
      /* min_free_disk applies to both ASLR and persisted caches */
      OPTION_DEFAULT(uint_size, min_free_disk, 50*(1024*1024), /* 50MB */
          "minimum free disk space (or quota) on DLL cache volume")
          /* case 8494 cache capacity management for ASLR and pcaches
           * Note default size is in Kilobytes, so it's best to always add M qualifier.
           * Examples: 1m, 10M
           */
  #ifdef WINDOWS
      OPTION_DEFAULT_INTERNAL(uint, aslr_internal, 0 /* ASLR_INTERNAL_DEFAULT */, 
          "address space layout randomization, internal flags from aslr_internal_option_t")
  
       /* FIXME: we need to find a good location to allow growth for other allocations */
      OPTION_DEFAULT(uint_addr, aslr_dll_base, 0x40000000, "starting DLL base addresses")
  
       /* limit for ASLR_RANGE_BOTTOM_UP, or starting point for ASLR_RANGE_TOP_DOWN */
       /* FIXME: case 6739 - what to do when reaching top, 
        *
        * FIXME: how is STATUS_ILLEGAL_DLL_RELOCATION determined, we
        * have to know stay out of the way since loader fails app if it
        * finds that user32.dll is not where it wanted?
        */
      OPTION_DEFAULT(uint_addr, aslr_dll_top,  0x77000000, "top of DLL range")
  
       /* FIXME: the lower 16 bits are ignored (Windows/x86
        * AllocationGranularity is 64KB).  This here gives us 12bits of
        * randomness.  Could make it larger if necessary. */
      OPTION_DEFAULT(uint_addr, aslr_dll_offset,  0x10000000, "maximum random jitter for first DLL")
  
       /* FIXME: too little (4 bits) randomness between DLLs, vs too much fragmentation */
      OPTION_DEFAULT(uint_addr, aslr_dll_pad, 0x00100000, "maximum random jitter between DLLs")
  
       /* case 6287 - first thread's stack can be controlled only by parent */
       /* ASLR_STACK activates, though affect real heap reservations as well */
       /* FIXME: the lower 16 bits are ignored (Windows/x86
        * AllocationGranularity is 64KB).  FIXME: This here gives us 8 bits of
        * randomness.  Could make it larger if necessary. */
      OPTION_DEFAULT(uint_addr, aslr_parent_offset,              0x01000000, 
          "maximum random jitter for parent reservation")
       /* ASLR_HEAP activates, though affect real stack reservations as
        * well This here gives us 12 bits of randomness.  Could make it
        * larger if necessary.
        */
      OPTION_DEFAULT(uint_addr, aslr_heap_reserve_offset,        0x10000000,
          "random jitter for first child reservation (large)")
      OPTION_DEFAULT(uint_addr, aslr_heap_exe_reserve_offset,    0x01000000,
          /* if executable ImageBaseAddress is in the middle of virtual address space */
          "random jitter for reservation after executable (smaller)")
  
       /* ASLR_HEAP_FILL activates */
       /* FIXME: too little (4 bits) randomness between heap reservations, 
        * vs too much fragmentation */
      OPTION_DEFAULT(uint_addr, aslr_reserve_pad,                0x00100000, 
          "random jitter between reservations (tiny)")
  
      /* FIXME: plan for 4.3 only after aslr_safe_save is checked in
       * ASLR_PERSISTENT_SOURCE_DIGEST | ASLR_PERSISTENT_SHORT_DIGESTS */
      OPTION_DEFAULT(uint, aslr_validation, 0x1, /* ASLR_PERSISTENT_PARANOID */
          "consistency and security validation level of stringency")
  
      OPTION_DEFAULT(uint_size, aslr_short_digest, (16*1024),
          "size of file header and footer to check, in KB or MB")
          /* used for checksum comparison of file header and footer,
           * note that if this value is changed previously persisted
           * files will not be accepted.  
           * 0 turns into a full file digest
           */
          /* default size is in Kilobytes, Examples: 1024, 1024k, 1m */
  
      OPTION_DEFAULT(uint_size, aslr_section_prefix, (16*1024),
          "size of section prefix to match, in KB or MB")
          /* used for byte comparison of a prefix of each file section,
           * if enabled by ASLR_PERSISTENT_PARANOID_PREFIX.
           * 0 disables section validation
           */
          /* default size is in Kilobytes, Examples: 1024, 1024k, 1m */
  
      OPTION_DEFAULT(liststring_t, exempt_aslr_default_list, 
          /* user32.dll - case 6620 on STATUS_ILLEGAL_DLL_RELOCATION. Not
           *              clear whether loader is just whining, or there
           *              is a good reason it shouldn't be rebased.  
           *       FIXME: without early injection affects only RU=5 processes that load it late,
           *              SHOWSTOPPER on XP.
           *       FIXME: Hopefully shouldn't be necessary for all KnownDlls, investigate full list.
           * ole32.dll - case 7746 on Win2000 and case 7743 
           *      on NT complaining about STATUS_ILLEGAL_DLL_RELOCATION
           * sfc.dll - case 8705 
           *      update.exe targeting directly 
           *      sfc.dll!MySfcTerminateWatcherThread in winlogon.exe
           * kbdus.dll,kbdbg.dll - case 6671 FIXME: list not complete, 
           *              FIXME: case 6740: we don't actually support kbd*.dll
           * kernel32.dll - with early injection this one also complains of being
           *                rebased.
           */
          OPTION_STRING("kernel32.dll;user32.dll;ole32.dll;sfc.dll;kbdus.dll;kbdbu.dll;kbd*.dll"), 
          "exempt from randomization these ;-separated modules")
      OPTION_DEFAULT(liststring_t, exempt_aslr_list,
          /* Note that allows '*' as a stress option */
          EMPTY_STRING, "exempt from randomization these ;-separated modules, append")
  
  
      /* case 7794 - when using private ASLR these large DLLs have a higher
       * impact on visible memory, and in stress testing on performance.
       * not really recommended but available until we enable sharing
       */
      OPTION_DEFAULT(bool, aslr_extra, false, "ASLR DLL exempt longer list")
      OPTION_DEFAULT(liststring_t, exempt_aslr_extra_list,
          /* see case 7794 exempt from both private and shared */
          /* note that these names are matched to PE name for private,
           * but to file names for ASLR cache */
          OPTION_STRING("mshtml.dll;msi.dll;mso.dll;shell32.dll"), 
          "exempt from randomization these ;-separated modules")
  
      /* case 9495 - include or exclude list for DLLs to share and
       * persist. Note that one cannot use simultaneously an include and
       * exclude list, so to remove an entry from either need to provide the 
       * whole list as '#advapi32.dll'
       */
      OPTION_DEFAULT(uint, aslr_cache_list, 1, /* ASLR_CACHE_LIST_INCLUDE */
          "controls DLLs to be shared via aslr_cache {all,include,exclude}")
          /* (note aslr_cache_list_t values match meaning in process_control) */
      /* exemptions are based on file names, not PE names */
      OPTION_DEFAULT(liststring_t, aslr_cache_include_list,
          /* enabled via -aslr_cache_list 1 (ASLR_CACHE_LIST_INCLUDE) (default) */
          /* All other DLLs are left for private ASLR if not exempt by
           * exempt_aslr_extra_list. */
          /* Need a slightly longer list to be worth enabling */
          /* Note we're bound by MAX_LIST_OPTION_LENGTH so check total
           * length before adding, and leave some room for DLLs that we
           * may want to add in the field.
           */
          /* Note DLLs that have no or very few relocation pages shouldn't be added */
          OPTION_STRING(
          "advapi32.dll;"
          /* FIXME: browseui.dll; also has high wset in IE after empty.exe */
          "comctl32.dll;"         /* note two different SxS versions */
          "gdi32.dll;"
          "jscript.dll;"          /* IE */
          "msctf.dll;"
          "mshtml.dll;"           /* shared by IE and Explorer */
          /* FIXME: mso.dll is the top DLL in Office apps, yet has startup effects */
          "msvcrt.dll;"
          "riched20.dll;"         /* different versions of in Office11\ and system32\ */
          "rpcrt4.dll;"
          "sapi.dll;"             /* only Speech\ for Office apps */
          "setupapi.dll;"
          "shell32.dll;"
          /* FIXME: shdocvw.dll; is a top DLL in Office and IE */
          /* shdoclc.dll companion DLL has resources for shdocvw.dll,
           * and has no relocations so it's fine to randomize privately
           * the resources, while not having to validate them if in
           * shared ASLR cache
           */
          "sptip.dll;"            /* only Speech\ related */
          "sxs.dll;"              /* XP, in all processes, provides Side x Side  */
          "uxtheme.dll;"           /* FIXME: XP, not very high WSet after startup */
          "ws2_32.dll"            /* case 9627 make sure any ASLR at all */
          ),
          "use shared cache only for these ;-separated modules")
      /* exemptions are based on file names, not PE names */
      OPTION_DEFAULT(liststring_t, aslr_cache_exclude_list,
          /* enabled via -aslr_cache_list 2 (ASLR_CACHE_LIST_EXCLUDE) */
          /* exempt from shared ASLR but still apply private ASLR */
          OPTION_STRING("mso.dll;xpsp2res.dll"),
          "exclude from shared cache these ;-separated modules")
      OPTION_DEFAULT(bool, aslr_safe_save, true, 
          /* see case 9696 */
          "ASLR DLL safe file creation in temporary file before rename")
  
      /* Syntactic sugar for memory savings at the cost of security controlled from core */
      OPTION_COMMAND(bool, medium, false, "medium", {
             if (options->medium) {
                 options->aslr_extra = true;
                 options->thin_client = false;   /* Case 9037. */
             }
          }, "medium security/memory mapping",
          STATIC, OP_PCACHE_NOP)
  
      OPTION_COMMAND(bool, low, false, "low", {
             if (options->low) {
                  IF_HOTP(options->hot_patching = true);
                  IF_HOTP(options->hotp_only = true;)
                  IF_HOTP(options->liveshields = true;)
                  IF_HOTP(options->hotp_diagnostics = true;)
                  IF_HOTP(if (options->hotp_only == true) {
                     /* coordinate with hotp_only any additional option changes */
                     IF_RETURN_AFTER_CALL(options->ret_after_call = false;)
                     IF_RCT_IND_BRANCH(options->rct_ind_call = OPTION_DISABLED;)
                     IF_RCT_IND_BRANCH(options->rct_ind_jump = OPTION_DISABLED;)
                  });
                  /* Matching old behavior */
                  IF_WINDOWS(options->apc_policy =
                             OPTION_ENABLED|OPTION_BLOCK|OPTION_REPORT|OPTION_CUSTOM;)
  
                  options->vm_size   = 32*1024*1024; /* 32MB */
                  IF_GBOP(options->gbop = 0x6037;) /* GBOP_CLIENT_DEFAULT */
                  options->aslr      = 0x0; /* ASLR_DISABLED */
                  /* Reset has no meaning for hotp_only; see case 8389. */
                  DISABLE_RESET(options);
                  IF_KSTATS(options->kstats = false); /* Cases 6837 & 8869. */
                  options->thin_client = false;   /* Case 9037. */
             }
          }, "low security/memory mapping",
          STATIC, OP_PCACHE_NOP)
  
      OPTION_COMMAND(bool, client, false, "client", {
             if (options->client) {
                  IF_HOTP(options->hot_patching = true);
                  IF_HOTP(options->hotp_only = true;)
                  IF_HOTP(options->liveshields = true;)
                  IF_HOTP(options->hotp_diagnostics = true;)
                  IF_HOTP(if (options->hotp_only == true) {
                     /* coordinate with hotp_only any additional option changes */
                     IF_RETURN_AFTER_CALL(options->ret_after_call = false;)
                     IF_RCT_IND_BRANCH(options->rct_ind_call = OPTION_DISABLED;)
                     IF_RCT_IND_BRANCH(options->rct_ind_jump = OPTION_DISABLED;)
                  });
                  /* Matching old behavior */
                  IF_WINDOWS(options->apc_policy =
                             OPTION_ENABLED|OPTION_BLOCK|OPTION_REPORT|OPTION_CUSTOM;)
  
                  options->vm_size   = 32*1024*1024; /* 32MB */
                  IF_GBOP(options->gbop = 0x6037;) /* GBOP_CLIENT_DEFAULT */
                  /* making sure -client -low  == -low -client*/
                  if (options->low) {
                      options->aslr      = 0x0; /* ASLR_DISABLED */
                      options->aslr_cache= 0x0; /* ASLR_DISABLED */
                  } else {
                      options->aslr      = 0x7; /* ASLR_CLIENT_DEFAULT */
                      options->aslr_cache= 0x192; /* ASLR_CACHE_DEFAULT */
                  }
  
                  /* case 2491 ASLR_SHARED_CONTENTS | 
                   * ASLR_SHARED_ANONYMOUS_CONSUMER | ASLR_SHARED_FILE_PRODUCER,
                   */
  
                  /* Reset has no meaning for hotp_only; see case 8389. */
                  DISABLE_RESET(options);
                  IF_KSTATS(options->kstats = false); /* Cases 6837 & 8869. */
                  options->thin_client = false;   /* Case 9037. */
             } else {
                 /* 
                  * case 8283 -no_client.  Note that this will work well
                  * only for simple sequences of -client -no_client, as
                  * we do not attempt to actually recover and is very
                  * very likely we'll forget to keep this in synch
                  */
                  IF_HOTP(options->hotp_only = false;)
                  /* coordinate with hotp_only any additional option changes */
                  IF_RETURN_AFTER_CALL(options->ret_after_call = 
                                       DEFAULT_OPTION_VALUE(ret_after_call);)
                  IF_RCT_IND_BRANCH(options->rct_ind_call = 
                                    DEFAULT_OPTION_VALUE(rct_ind_call);)
                  IF_RCT_IND_BRANCH(options->rct_ind_jump = 
                                    DEFAULT_OPTION_VALUE(rct_ind_jump);)
                  options->vm_size = DEFAULT_OPTION_VALUE(vm_size);
                  IF_GBOP(options->gbop = DEFAULT_OPTION_VALUE(gbop);)
                  options->aslr = DEFAULT_OPTION_VALUE(aslr);
                  options->aslr_cache = DEFAULT_OPTION_VALUE(aslr_cache);
  
                  REENABLE_RESET(options);
                  IF_KSTATS(options->kstats = true);
             }
          }, "client process protection",
          STATIC, OP_PCACHE_NOP)
  
  # ifdef GBOP
      /* Generically Bypassable Overflow Protection in user mode */
      OPTION_DEFAULT(uint, gbop, 0 /* GBOP_DISABLED */,
          "GBOP control, from GBOP_OPTION")
      OPTION_ALIAS(O, gbop, 0 /* GBOP_DISABLED */, STATIC, OP_PCACHE_NOP)
      DYNAMIC_OPTION_DEFAULT(uint, gbop_frames, 0, 
          "GBOP stack backtrace frame depth") /* >0 NYI */
  
      OPTION_DEFAULT(uint, gbop_include_set, 
           0x1 /* GBOP_SET_NTDLL_BASE */
          |0x2 /* KERNEL32 BASE */
          |0x4 /* MSVCRT BASE */
          |0x8 /* WS2_32 BASE */
          |0x10/* WININET BASE */
          |0x20/* USER32 BASE */
          |0x40/* SHELL32 BASE */
          /* FIXME: case 8006 should enable MORE NTDLL KERNEL32 MSVCRT WS2_32 in a later round */
          , "GBOP policy group control, 0 means all")
       /* bit positions are as defined in GBOP_ALL_HOOKS */
  
      OPTION_DEFAULT(uint, gbop_last_hook, 0 /* automatically determine number of hooks */,
          /* note this should be internal, but currently provides good
           * control over the performance impact of having extra GBOP hooks
           */
          "GBOP number of hooks length, crude override")
  
      /* FIXME: may want to duplicate the above options for the extra
       * hooks, that may have different flags and different frame depth
       */
      OPTION_DEFAULT(liststring_t, gbop_include_list,
          /* NYI: case 7127 list of additional hook points module!func */
          /* FIXME: should allow module!* for stress testing */
          EMPTY_STRING, "include for GBOP these ;-separated module!func descriptors, append")
      OPTION_DEFAULT(liststring_t, gbop_exclude_list,
          /* case 7127 list of GBOP hook points to turn the mode off (disable hook) for */
          /* e.g. 'KERNEL32.dll!FreeLibrary;WININET.dll!*',
           * Note the only wildcards supported are module.dll!*,
           * or '*' as a stress test option to exclude all hooks.
           */
          EMPTY_STRING, "disable GBOP hook for these ;-separated module!func descriptors, append")
      OPTION_DEFAULT(liststring_t, exempt_gbop_from_default_list, 
          EMPTY_STRING, "allow GBOP violations from these ;-separated modules")
      OPTION_DEFAULT(liststring_t, exempt_gbop_from_list, 
          EMPTY_STRING, "allow GBOP violations from these ;-separated modules, append")
  
     /* FIXME: case 7127 - can make all gbop options dynamic, though
      * extra hook injection will need a more explicit nudge-like
      * mechanism
      */
  # endif /* GBOP */
      /* FIXME: temporary fix for case 9467 - option to disable if not needed */
      OPTION_DEFAULT(bool, mute_nudge, true, "mute nudges for thin_clients")
  #endif /* WINDOWS */
       
      /* Pseudo Random Number Generator seed affects all random number users:
       * (currently vm_max_offset, aslr_dll_offset, aslr_dll_pad) */
      OPTION_DEFAULT(uint, prng_seed, 0 /* get a good seed from the OS */,
          "if non-0 allows reproducible pseudo random number generator sequences")
  
      /* FIXME PR 215179 on enabling pad_jmps in all builds */
  #if defined(PROFILE_LINKCOUNT) || defined(TRACE_HEAD_CACHE_INCR) || defined(CUSTOM_EXIT_STUBS)
      OPTION_DEFAULT(bool, pad_jmps, false, "nop pads jmps in the cache that we might need to patch so that the offset doesn't cross a L1 cache line boundary (necessary for atomic linking/unlinking on an mp machine)")
  #else 
      OPTION_DEFAULT(bool, pad_jmps, true, "nop pads jmps in the cache that we might need to patch so that the offset doesn't cross a L1 cache line boundary (necessary for atomic linking/unlinking on an mp machine)")
  #endif
      /* FIXME PR 215179 on getting rid of this tracing restriction. */
  #if defined(LINUX)
      OPTION_DEFAULT(bool, pad_jmps_mark_no_trace, true, "mark bbs that require added nops "
                     "for multiple hot patchable exits with CANNOT_BE_TRACE, since tracing "
                     "through fragments with inserted nops isn't well supported (see PR "
                     "215179 on fixing this)") 
  #else
      OPTION_DEFAULT(bool, pad_jmps_mark_no_trace, false, "mark bbs that require added nops "
                     "for multiple hot patchable exits with CANNOT_BE_TRACE, since tracing "
                     "through fragments with inserted nops isn't well supported (see PR "
                     "215179 on fixing this)") 
  #endif
      OPTION_DEFAULT_INTERNAL(bool, pad_jmps_return_excess_padding, true, "if -pad_jmps returns any excess requested memory to fcache")
      OPTION_DEFAULT_INTERNAL(bool, pad_jmps_shift_bb, true, 
          "if -pad_jmps shifts the start_pc for padding the first jmp of a bb instead of inserting a nop")
      OPTION_DEFAULT_INTERNAL(bool, pad_jmps_shift_trace, true,
          "if -pad_jmps shifts the start_pc for padding the first jmp of a trace instead of inserting a nop")
      OPTION_DEFAULT_INTERNAL(uint, pad_jmps_set_alignment, 0, "if non-zero sets the pad_jmps alignment (useful for stress testing -pad_jmps code)")
  
      OPTION_DEFAULT_INTERNAL(bool, ibl_sentinel_check, true, /* case 2174: FIXME: remove when working fine */
          "check for sentinel overwraps in IBL routine instead of exit")
  
      OPTION_DEFAULT(bool, ibl_addr_prefix, false, /* case 5231: FIXME: remove when working fine */
          "uses shorter but slower encode with addr16 prefix in IBL routine and elsewhere")
  
       /* Artificial Slowdown Options */
      OPTION_DEFAULT_INTERNAL(uint, slowdown_ibl_found, 0,
          "add a loop to slow down the IBL hit path")
  
       /* Stress Testing Options */
      OPTION_DEFAULT_INTERNAL(bool, stress_recreate_pc, false, 
          "stress test recreate pc after each trace or bb")
      OPTION_COMMAND_INTERNAL(bool, stress_recreate_state, false, "stress_recreate_state",
      { if (options->stress_recreate_state) 
          options->stress_recreate_pc = true;
      }, "stress test recreate state after each trace or bb", STATIC, OP_PCACHE_NOP)
      OPTION_DEFAULT_INTERNAL(bool, detect_dangling_fcache, false, 
          "detect any execution of a freed fragment")
      OPTION_DEFAULT_INTERNAL(bool, stress_detach_with_stacked_callbacks, false,
          "detach once a thread has 2 levels of nested callbacks (for internal testing)")
      OPTION_DEFAULT_INTERNAL(bool, detach_fix_sysenter_on_stack, true /* default true */,
          "if false then detach does not fix sysenter callbacks on the stack and instead "
          "uses the emitted dispatch code used for other system calls (a fairly minor "
          "transparency violation).  Used for internal testing.")
  
       /* for stress testing can use 1 */
      OPTION_DEFAULT_INTERNAL(uint, vmarea_initial_size, 100, 
          "initial vmarea vector size")
      /* FIXME: case 4471 should start smaller and double instead */
      OPTION_DEFAULT_INTERNAL(uint, vmarea_increment_size, 100, 
          "incremental vmarea vector size")
      OPTION_INTERNAL(uint_addr, stress_fake_userva, 
          "pretend system address space starts at this address (case 9022)")
  
      /* degenerate options: only used for run-once testing (case 3990) */
      OPTION_INTERNAL(bool, unsafe_crash_process, "unsafe: generates a DR exception")
      OPTION_INTERNAL(bool, unsafe_hang_process, "unsafe: hang the process")
  
      /* unsafe experimental options */
      OPTION_DEFAULT_INTERNAL(bool, unsafe_ignore_overflow, false,
          "do not preserve OF flag, unsafe")
      OPTION_COMMAND_INTERNAL(bool, unsafe_ignore_eflags, false, "unsafe_ignore_eflags", {
          if (options->unsafe_ignore_eflags) { /* else leave alone */
              options->unsafe_ignore_eflags_trace = options->unsafe_ignore_eflags;
              options->unsafe_ignore_eflags_prefix = options->unsafe_ignore_eflags;
              options->unsafe_ignore_eflags_ibl = options->unsafe_ignore_eflags;
              /* this also covers NATIVE_RETURN which doesn't have a separate option */
          }
       }, "do not preserve EFLAGS on any part of ind br handling, unsafe", STATIC,
      OP_PCACHE_NOP)
  
      OPTION_DEFAULT_INTERNAL(bool, unsafe_ignore_eflags_trace, false,
          "do not preserve EFLAGS on in-trace cmp, unsafe")
      OPTION_DEFAULT_INTERNAL(bool, unsafe_ignore_eflags_prefix, false,
          "do not preserve EFLAGS on prefixes, unsafe")
      OPTION_DEFAULT_INTERNAL(bool, unsafe_ignore_eflags_ibl, false,
          "do not preserve EFLAGS in ibl proper, unsafe")
  
      OPTION_DEFAULT(liststring_t, ignore_assert_list, 
          EMPTY_STRING, "convert into warnings these ;-separated assert identifiers")
       /* Should be an exact match of message after Internal Error.
        * Most common ones look like 'x86/arch.c:142', but could also
        * look like 'Not implemented @x86/arch.c:142' or 
        * 'Bug #4809 @x86/arch.c:145;Ignore message @x86/arch.c:146'
        */
  
      /* needed primarily for CLIENT_INTERFACE but technically all configurations
       * can have racy crashes at exit time (xref PR 470957)
       */
      OPTION(bool, synch_at_exit,
          "synchronize with all threads at exit in release build")
  
  #ifdef EXPOSE_INTERNAL_OPTIONS
      OPTION_NAME(bool, optimize, " synthethic", "set if ANY opts are on")
  
  #define OPTIMIZE_OPTION(type, name) OPTION_COMMAND(type, name, 0, #name, {      \
      options->optimize = true;                                             \
  }, "optimization", STATIC, OP_PCACHE_NOP)
  
  # ifdef SIDELINE
      OPTION(bool, sideline, "use sideline thread for optimization")
  # endif
      /* optimizations */
  
  # if 0 /* this flag does nothing yet...disable so people don't try to use it */
      OPTION(uint, aggressiveness, "level of aggressiveness in optimizations")
  # endif
  
  # ifdef IA32_ON_IA64
      OPTIMIZE_OPTION(bool, test_ia64)
  # endif
      OPTIMIZE_OPTION(bool, prefetch)
      OPTIMIZE_OPTION(bool, rlr)
      OPTIMIZE_OPTION(bool, vectorize)
      OPTIMIZE_OPTION(bool, unroll_loops)
  
      OPTIMIZE_OPTION(bool, instr_counts)
      OPTIMIZE_OPTION(bool, stack_adjust)
  # ifdef LOAD_TO_CONST
      OPTIMIZE_OPTION(bool, loads_to_const)
      OPTIMIZE_OPTION(bool, safe_loads_to_const)
  # endif
  
      OPTIMIZE_OPTION(uint, remove_dead_code)             /* aggressiveness level */
      OPTIMIZE_OPTION(uint, constant_prop)                /* aggressiveness level */
          /* 2 digits, first controls local aggressiveness second global */
          /* aggressiveness, i.e. 14 is local aggressiveness 1 and global */
          /* aggressiveness 4, possible values are 0, 1, 2 for global and */
          /* 0, 1, 2, 3 for local, larger numbers = more aggressive at the */
          /* possible (but hopefully unlikely) expense of correctness    */
  
      OPTIMIZE_OPTION(bool, call_return_matching)
      OPTIMIZE_OPTION(bool, remove_unnecessary_zeroing) // FIXME: unnecessarily long option
      OPTIMIZE_OPTION(bool, peephole)
  # undef OPTIMIZE_OPTION
  #endif /* EXPOSE_INTERNAL_OPTIONS */
  #ifdef HOT_PATCHING_INTERFACE
      OPTION_DEFAULT(bool, hot_patching, false, "enable hot patching")
  
      /* This is used to create forensics files when a hot patch event is
       * logged.  There can be numerous hotpatch events and dumping a
       * forensics file for each one by default would result in too many,
       * hence the need for this option.  Note: hot patch exceptions and
       * internal errors are not hot patch requested events, so this option
       * won't be used to control forensics files for those.
       */
      DYNAMIC_OPTION_DEFAULT(bool, hotp_diagnostics, false,
                             "produces forensics for hot patch events")
      /* There are many technical challenges to switching dynamically between
       * full core control mode and hotp_only mode.  So hotp_only is not DYNAMIC.
       * TODO: Revisit when starting on "attach" mode.
       * NOTE: hotp_only specifies the non-code cache mode, not liveshields; for
       *       liveshields must use the -liveshields option.
       */
      OPTION_COMMAND(bool, hotp_only, false, "hotp_only", {
          if (options->hotp_only) {
              IF_RETURN_AFTER_CALL(options->ret_after_call = false;)
              IF_RCT_IND_BRANCH(options->rct_ind_call = OPTION_DISABLED;)
              IF_RCT_IND_BRANCH(options->rct_ind_jump = OPTION_DISABLED;)
  
              /* no kstats for -hotp_only; case 6837 */
              IF_KSTATS(options->kstats = false);
  
              /* reset has no meaning for hotp_only; see case 8389 */
              DISABLE_RESET(options);
  
              /* -low and -client set their sizes afterward so no conflict */
              options->vm_size   = 32*1024*1024; /* 32MB */
  
              options->thin_client = false;   /* Case 9037. */
              options->native_exec = false;
  
              /* FIXME: add other options we should turn off */
              /* FIXME: coordinate with -client any other option changes _required_ 
               * for -hotp_only */
          }
      }, "enable hot patching only mode, i.e., no code cache", STATIC, OP_PCACHE_NOP)
      /* NOTE: as of today probe_api and liveshields are mutually exclusive, i.e,
       * ls-defs and probes can't be specified by one or more clients.  The
       * ultimate goal is to abstract out the probe api and convert LiveShields
       * into a client using probe api, at which point -probe_api will be the
       * same as -hot_patching.  The same applies to gbop too, i.e., excluded
       * when probe_api is turned on; gbop & livshields can co-exist as before.
       */
      OPTION_COMMAND(bool, liveshields, false, "liveshields", { 
          if (options->liveshields) {
              options->hot_patching = true;
              options->hotp_diagnostics = true;
              IF_CLIENT_INTERFACE(options->probe_api = false;)
          }
      }, "enables LiveShields", STATIC, OP_PCACHE_NOP)
  #endif /* HOT_PATCHING_INTERFACE */
  #ifdef PROCESS_CONTROL      /* case 8594 */
      /* Dynamic because it can be turned on or off using a nudge. */
      DYNAMIC_OPTION_DEFAULT(uint, process_control, 0,
          "sets process control mode {off,whitelist,blacklist} thereby "
          "deciding if a process is allowed to execute or not")
      /* FIXME: remove this after md5s are obtained from a mapped file; case 9252.*/
      DYNAMIC_OPTION_DEFAULT(uint, pc_num_hashes, 100,
          "sets the number of hashes a process control hashlist can contain")
  
      /* detect_mode for process_control; see case 10610.  Only reason to have it
       * separate is that it is distinctly different than other core features,
       * and is exposed in UI as orthogonal to other VPS features.
       *
       * FIXME: having a separate detect_mode option for each
       * security mechanism won't scale even if each used the OPTION_* flags
       * internally; should make the actual security mechanism parameterized to
       * take in OPTION_* flags (which can't be done today because OPTION_* flags
       * assume only on or off state and things like process control, gbop, aslr
       * have more than one state, in some cases, they have their own set of
       * operational flags) or parameterize individual actions like
       * detect_mode, dumpcore, remediation action, forensics file, etc.  */
      DYNAMIC_OPTION_DEFAULT(bool, pc_detect_mode, false,
          "provides detect_mode for process control independent of -detect_mode")
  
      /* Case 11023: don't produce forensices by default; needless load for EV. */
      DYNAMIC_OPTION_DEFAULT(bool, pc_diagnostics, false,
          "provides forensics for process control independent of -diagnostics")
  #endif
  
      /* thin_client mode is just a light weight mode in which the core
       * executes where there is no code cache, hotp_only, gbop or aslr.
       * It hooks one or two system calls, enough to follow into child 
       * processes.  Though it is intended to be used for process_control
       * today, it has value independent of process_control.  One example
       * is to inflate/switch the core to hotp_only, gbop or aslr on the 
       * fly for any unprotected process, which I think would be very handy.
       * Case 8576.
       */
      OPTION_COMMAND(bool, thin_client, false, "thin_client", {
          if (options->thin_client) {
              /* Will be running native mostly, so need native_exec_syscalls 
               * to hook syscalls to follow children.
               */
              options->native_exec_syscalls = true;
  
              /* thin_client is just that, thin; so no hot patching, gbopping 
               * or aslring here.
               */
              IF_HOTP(options->hot_patching = false;)
              IF_HOTP(options->hotp_only = false;)
              IF_GBOP(options->gbop = 0;)
              IF_WINDOWS(options->aslr = 0;)
  
              /* similarly, client/low/medium modes are incompatible with 
               * thin_client; though check_options_compatibility() enforces this,
               * this is a special case as the user may legitimately set both
               * -client and -thin_client.  Mostly for debugging; case 9037. */
              IF_WINDOWS(options->client = false;)
              IF_WINDOWS(options->low = false;)
              IF_WINDOWS(options->medium = false;)
  
              /* thin_client mode is intended to have a low foot print;
               * reserving the default 128 mb takes 256 kb of page table
               * space (case 8491), so reserve just 4 mb, in case we inflate
               * to hotp_only mode.
               */
              options->vm_size = 4*1024*1024;
  
              /* Don't randomize the core heap; cygwin app's stack & heaps 
               * will move, causing them to crash.  Also memory 
               * contiguity expected by .NET apps would be broken.  The
               * problem is when we inflate we still won't be randomized!
               */
              options->vm_base = 0;
              options->vm_max_offset = 0;
  
              /* Reset has no meaning for thin_client; see case 8389. */
              DISABLE_RESET(options);
  
              /* No kstats for -thin_client - same issue as case 6837. */
              IF_KSTATS(options->kstats = false);     /* See case 8869 also. */
          }
      }, "run dr in a light weight mode with nothing but a few hooks", STATIC,
      OP_PCACHE_NOP)
  
  #ifdef LINUX_KERNEL
      OPTION_DEFAULT(bool, optimize_sys_call_ret, true,
                     "optimize syscall and sysret to avoid dispatch")
  #endif
  
  #undef OPTION
  #undef OPTION_NAME
  #undef OPTION_DEFAULT
  
  #undef DYNAMIC_OPTION
  #undef DYNAMIC_OPTION_DEFAULT
  