Home | History | Annotate | Download | only in coregrind
      1 
      2 /*--------------------------------------------------------------------*/
      3 /*--- Startup: the real stuff                             m_main.c ---*/
      4 /*--------------------------------------------------------------------*/
      5 
      6 /*
      7    This file is part of Valgrind, a dynamic binary instrumentation
      8    framework.
      9 
     10    Copyright (C) 2000-2015 Julian Seward
     11       jseward (at) acm.org
     12 
     13    This program is free software; you can redistribute it and/or
     14    modify it under the terms of the GNU General Public License as
     15    published by the Free Software Foundation; either version 2 of the
     16    License, or (at your option) any later version.
     17 
     18    This program is distributed in the hope that it will be useful, but
     19    WITHOUT ANY WARRANTY; without even the implied warranty of
     20    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     21    General Public License for more details.
     22 
     23    You should have received a copy of the GNU General Public License
     24    along with this program; if not, write to the Free Software
     25    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
     26    02111-1307, USA.
     27 
     28    The GNU General Public License is contained in the file COPYING.
     29 */
     30 
     31 #include "pub_core_basics.h"
     32 #include "pub_core_vki.h"
     33 #include "pub_core_vkiscnums.h"
     34 #include "pub_core_threadstate.h"
     35 #include "pub_core_xarray.h"
     36 #include "pub_core_clientstate.h"
     37 #include "pub_core_aspacemgr.h"
     38 #include "pub_core_aspacehl.h"
     39 #include "pub_core_commandline.h"
     40 #include "pub_core_debuglog.h"
     41 #include "pub_core_errormgr.h"
     42 #include "pub_core_execontext.h"
     43 #include "pub_core_gdbserver.h"
     44 #include "pub_core_initimg.h"
     45 #include "pub_core_libcbase.h"
     46 #include "pub_core_libcassert.h"
     47 #include "pub_core_libcfile.h"
     48 #include "pub_core_libcprint.h"
     49 #include "pub_core_libcproc.h"
     50 #include "pub_core_libcsignal.h"
     51 #include "pub_core_sbprofile.h"
     52 #include "pub_core_syscall.h"       // VG_(strerror)
     53 #include "pub_core_mach.h"
     54 #include "pub_core_machine.h"
     55 #include "pub_core_mallocfree.h"
     56 #include "pub_core_options.h"
     57 #include "pub_core_debuginfo.h"
     58 #include "pub_core_redir.h"
     59 #include "pub_core_scheduler.h"
     60 #include "pub_core_seqmatch.h"      // For VG_(string_match)
     61 #include "pub_core_signals.h"
     62 #include "pub_core_stacks.h"        // For VG_(register_stack)
     63 #include "pub_core_syswrap.h"
     64 #include "pub_core_tooliface.h"
     65 #include "pub_core_translate.h"     // For VG_(translate)
     66 #include "pub_core_trampoline.h"
     67 #include "pub_core_transtab.h"
     68 #include "pub_core_inner.h"
     69 #if defined(ENABLE_INNER_CLIENT_REQUEST)
     70 #include "pub_core_clreq.h"
     71 #endif
     72 
     73 
     74 /*====================================================================*/
     75 /*=== Command-line: variables, processing, etc                     ===*/
     76 /*====================================================================*/
     77 
     78 // See pub_{core,tool}_options.h for explanations of all these.
     79 
     80 static void usage_NORETURN ( Bool debug_help )
     81 {
     82    /* 'usage1' contains a %s
     83       - for the name of the GDB executable
     84       - for the name of vgdb's path prefix
     85       which must be supplied when they are VG_(printf)'d. */
     86    const HChar usage1[] =
     87 "usage: valgrind [options] prog-and-args\n"
     88 "\n"
     89 "  tool-selection option, with default in [ ]:\n"
     90 "    --tool=<name>             use the Valgrind tool named <name> [memcheck]\n"
     91 "\n"
     92 "  basic user options for all Valgrind tools, with defaults in [ ]:\n"
     93 "    -h --help                 show this message\n"
     94 "    --help-debug              show this message, plus debugging options\n"
     95 "    --version                 show version\n"
     96 "    -q --quiet                run silently; only print error msgs\n"
     97 "    -v --verbose              be more verbose -- show misc extra info\n"
     98 "    --trace-children=no|yes   Valgrind-ise child processes (follow execve)? [no]\n"
     99 "    --trace-children-skip=patt1,patt2,...    specifies a list of executables\n"
    100 "                              that --trace-children=yes should not trace into\n"
    101 "    --trace-children-skip-by-arg=patt1,patt2,...   same as --trace-children-skip=\n"
    102 "                              but check the argv[] entries for children, rather\n"
    103 "                              than the exe name, to make a follow/no-follow decision\n"
    104 "    --child-silent-after-fork=no|yes omit child output between fork & exec? [no]\n"
    105 "    --vgdb=no|yes|full        activate gdbserver? [yes]\n"
    106 "                              full is slower but provides precise watchpoint/step\n"
    107 "    --vgdb-error=<number>     invoke gdbserver after <number> errors [%d]\n"
    108 "                              to get started quickly, use --vgdb-error=0\n"
    109 "                              and follow the on-screen directions\n"
    110 "    --vgdb-stop-at=event1,event2,... invoke gdbserver for given events [none]\n"
    111 "         where event is one of:\n"
    112 "           startup exit valgrindabexit all none\n"
    113 "    --track-fds=no|yes        track open file descriptors? [no]\n"
    114 "    --time-stamp=no|yes       add timestamps to log messages? [no]\n"
    115 "    --log-fd=<number>         log messages to file descriptor [2=stderr]\n"
    116 "    --log-file=<file>         log messages to <file>\n"
    117 "    --log-socket=ipaddr:port  log messages to socket ipaddr:port\n"
    118 "\n"
    119 "  user options for Valgrind tools that report errors:\n"
    120 "    --xml=yes                 emit error output in XML (some tools only)\n"
    121 "    --xml-fd=<number>         XML output to file descriptor\n"
    122 "    --xml-file=<file>         XML output to <file>\n"
    123 "    --xml-socket=ipaddr:port  XML output to socket ipaddr:port\n"
    124 "    --xml-user-comment=STR    copy STR verbatim into XML output\n"
    125 "    --demangle=no|yes         automatically demangle C++ names? [yes]\n"
    126 "    --num-callers=<number>    show <number> callers in stack traces [12]\n"
    127 "    --error-limit=no|yes      stop showing new errors if too many? [yes]\n"
    128 "    --error-exitcode=<number> exit code to return if errors found [0=disable]\n"
    129 "    --error-markers=<begin>,<end> add lines with begin/end markers before/after\n"
    130 "                              each error output in plain text mode [none]\n"
    131 "    --show-below-main=no|yes  continue stack traces below main() [no]\n"
    132 "    --default-suppressions=yes|no\n"
    133 "                              load default suppressions [yes]\n"
    134 "    --suppressions=<filename> suppress errors described in <filename>\n"
    135 "    --gen-suppressions=no|yes|all    print suppressions for errors? [no]\n"
    136 "    --input-fd=<number>       file descriptor for input [0=stdin]\n"
    137 "    --dsymutil=no|yes         run dsymutil on Mac OS X when helpful? [yes]\n"
    138 "    --max-stackframe=<number> assume stack switch for SP changes larger\n"
    139 "                              than <number> bytes [2000000]\n"
    140 "    --main-stacksize=<number> set size of main thread's stack (in bytes)\n"
    141 "                              [min(max(current 'ulimit' value,1MB),16MB)]\n"
    142 "\n"
    143 "  user options for Valgrind tools that replace malloc:\n"
    144 "    --alignment=<number>      set minimum alignment of heap allocations [%s]\n"
    145 "    --redzone-size=<number>   set minimum size of redzones added before/after\n"
    146 "                              heap blocks (in bytes). [%s]\n"
    147 "\n"
    148 "  uncommon user options for all Valgrind tools:\n"
    149 "    --fullpath-after=         (with nothing after the '=')\n"
    150 "                              show full source paths in call stacks\n"
    151 "    --fullpath-after=string   like --fullpath-after=, but only show the\n"
    152 "                              part of the path after 'string'.  Allows removal\n"
    153 "                              of path prefixes.  Use this flag multiple times\n"
    154 "                              to specify a set of prefixes to remove.\n"
    155 "    --extra-debuginfo-path=path    absolute path to search for additional\n"
    156 "                              debug symbols, in addition to existing default\n"
    157 "                              well known search paths.\n"
    158 "    --debuginfo-server=ipaddr:port    also query this server\n"
    159 "                              (valgrind-di-server) for debug symbols\n"
    160 "    --allow-mismatched-debuginfo=no|yes  [no]\n"
    161 "                              for the above two flags only, accept debuginfo\n"
    162 "                              objects that don't \"match\" the main object\n"
    163 "    --smc-check=none|stack|all|all-non-file [all-non-file]\n"
    164 "                              checks for self-modifying code: none, only for\n"
    165 "                              code found in stacks, for all code, or for all\n"
    166 "                              code except that from file-backed mappings\n"
    167 "    --read-inline-info=yes|no read debug info about inlined function calls\n"
    168 "                              and use it to do better stack traces.  [yes]\n"
    169 "                              on Linux/Android/Solaris for Memcheck/Helgrind/DRD\n"
    170 "                              only.  [no] for all other tools and platforms.\n"
    171 "    --read-var-info=yes|no    read debug info on stack and global variables\n"
    172 "                              and use it to print better error messages in\n"
    173 "                              tools that make use of it (Memcheck, Helgrind,\n"
    174 "                              DRD) [no]\n"
    175 "    --vgdb-poll=<number>      gdbserver poll max every <number> basic blocks [%d] \n"
    176 "    --vgdb-shadow-registers=no|yes   let gdb see the shadow registers [no]\n"
    177 "    --vgdb-prefix=<prefix>    prefix for vgdb FIFOs [%s]\n"
    178 "    --run-libc-freeres=no|yes free up glibc memory at exit on Linux? [yes]\n"
    179 "    --sim-hints=hint1,hint2,...  activate unusual sim behaviours [none] \n"
    180 "         where hint is one of:\n"
    181 "           lax-ioctls lax-doors fuse-compatible enable-outer\n"
    182 "           no-inner-prefix no-nptl-pthread-stackcache none\n"
    183 "    --fair-sched=no|yes|try   schedule threads fairly on multicore systems [no]\n"
    184 "    --kernel-variant=variant1,variant2,...\n"
    185 "         handle non-standard kernel variants [none]\n"
    186 "         where variant is one of:\n"
    187 "           bproc android-no-hw-tls\n"
    188 "           android-gpu-sgx5xx android-gpu-adreno3xx none\n"
    189 "    --merge-recursive-frames=<number>  merge frames between identical\n"
    190 "           program counters in max <number> frames) [0]\n"
    191 "    --num-transtab-sectors=<number> size of translated code cache [%d]\n"
    192 "           more sectors may increase performance, but use more memory.\n"
    193 "    --avg-transtab-entry-size=<number> avg size in bytes of a translated\n"
    194 "           basic block [0, meaning use tool provided default]\n"
    195 "    --aspace-minaddr=0xPP     avoid mapping memory below 0xPP [guessed]\n"
    196 "    --valgrind-stacksize=<number> size of valgrind (host) thread's stack\n"
    197 "                               (in bytes) ["
    198                                 VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)
    199                                                 "]\n"
    200 "    --show-emwarns=no|yes     show warnings about emulation limits? [no]\n"
    201 "    --require-text-symbol=:sonamepattern:symbolpattern    abort run if the\n"
    202 "                              stated shared object doesn't have the stated\n"
    203 "                              text symbol.  Patterns can contain ? and *.\n"
    204 "    --soname-synonyms=syn1=pattern1,syn2=pattern2,... synonym soname\n"
    205 "              specify patterns for function wrapping or replacement.\n"
    206 "              To use a non-libc malloc library that is\n"
    207 "                  in the main exe:  --soname-synonyms=somalloc=NONE\n"
    208 "                  in libxyzzy.so:   --soname-synonyms=somalloc=libxyzzy.so\n"
    209 "    --sigill-diagnostics=yes|no  warn about illegal instructions? [yes]\n"
    210 "    --unw-stack-scan-thresh=<number>   Enable stack-scan unwind if fewer\n"
    211 "                  than <number> good frames found  [0, meaning \"disabled\"]\n"
    212 "                  NOTE: stack scanning is only available on arm-linux.\n"
    213 "    --unw-stack-scan-frames=<number>   Max number of frames that can be\n"
    214 "                  recovered by stack scanning [5]\n"
    215 "    --resync-filter=no|yes|verbose [yes on MacOS, no on other OSes]\n"
    216 "              attempt to avoid expensive address-space-resync operations\n"
    217 "    --max-threads=<number>    maximum number of threads that valgrind can\n"
    218 "                              handle [%d]\n"
    219 "\n";
    220 
    221    const HChar usage2[] =
    222 "\n"
    223 "  debugging options for all Valgrind tools:\n"
    224 "    -d                        show verbose debugging output\n"
    225 "    --stats=no|yes            show tool and core statistics [no]\n"
    226 "    --sanity-level=<number>   level of sanity checking to do [1]\n"
    227 "    --trace-flags=<XXXXXXXX>   show generated code? (X = 0|1) [00000000]\n"
    228 "    --profile-flags=<XXXXXXXX> ditto, but for profiling (X = 0|1) [00000000]\n"
    229 "    --profile-interval=<number> show profile every <number> event checks\n"
    230 "                                [0, meaning only at the end of the run]\n"
    231 "    --trace-notbelow=<number> only show BBs above <number> [999999999]\n"
    232 "    --trace-notabove=<number> only show BBs below <number> [0]\n"
    233 "    --trace-syscalls=no|yes   show all system calls? [no]\n"
    234 "    --trace-signals=no|yes    show signal handling details? [no]\n"
    235 "    --trace-symtab=no|yes     show symbol table details? [no]\n"
    236 "    --trace-symtab-patt=<patt> limit debuginfo tracing to obj name <patt>\n"
    237 "    --trace-cfi=no|yes        show call-frame-info details? [no]\n"
    238 "    --debug-dump=syms         mimic /usr/bin/readelf --syms\n"
    239 "    --debug-dump=line         mimic /usr/bin/readelf --debug-dump=line\n"
    240 "    --debug-dump=frames       mimic /usr/bin/readelf --debug-dump=frames\n"
    241 "    --trace-redir=no|yes      show redirection details? [no]\n"
    242 "    --trace-sched=no|yes      show thread scheduler details? [no]\n"
    243 "    --profile-heap=no|yes     profile Valgrind's own space use\n"
    244 "    --core-redzone-size=<number>  set minimum size of redzones added before/after\n"
    245 "                              heap blocks allocated for Valgrind internal use (in bytes) [4]\n"
    246 "    --wait-for-gdb=yes|no     pause on startup to wait for gdb attach\n"
    247 "    --sym-offsets=yes|no      show syms in form 'name+offset' ? [no]\n"
    248 "    --command-line-only=no|yes  only use command line options [no]\n"
    249 "\n"
    250 "  Vex options for all Valgrind tools:\n"
    251 "    --vex-iropt-verbosity=<0..9>           [0]\n"
    252 "    --vex-iropt-level=<0..2>               [2]\n"
    253 "    --vex-iropt-unroll-thresh=<0..400>     [120]\n"
    254 "    --vex-guest-max-insns=<1..100>         [50]\n"
    255 "    --vex-guest-chase-thresh=<0..99>       [10]\n"
    256 "    --vex-guest-chase-cond=no|yes          [no]\n"
    257 "    Precise exception control.  Possible values for 'mode' are as follows\n"
    258 "      and specify the minimum set of registers guaranteed to be correct\n"
    259 "      immediately prior to memory access instructions:\n"
    260 "         sp-at-mem-access          stack pointer only\n"
    261 "         unwindregs-at-mem-access  registers needed for stack unwinding\n"
    262 "         allregs-at-mem-access     all registers\n"
    263 "         allregs-at-each-insn      all registers are always correct\n"
    264 "      Default value for all 3 following flags is [unwindregs-at-mem-access].\n"
    265 "      --vex-iropt-register-updates=mode   setting to use by default\n"
    266 "      --px-default=mode      synonym for --vex-iropt-register-updates\n"
    267 "      --px-file-backed=mode  optional setting for file-backed (non-JIT) code\n"
    268 "    Tracing and profile control:\n"
    269 "      --trace-flags and --profile-flags values (omit the middle space):\n"
    270 "         1000 0000   show conversion into IR\n"
    271 "         0100 0000   show after initial opt\n"
    272 "         0010 0000   show after instrumentation\n"
    273 "         0001 0000   show after second opt\n"
    274 "         0000 1000   show after tree building\n"
    275 "         0000 0100   show selecting insns\n"
    276 "         0000 0010   show after reg-alloc\n"
    277 "         0000 0001   show final assembly\n"
    278 "         0000 0000   show summary profile only\n"
    279 "        (Nb: you need --trace-notbelow and/or --trace-notabove\n"
    280 "             with --trace-flags for full details)\n"
    281 "\n"
    282 "  debugging options for Valgrind tools that report errors\n"
    283 "    --dump-error=<number>     show translation for basic block associated\n"
    284 "                              with <number>'th error context [0=show none]\n"
    285 "\n"
    286 "  debugging options for Valgrind tools that replace malloc:\n"
    287 "    --trace-malloc=no|yes     show client malloc details? [no]\n"
    288 "\n";
    289 
    290    const HChar usage3[] =
    291 "\n"
    292 "  Extra options read from ~/.valgrindrc, $VALGRIND_OPTS, ./.valgrindrc\n"
    293 "\n"
    294 "  %s is %s\n"
    295 "  Valgrind is Copyright (C) 2000-2015, and GNU GPL'd, by Julian Seward et al.\n"
    296 "  LibVEX is Copyright (C) 2004-2015, and GNU GPL'd, by OpenWorks LLP et al.\n"
    297 "\n"
    298 "  Bug reports, feedback, admiration, abuse, etc, to: %s.\n"
    299 "\n";
    300 
    301    HChar default_alignment[30];      // large enough
    302    HChar default_redzone_size[30];   // large enough
    303 
    304    // Ensure the message goes to stdout
    305    VG_(log_output_sink).fd = 1;
    306    VG_(log_output_sink).is_socket = False;
    307 
    308    if (VG_(needs).malloc_replacement) {
    309       VG_(sprintf)(default_alignment,    "%d",  VG_MIN_MALLOC_SZB);
    310       VG_(sprintf)(default_redzone_size, "%lu", VG_(tdict).tool_client_redzone_szB);
    311    } else {
    312       VG_(strcpy)(default_alignment,    "not used by this tool");
    313       VG_(strcpy)(default_redzone_size, "not used by this tool");
    314    }
    315    /* 'usage1' a type as described after each arg. */
    316    VG_(printf)(usage1,
    317                VG_(clo_vgdb_error)        /* int */,
    318                default_alignment          /* char* */,
    319                default_redzone_size       /* char* */,
    320                VG_(clo_vgdb_poll)         /* int */,
    321                VG_(vgdb_prefix_default)() /* char* */,
    322                N_SECTORS_DEFAULT          /* int */,
    323                MAX_THREADS_DEFAULT        /* int */
    324                );
    325    if (VG_(details).name) {
    326       VG_(printf)("  user options for %s:\n", VG_(details).name);
    327       if (VG_(needs).command_line_options)
    328 	 VG_TDICT_CALL(tool_print_usage);
    329       else
    330 	 VG_(printf)("    (none)\n");
    331    }
    332    if (debug_help) {
    333       VG_(printf)("%s", usage2);
    334 
    335       if (VG_(details).name) {
    336          VG_(printf)("  debugging options for %s:\n", VG_(details).name);
    337 
    338          if (VG_(needs).command_line_options)
    339             VG_TDICT_CALL(tool_print_debug_usage);
    340          else
    341             VG_(printf)("    (none)\n");
    342       }
    343    }
    344    VG_(printf)(usage3, VG_(details).name, VG_(details).copyright_author,
    345                VG_BUGS_TO);
    346    VG_(exit)(0);
    347 }
    348 
    349 
    350 /* Peer at previously set up VG_(args_for_valgrind) and do some
    351    minimal command line processing that must happen early on:
    352 
    353    - show the version string, if requested (-v)
    354    - extract any request for help (--help, -h, --help-debug)
    355    - get the toolname (--tool=)
    356    - set VG_(clo_max_stackframe) (--max-stackframe=)
    357    - set VG_(clo_main_stacksize) (--main-stacksize=)
    358    - set VG_(clo_sim_hints) (--sim-hints=)
    359    - set VG_(clo_max_threads) (--max-threads)
    360 
    361    That's all it does.  The main command line processing is done below
    362    by main_process_cmd_line_options.  Note that
    363    main_process_cmd_line_options has to handle but ignore the ones we
    364    have handled here.
    365 */
    366 static void early_process_cmd_line_options ( /*OUT*/Int* need_help,
    367                                              /*OUT*/const HChar** tool )
    368 {
    369    UInt   i;
    370    HChar* str;
    371 
    372    vg_assert( VG_(args_for_valgrind) );
    373 
    374    /* parse the options we have (only the options we care about now) */
    375    for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
    376 
    377       str = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
    378       vg_assert(str);
    379 
    380       // Nb: the version string goes to stdout.
    381       if VG_XACT_CLO(str, "--version", VG_(log_output_sink).fd, 1) {
    382          VG_(log_output_sink).is_socket = False;
    383          VG_(printf)("valgrind-" VERSION "\n");
    384          VG_(exit)(0);
    385       }
    386       else if VG_XACT_CLO(str, "--help", *need_help, *need_help+1) {}
    387       else if VG_XACT_CLO(str, "-h",     *need_help, *need_help+1) {}
    388 
    389       else if VG_XACT_CLO(str, "--help-debug", *need_help, *need_help+2) {}
    390 
    391       // The tool has already been determined, but we need to know the name
    392       // here.
    393       else if VG_STR_CLO(str, "--tool", *tool) {}
    394 
    395       // Set up VG_(clo_max_stackframe) and VG_(clo_main_stacksize).
    396       // These are needed by VG_(ii_create_image), which happens
    397       // before main_process_cmd_line_options().
    398       else if VG_INT_CLO(str, "--max-stackframe", VG_(clo_max_stackframe)) {}
    399       else if VG_INT_CLO(str, "--main-stacksize", VG_(clo_main_stacksize)) {}
    400 
    401       // Set up VG_(clo_max_threads); needed for VG_(tl_pre_clo_init)
    402       else if VG_INT_CLO(str, "--max-threads", VG_(clo_max_threads)) {}
    403 
    404       // Set up VG_(clo_sim_hints). This is needed a.o. for an inner
    405       // running in an outer, to have "no-inner-prefix" enabled
    406       // as early as possible.
    407       else if VG_USETX_CLO (str, "--sim-hints",
    408                             "lax-ioctls,lax-doors,fuse-compatible,"
    409                             "enable-outer,no-inner-prefix,"
    410                             "no-nptl-pthread-stackcache",
    411                             VG_(clo_sim_hints)) {}
    412    }
    413 
    414    /* For convenience */
    415    VG_N_THREADS = VG_(clo_max_threads);
    416 }
    417 
    418 /* The main processing for command line options.  See comments above
    419    on early_process_cmd_line_options.
    420 
    421    Comments on how the logging options are handled:
    422 
    423    User can specify:
    424       --log-fd=      for a fd to write to (default setting, fd = 2)
    425       --log-file=    for a file name to write to
    426       --log-socket=  for a socket to write to
    427 
    428    As a result of examining these and doing relevant socket/file
    429    opening, a final fd is established.  This is stored in
    430    VG_(log_output_sink) in m_libcprint.  Also, if --log-file=STR was
    431    specified, then STR, after expansion of %p and %q templates within
    432    it, is stored in VG_(clo_log_fname_expanded), in m_options, just in
    433    case anybody wants to know what it is.
    434 
    435    When printing, VG_(log_output_sink) is consulted to find the
    436    fd to send output to.
    437 
    438    Exactly analogous actions are undertaken for the XML output
    439    channel, with the one difference that the default fd is -1, meaning
    440    the channel is disabled by default.
    441 */
    442 static
    443 void main_process_cmd_line_options ( /*OUT*/Bool* logging_to_fd,
    444                                      /*OUT*/const HChar** xml_fname_unexpanded,
    445                                      const HChar* toolname )
    446 {
    447    // VG_(clo_log_fd) is used by all the messaging.  It starts as 2 (stderr)
    448    // and we cannot change it until we know what we are changing it to is
    449    // ok.  So we have tmp_log_fd to hold the tmp fd prior to that point.
    450    SysRes sres;
    451    Int    i, tmp_log_fd, tmp_xml_fd;
    452    Int    toolname_len = VG_(strlen)(toolname);
    453    const HChar* tmp_str;         // Used in a couple of places.
    454    enum {
    455       VgLogTo_Fd,
    456       VgLogTo_File,
    457       VgLogTo_Socket
    458    } log_to = VgLogTo_Fd,   // Where is logging output to be sent?
    459      xml_to = VgLogTo_Fd;   // Where is XML output to be sent?
    460 
    461    /* Temporarily holds the string STR specified with
    462       --{log,xml}-{name,socket}=STR.  'fs' stands for
    463       file-or-socket. */
    464    const HChar* log_fsname_unexpanded = NULL;
    465    const HChar* xml_fsname_unexpanded = NULL;
    466 
    467    /* Whether the user has explicitly provided --sigill-diagnostics.
    468       If not explicitly given depends on general verbosity setting. */
    469    Bool sigill_diag_set = False;
    470 
    471    /* Log to stderr by default, but usage message goes to stdout.  XML
    472       output is initially disabled. */
    473    tmp_log_fd = 2;
    474    tmp_xml_fd = -1;
    475 
    476    /* Check for sane path in ./configure --prefix=... */
    477    if (VG_LIBDIR[0] != '/')
    478       VG_(err_config_error)("Please use absolute paths in "
    479                             "./configure --prefix=... or --libdir=...\n");
    480 
    481    vg_assert( VG_(args_for_valgrind) );
    482 
    483    VG_(clo_suppressions) = VG_(newXA)(VG_(malloc), "main.mpclo.4",
    484                                       VG_(free), sizeof(HChar *));
    485    VG_(clo_fullpath_after) = VG_(newXA)(VG_(malloc), "main.mpclo.5",
    486                                         VG_(free), sizeof(HChar *));
    487    VG_(clo_req_tsyms) = VG_(newXA)(VG_(malloc), "main.mpclo.6",
    488                                    VG_(free), sizeof(HChar *));
    489 
    490    /* Constants for parsing PX control flags. */
    491    const HChar* pxStrings[5]
    492       = { "sp-at-mem-access",      "unwindregs-at-mem-access",
    493           "allregs-at-mem-access", "allregs-at-each-insn", NULL };
    494    const VexRegisterUpdates pxVals[5]
    495       = { VexRegUpdSpAtMemAccess,      VexRegUpdUnwindregsAtMemAccess,
    496           VexRegUpdAllregsAtMemAccess, VexRegUpdAllregsAtEachInsn, 0/*inval*/ };
    497 
    498    /* BEGIN command-line processing loop */
    499 
    500    for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
    501 
    502       HChar* arg   = * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i );
    503       HChar* colon = arg;
    504       UInt   ix    = 0;
    505 
    506       // Look for a colon in the option name.
    507       while (*colon && *colon != ':' && *colon != '=')
    508          colon++;
    509 
    510       // Does it have the form "--toolname:foo"?  We have to do it at the start
    511       // in case someone has combined a prefix with a core-specific option,
    512       // eg.  "--memcheck:verbose".
    513       if (*colon == ':') {
    514          if (VG_STREQN(2,            arg,                "--") &&
    515              VG_STREQN(toolname_len, arg+2,              toolname) &&
    516              VG_STREQN(1,            arg+2+toolname_len, ":"))
    517          {
    518             // Prefix matches, convert "--toolname:foo" to "--foo".
    519             // Two things to note:
    520             // - We cannot modify the option in-place.  If we did, and then
    521             //   a child was spawned with --trace-children=yes, the
    522             //   now-non-prefixed option would be passed and could screw up
    523             //   the child.
    524             // - We create copies, and never free them.  Why?  Non-prefixed
    525             //   options hang around forever, so tools need not make copies
    526             //   of strings within them.  We need to have the same behaviour
    527             //   for prefixed options.  The pointer to the copy will be lost
    528             //   once we leave this function (although a tool may keep a
    529             //   pointer into it), but the space wasted is insignificant.
    530             //   (In bug #142197, the copies were being freed, which caused
    531             //   problems for tools that reasonably assumed that arguments
    532             //   wouldn't disappear on them.)
    533             if (0)
    534                VG_(printf)("tool-specific arg: %s\n", arg);
    535             arg = VG_(strdup)("main.mpclo.1", arg + toolname_len + 1);
    536             arg[0] = '-';
    537             arg[1] = '-';
    538 
    539          } else {
    540             // prefix doesn't match, skip to next arg
    541             continue;
    542          }
    543       }
    544 
    545       /* Ignore these options - they've already been handled */
    546       if      VG_STREQN( 7, arg, "--tool=")              {}
    547       else if VG_STREQN(20, arg, "--command-line-only=") {}
    548       else if VG_STREQ(     arg, "--")                   {}
    549       else if VG_STREQ(     arg, "-d")                   {}
    550       else if VG_STREQN(17, arg, "--max-stackframe=")    {}
    551       else if VG_STREQN(17, arg, "--main-stacksize=")    {}
    552       else if VG_STREQN(14, arg, "--max-threads=")       {}
    553       else if VG_STREQN(12, arg, "--sim-hints=")         {}
    554       else if VG_STREQN(15, arg, "--profile-heap=")      {}
    555       else if VG_STREQN(20, arg, "--core-redzone-size=") {}
    556       else if VG_STREQN(15, arg, "--redzone-size=")      {}
    557       else if VG_STREQN(17, arg, "--aspace-minaddr=")    {}
    558 
    559       else if VG_BINT_CLO(arg, "--valgrind-stacksize",
    560                           VG_(clo_valgrind_stacksize),
    561                           2*VKI_PAGE_SIZE, 10*VG_DEFAULT_STACK_ACTIVE_SZB)
    562                             {VG_(clo_valgrind_stacksize)
    563                                   = VG_PGROUNDUP(VG_(clo_valgrind_stacksize));}
    564 
    565       /* Obsolete options. Report an error and exit */
    566       else if VG_STREQN(34, arg, "--vex-iropt-precise-memory-exns=no") {
    567          VG_(fmsg_bad_option)
    568             (arg,
    569              "--vex-iropt-precise-memory-exns is obsolete\n"
    570              "Use --vex-iropt-register-updates=unwindregs-at-mem-access instead\n");
    571       }
    572       else if VG_STREQN(35, arg, "--vex-iropt-precise-memory-exns=yes") {
    573          VG_(fmsg_bad_option)
    574             (arg,
    575              "--vex-iropt-precise-memory-exns is obsolete\n"
    576              "Use --vex-iropt-register-updates=allregs-at-mem-access instead\n"
    577              " (or --vex-iropt-register-updates=allregs-at-each-insn)\n");
    578       }
    579 
    580       // These options are new.
    581       else if (VG_STREQ(arg, "-v") ||
    582                VG_STREQ(arg, "--verbose"))
    583          VG_(clo_verbosity)++;
    584 
    585       else if (VG_STREQ(arg, "-q") ||
    586                VG_STREQ(arg, "--quiet"))
    587          VG_(clo_verbosity)--;
    588 
    589       else if VG_BOOL_CLO(arg, "--sigill-diagnostics", VG_(clo_sigill_diag))
    590          sigill_diag_set = True;
    591 
    592       else if VG_BOOL_CLO(arg, "--stats",          VG_(clo_stats)) {}
    593       else if VG_BOOL_CLO(arg, "--xml",            VG_(clo_xml))
    594          VG_(debugLog_setXml)(VG_(clo_xml));
    595 
    596       else if VG_XACT_CLO(arg, "--vgdb=no",        VG_(clo_vgdb), Vg_VgdbNo) {}
    597       else if VG_XACT_CLO(arg, "--vgdb=yes",       VG_(clo_vgdb), Vg_VgdbYes) {}
    598       else if VG_XACT_CLO(arg, "--vgdb=full",      VG_(clo_vgdb), Vg_VgdbFull) {
    599          /* automatically updates register values at each insn
    600             with --vgdb=full */
    601          VG_(clo_vex_control).iropt_register_updates_default
    602             = VG_(clo_px_file_backed)
    603             = VexRegUpdAllregsAtEachInsn;
    604       }
    605       else if VG_INT_CLO (arg, "--vgdb-poll",      VG_(clo_vgdb_poll)) {}
    606       else if VG_INT_CLO (arg, "--vgdb-error",     VG_(clo_vgdb_error)) {}
    607       else if VG_USET_CLO (arg, "--vgdb-stop-at",
    608                            "startup,exit,valgrindabexit",
    609                            VG_(clo_vgdb_stop_at)) {}
    610       else if VG_STR_CLO (arg, "--vgdb-prefix",    VG_(clo_vgdb_prefix)) {
    611          VG_(arg_vgdb_prefix) = arg;
    612       }
    613       else if VG_BOOL_CLO(arg, "--vgdb-shadow-registers",
    614                             VG_(clo_vgdb_shadow_registers)) {}
    615       else if VG_BOOL_CLO(arg, "--demangle",       VG_(clo_demangle)) {}
    616       else if VG_STR_CLO (arg, "--soname-synonyms",VG_(clo_soname_synonyms)) {}
    617       else if VG_BOOL_CLO(arg, "--error-limit",    VG_(clo_error_limit)) {}
    618       else if VG_INT_CLO (arg, "--error-exitcode", VG_(clo_error_exitcode)) {}
    619       else if VG_STR_CLO (arg, "--error-markers",  tmp_str) {
    620          Int m;
    621          const HChar *startpos = tmp_str;
    622          const HChar *nextpos;
    623          for (m = 0;
    624               m < sizeof(VG_(clo_error_markers))
    625                  /sizeof(VG_(clo_error_markers)[0]);
    626               m++) {
    627             /* Release previous value if clo given multiple times. */
    628             VG_(free)(VG_(clo_error_markers)[m]);
    629             VG_(clo_error_markers)[m] = NULL;
    630 
    631             nextpos = VG_(strchr)(startpos, ',');
    632             if (!nextpos)
    633                nextpos = startpos + VG_(strlen)(startpos);
    634             if (startpos != nextpos) {
    635                VG_(clo_error_markers)[m]
    636                   = VG_(malloc)("main.mpclo.2", nextpos - startpos + 1);
    637                VG_(memcpy)(VG_(clo_error_markers)[m], startpos,
    638                            nextpos - startpos);
    639                VG_(clo_error_markers)[m][nextpos - startpos] = '\0';
    640             }
    641             startpos = *nextpos ? nextpos + 1 : nextpos;
    642          }
    643       }
    644       else if VG_BOOL_CLO(arg, "--show-emwarns",   VG_(clo_show_emwarns)) {}
    645 
    646       else if VG_BOOL_CLO(arg, "--run-libc-freeres", VG_(clo_run_libc_freeres)) {}
    647       else if VG_BOOL_CLO(arg, "--show-below-main",  VG_(clo_show_below_main)) {}
    648       else if VG_BOOL_CLO(arg, "--time-stamp",       VG_(clo_time_stamp)) {}
    649       else if VG_BOOL_CLO(arg, "--track-fds",        VG_(clo_track_fds)) {}
    650       else if VG_BOOL_CLO(arg, "--trace-children",   VG_(clo_trace_children)) {}
    651       else if VG_BOOL_CLO(arg, "--child-silent-after-fork",
    652                             VG_(clo_child_silent_after_fork)) {}
    653       else if VG_STR_CLO(arg, "--fair-sched",        tmp_str) {
    654          if (VG_(strcmp)(tmp_str, "yes") == 0)
    655             VG_(clo_fair_sched) = enable_fair_sched;
    656          else if (VG_(strcmp)(tmp_str, "try") == 0)
    657             VG_(clo_fair_sched) = try_fair_sched;
    658          else if (VG_(strcmp)(tmp_str, "no") == 0)
    659             VG_(clo_fair_sched) = disable_fair_sched;
    660          else
    661             VG_(fmsg_bad_option)(arg,
    662                "Bad argument, should be 'yes', 'try' or 'no'\n");
    663       }
    664       else if VG_BOOL_CLO(arg, "--trace-sched",      VG_(clo_trace_sched)) {}
    665       else if VG_BOOL_CLO(arg, "--trace-signals",    VG_(clo_trace_signals)) {}
    666       else if VG_BOOL_CLO(arg, "--trace-symtab",     VG_(clo_trace_symtab)) {}
    667       else if VG_STR_CLO (arg, "--trace-symtab-patt", VG_(clo_trace_symtab_patt)) {}
    668       else if VG_BOOL_CLO(arg, "--trace-cfi",        VG_(clo_trace_cfi)) {}
    669       else if VG_XACT_CLO(arg, "--debug-dump=syms",  VG_(clo_debug_dump_syms),
    670                                                      True) {}
    671       else if VG_XACT_CLO(arg, "--debug-dump=line",  VG_(clo_debug_dump_line),
    672                                                      True) {}
    673       else if VG_XACT_CLO(arg, "--debug-dump=frames",
    674                                VG_(clo_debug_dump_frames), True) {}
    675       else if VG_BOOL_CLO(arg, "--trace-redir",      VG_(clo_trace_redir)) {}
    676 
    677       else if VG_BOOL_CLO(arg, "--trace-syscalls",   VG_(clo_trace_syscalls)) {}
    678       else if VG_BOOL_CLO(arg, "--wait-for-gdb",     VG_(clo_wait_for_gdb)) {}
    679       else if VG_BOOL_CLO(arg, "--sym-offsets",      VG_(clo_sym_offsets)) {}
    680       else if VG_BOOL_CLO(arg, "--read-inline-info", VG_(clo_read_inline_info)) {}
    681       else if VG_BOOL_CLO(arg, "--read-var-info",    VG_(clo_read_var_info)) {}
    682 
    683       else if VG_INT_CLO (arg, "--dump-error",       VG_(clo_dump_error))   {}
    684       else if VG_INT_CLO (arg, "--input-fd",         VG_(clo_input_fd))     {}
    685       else if VG_INT_CLO (arg, "--sanity-level",     VG_(clo_sanity_level)) {}
    686       else if VG_BINT_CLO(arg, "--num-callers",      VG_(clo_backtrace_size), 1,
    687                                                      VG_DEEPEST_BACKTRACE) {}
    688       else if VG_BINT_CLO(arg, "--num-transtab-sectors",
    689                                VG_(clo_num_transtab_sectors),
    690                                MIN_N_SECTORS, MAX_N_SECTORS) {}
    691       else if VG_BINT_CLO(arg, "--avg-transtab-entry-size",
    692                                VG_(clo_avg_transtab_entry_size),
    693                                50, 5000) {}
    694       else if VG_BINT_CLO(arg, "--merge-recursive-frames",
    695                                VG_(clo_merge_recursive_frames), 0,
    696                                VG_DEEPEST_BACKTRACE) {}
    697 
    698       else if VG_XACT_CLO(arg, "--smc-check=none",
    699                           VG_(clo_smc_check), Vg_SmcNone) {}
    700       else if VG_XACT_CLO(arg, "--smc-check=stack",
    701                           VG_(clo_smc_check), Vg_SmcStack) {}
    702       else if VG_XACT_CLO(arg, "--smc-check=all",
    703                           VG_(clo_smc_check), Vg_SmcAll) {}
    704       else if VG_XACT_CLO(arg, "--smc-check=all-non-file",
    705                           VG_(clo_smc_check), Vg_SmcAllNonFile) {}
    706 
    707       else if VG_USETX_CLO (arg, "--kernel-variant",
    708                             "bproc,"
    709                             "android-no-hw-tls,"
    710                             "android-gpu-sgx5xx,"
    711                             "android-gpu-adreno3xx",
    712                             VG_(clo_kernel_variant)) {}
    713 
    714       else if VG_BOOL_CLO(arg, "--dsymutil",        VG_(clo_dsymutil)) {}
    715 
    716       else if VG_STR_CLO (arg, "--trace-children-skip",
    717                                VG_(clo_trace_children_skip)) {}
    718       else if VG_STR_CLO (arg, "--trace-children-skip-by-arg",
    719                                VG_(clo_trace_children_skip_by_arg)) {}
    720 
    721       else if VG_BINT_CLO(arg, "--vex-iropt-verbosity",
    722                        VG_(clo_vex_control).iropt_verbosity, 0, 10) {}
    723       else if VG_BINT_CLO(arg, "--vex-iropt-level",
    724                        VG_(clo_vex_control).iropt_level, 0, 2) {}
    725 
    726       else if VG_STRINDEX_CLO(arg, "--vex-iropt-register-updates",
    727                                    pxStrings, ix) {
    728          vg_assert(ix < 4);
    729          vg_assert(pxVals[ix] >= VexRegUpdSpAtMemAccess);
    730          vg_assert(pxVals[ix] <= VexRegUpdAllregsAtEachInsn);
    731          VG_(clo_vex_control).iropt_register_updates_default = pxVals[ix];
    732       }
    733       else if VG_STRINDEX_CLO(arg, "--px-default", pxStrings, ix) {
    734          // NB: --px-default is an alias for the hard-to-remember
    735          // --vex-iropt-register-updates, hence the same logic.
    736          vg_assert(ix < 4);
    737          vg_assert(pxVals[ix] >= VexRegUpdSpAtMemAccess);
    738          vg_assert(pxVals[ix] <= VexRegUpdAllregsAtEachInsn);
    739          VG_(clo_vex_control).iropt_register_updates_default = pxVals[ix];
    740       }
    741       else if VG_STRINDEX_CLO(arg, "--px-file-backed", pxStrings, ix) {
    742          // Whereas --px-file-backed isn't
    743          // the same flag as --vex-iropt-register-updates.
    744          vg_assert(ix < 4);
    745          vg_assert(pxVals[ix] >= VexRegUpdSpAtMemAccess);
    746          vg_assert(pxVals[ix] <= VexRegUpdAllregsAtEachInsn);
    747          VG_(clo_px_file_backed) = pxVals[ix];
    748       }
    749 
    750       else if VG_BINT_CLO(arg, "--vex-iropt-unroll-thresh",
    751                        VG_(clo_vex_control).iropt_unroll_thresh, 0, 400) {}
    752       else if VG_BINT_CLO(arg, "--vex-guest-max-insns",
    753                        VG_(clo_vex_control).guest_max_insns, 1, 100) {}
    754       else if VG_BINT_CLO(arg, "--vex-guest-chase-thresh",
    755                        VG_(clo_vex_control).guest_chase_thresh, 0, 99) {}
    756       else if VG_BOOL_CLO(arg, "--vex-guest-chase-cond",
    757                        VG_(clo_vex_control).guest_chase_cond) {}
    758 
    759       else if VG_INT_CLO(arg, "--log-fd", tmp_log_fd) {
    760          log_to = VgLogTo_Fd;
    761          log_fsname_unexpanded = NULL;
    762       }
    763       else if VG_INT_CLO(arg, "--xml-fd", tmp_xml_fd) {
    764          xml_to = VgLogTo_Fd;
    765          xml_fsname_unexpanded = NULL;
    766       }
    767 
    768       else if VG_STR_CLO(arg, "--log-file", log_fsname_unexpanded) {
    769          log_to = VgLogTo_File;
    770       }
    771       else if VG_STR_CLO(arg, "--xml-file", xml_fsname_unexpanded) {
    772          xml_to = VgLogTo_File;
    773       }
    774 
    775       else if VG_STR_CLO(arg, "--log-socket", log_fsname_unexpanded) {
    776          log_to = VgLogTo_Socket;
    777       }
    778       else if VG_STR_CLO(arg, "--xml-socket", xml_fsname_unexpanded) {
    779          xml_to = VgLogTo_Socket;
    780       }
    781 
    782       else if VG_STR_CLO(arg, "--debuginfo-server",
    783                               VG_(clo_debuginfo_server)) {}
    784 
    785       else if VG_BOOL_CLO(arg, "--allow-mismatched-debuginfo",
    786                                VG_(clo_allow_mismatched_debuginfo)) {}
    787 
    788       else if VG_STR_CLO(arg, "--xml-user-comment",
    789                               VG_(clo_xml_user_comment)) {}
    790 
    791       else if VG_BOOL_CLO(arg, "--default-suppressions",
    792                           VG_(clo_default_supp)) {}
    793 
    794       else if VG_STR_CLO(arg, "--suppressions", tmp_str) {
    795          VG_(addToXA)(VG_(clo_suppressions), &tmp_str);
    796       }
    797 
    798       else if VG_STR_CLO (arg, "--fullpath-after", tmp_str) {
    799          VG_(addToXA)(VG_(clo_fullpath_after), &tmp_str);
    800       }
    801 
    802       else if VG_STR_CLO (arg, "--extra-debuginfo-path",
    803                       VG_(clo_extra_debuginfo_path)) {}
    804 
    805       else if VG_STR_CLO(arg, "--require-text-symbol", tmp_str) {
    806          /* String needs to be of the form C?*C?*, where C is any
    807             character, but is the same both times.  Having it in this
    808             form facilitates finding the boundary between the sopatt
    809             and the fnpatt just by looking for the second occurrence
    810             of C, without hardwiring any assumption about what C
    811             is. */
    812          HChar patt[7];
    813          Bool ok = True;
    814          ok = tmp_str && VG_(strlen)(tmp_str) > 0;
    815          if (ok) {
    816            patt[0] = patt[3] = tmp_str[0];
    817            patt[1] = patt[4] = '?';
    818            patt[2] = patt[5] = '*';
    819            patt[6] = 0;
    820            ok = VG_(string_match)(patt, tmp_str);
    821          }
    822          if (!ok) {
    823             VG_(fmsg_bad_option)(arg,
    824                "Invalid --require-text-symbol= specification.\n");
    825          }
    826          VG_(addToXA)(VG_(clo_req_tsyms), &tmp_str);
    827       }
    828 
    829       /* "stuvwxyz" --> stuvwxyz (binary) */
    830       else if VG_STR_CLO(arg, "--trace-flags", tmp_str) {
    831          Int j;
    832          if (8 != VG_(strlen)(tmp_str)) {
    833             VG_(fmsg_bad_option)(arg,
    834                "--trace-flags argument must have 8 digits\n");
    835          }
    836          for (j = 0; j < 8; j++) {
    837             if      ('0' == tmp_str[j]) { /* do nothing */ }
    838             else if ('1' == tmp_str[j]) VG_(clo_trace_flags) |= (1 << (7-j));
    839             else {
    840                VG_(fmsg_bad_option)(arg,
    841                   "--trace-flags argument can only contain 0s and 1s\n");
    842             }
    843          }
    844       }
    845 
    846       else if VG_INT_CLO (arg, "--trace-notbelow", VG_(clo_trace_notbelow)) {}
    847 
    848       else if VG_INT_CLO (arg, "--trace-notabove", VG_(clo_trace_notabove)) {}
    849 
    850       /* "stuvwxyz" --> stuvwxyz (binary) */
    851       else if VG_STR_CLO(arg, "--profile-flags", tmp_str) {
    852          Int j;
    853          if (8 != VG_(strlen)(tmp_str)) {
    854             VG_(fmsg_bad_option)(arg,
    855                "--profile-flags argument must have 8 digits\n");
    856          }
    857          for (j = 0; j < 8; j++) {
    858             if      ('0' == tmp_str[j]) { /* do nothing */ }
    859             else if ('1' == tmp_str[j]) VG_(clo_profyle_flags) |= (1 << (7-j));
    860             else {
    861                VG_(fmsg_bad_option)(arg,
    862                   "--profile-flags argument can only contain 0s and 1s\n");
    863             }
    864          }
    865          VG_(clo_profyle_sbs) = True;
    866       }
    867 
    868       else if VG_INT_CLO (arg, "--profile-interval",
    869                           VG_(clo_profyle_interval)) {}
    870 
    871       else if VG_XACT_CLO(arg, "--gen-suppressions=no",
    872                                VG_(clo_gen_suppressions), 0) {}
    873       else if VG_XACT_CLO(arg, "--gen-suppressions=yes",
    874                                VG_(clo_gen_suppressions), 1) {}
    875       else if VG_XACT_CLO(arg, "--gen-suppressions=all",
    876                                VG_(clo_gen_suppressions), 2) {}
    877 
    878       else if VG_BINT_CLO(arg, "--unw-stack-scan-thresh",
    879                           VG_(clo_unw_stack_scan_thresh), 0, 100) {}
    880       else if VG_BINT_CLO(arg, "--unw-stack-scan-frames",
    881                           VG_(clo_unw_stack_scan_frames), 0, 32) {}
    882 
    883       else if VG_XACT_CLO(arg, "--resync-filter=no",
    884                                VG_(clo_resync_filter), 0) {}
    885       else if VG_XACT_CLO(arg, "--resync-filter=yes",
    886                                VG_(clo_resync_filter), 1) {}
    887       else if VG_XACT_CLO(arg, "--resync-filter=verbose",
    888                                VG_(clo_resync_filter), 2) {}
    889 
    890       else if ( ! VG_(needs).command_line_options
    891              || ! VG_TDICT_CALL(tool_process_cmd_line_option, arg) ) {
    892          VG_(fmsg_unknown_option)(arg);
    893       }
    894    }
    895 
    896    /* END command-line processing loop */
    897 
    898    /* Notify about deprecated features here. */
    899 
    900    /* Determine the path prefix for vgdb */
    901    if (VG_(clo_vgdb_prefix) == NULL)
    902      VG_(clo_vgdb_prefix) = VG_(vgdb_prefix_default)();
    903 
    904    /* Make VEX control parameters sane */
    905 
    906    if (VG_(clo_vex_control).guest_chase_thresh
    907        >= VG_(clo_vex_control).guest_max_insns)
    908       VG_(clo_vex_control).guest_chase_thresh
    909          = VG_(clo_vex_control).guest_max_insns - 1;
    910 
    911    if (VG_(clo_vex_control).guest_chase_thresh < 0)
    912       VG_(clo_vex_control).guest_chase_thresh = 0;
    913 
    914    /* Check various option values */
    915 
    916    if (VG_(clo_verbosity) < 0)
    917       VG_(clo_verbosity) = 0;
    918 
    919    if (!sigill_diag_set)
    920       VG_(clo_sigill_diag) = (VG_(clo_verbosity) > 0);
    921 
    922    if (VG_(clo_trace_notbelow) == -1) {
    923      if (VG_(clo_trace_notabove) == -1) {
    924        /* [] */
    925        VG_(clo_trace_notbelow) = 2147483647;
    926        VG_(clo_trace_notabove) = 0;
    927      } else {
    928        /* [0 .. notabove] */
    929        VG_(clo_trace_notbelow) = 0;
    930      }
    931    } else {
    932      if (VG_(clo_trace_notabove) == -1) {
    933        /* [notbelow .. ]  */
    934        VG_(clo_trace_notabove) = 2147483647;
    935      } else {
    936        /* [notbelow .. notabove]  */
    937      }
    938    }
    939 
    940    VG_(dyn_vgdb_error) = VG_(clo_vgdb_error);
    941 
    942    if (VG_(clo_gen_suppressions) > 0 &&
    943        !VG_(needs).core_errors && !VG_(needs).tool_errors) {
    944       VG_(fmsg_bad_option)("--gen-suppressions=yes",
    945          "Can't use --gen-suppressions= with %s\n"
    946          "because it doesn't generate errors.\n", VG_(details).name);
    947    }
    948 
    949 #  if !defined(VGO_darwin)
    950    if (VG_(clo_resync_filter) != 0) {
    951       VG_(fmsg_bad_option)("--resync-filter=yes or =verbose",
    952                            "--resync-filter= is only available on MacOS X.\n");
    953       /*NOTREACHED*/
    954    }
    955 #  endif
    956 
    957    /* If XML output is requested, check that the tool actually
    958       supports it. */
    959    if (VG_(clo_xml) && !VG_(needs).xml_output) {
    960       VG_(clo_xml) = False;
    961       VG_(fmsg_bad_option)("--xml=yes",
    962          "%s does not support XML output.\n", VG_(details).name);
    963       /*NOTREACHED*/
    964    }
    965 
    966    vg_assert( VG_(clo_gen_suppressions) >= 0 );
    967    vg_assert( VG_(clo_gen_suppressions) <= 2 );
    968 
    969    /* If we've been asked to emit XML, mash around various other
    970       options so as to constrain the output somewhat, and to remove
    971       any need for user input during the run.
    972    */
    973    if (VG_(clo_xml)) {
    974 
    975       /* We can't allow --gen-suppressions=yes, since that requires us
    976          to print the error and then ask the user if she wants a
    977          suppression for it, but in XML mode we won't print it until
    978          we know whether we also need to print a suppression.  Hence a
    979          circular dependency.  So disallow this.
    980          (--gen-suppressions=all is still OK since we don't need any
    981          user interaction in this case.) */
    982       if (VG_(clo_gen_suppressions) == 1) {
    983          VG_(fmsg_bad_option)(
    984             "--xml=yes together with --gen-suppressions=yes",
    985             "When --xml=yes is specified, --gen-suppressions=no\n"
    986             "or --gen-suppressions=all is allowed, but not "
    987             "--gen-suppressions=yes.\n");
    988       }
    989 
    990       /* Disallow dump_error in XML mode; sounds like a recipe for
    991          chaos.  No big deal; dump_error is a flag for debugging V
    992          itself. */
    993       if (VG_(clo_dump_error) > 0) {
    994          VG_(fmsg_bad_option)("--xml=yes",
    995             "Cannot be used together with --dump-error");
    996       }
    997 
    998       /* Disable error limits (this might be a bad idea!) */
    999       VG_(clo_error_limit) = False;
   1000       /* Disable emulation warnings */
   1001 
   1002       /* Also, we want to set options for the leak checker, but that
   1003          will have to be done in Memcheck's flag-handling code, not
   1004          here. */
   1005    }
   1006 
   1007    /* All non-logging-related options have been checked.  If the logging
   1008       option specified is ok, we can switch to it, as we know we won't
   1009       have to generate any other command-line-related error messages.
   1010       (So far we should be still attached to stderr, so we can show on
   1011       the terminal any problems to do with processing command line
   1012       opts.)
   1013 
   1014       So set up logging now.  After this is done, VG_(log_output_sink)
   1015       and (if relevant) VG_(xml_output_sink) should be connected to
   1016       whatever sink has been selected, and we indiscriminately chuck
   1017       stuff into it without worrying what the nature of it is.  Oh the
   1018       wonder of Unix streams. */
   1019 
   1020    vg_assert(VG_(log_output_sink).fd == 2 /* stderr */);
   1021    vg_assert(VG_(log_output_sink).is_socket == False);
   1022    vg_assert(VG_(clo_log_fname_expanded) == NULL);
   1023 
   1024    vg_assert(VG_(xml_output_sink).fd == -1 /* disabled */);
   1025    vg_assert(VG_(xml_output_sink).is_socket == False);
   1026    vg_assert(VG_(clo_xml_fname_expanded) == NULL);
   1027 
   1028    /* --- set up the normal text output channel --- */
   1029 
   1030    switch (log_to) {
   1031 
   1032       case VgLogTo_Fd:
   1033          vg_assert(log_fsname_unexpanded == NULL);
   1034          break;
   1035 
   1036       case VgLogTo_File: {
   1037          HChar* logfilename;
   1038 
   1039          vg_assert(log_fsname_unexpanded != NULL);
   1040          vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
   1041 
   1042          // Nb: we overwrite an existing file of this name without asking
   1043          // any questions.
   1044          logfilename = VG_(expand_file_name)("--log-file",
   1045                                              log_fsname_unexpanded);
   1046          sres = VG_(open)(logfilename,
   1047                           VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
   1048                           VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
   1049          if (!sr_isError(sres)) {
   1050             tmp_log_fd = sr_Res(sres);
   1051             VG_(clo_log_fname_expanded) = logfilename;
   1052          } else {
   1053             VG_(fmsg)("can't create log file '%s': %s\n",
   1054                       logfilename, VG_(strerror)(sr_Err(sres)));
   1055             VG_(exit)(1);
   1056             /*NOTREACHED*/
   1057          }
   1058          break;
   1059       }
   1060 
   1061       case VgLogTo_Socket: {
   1062          vg_assert(log_fsname_unexpanded != NULL);
   1063          vg_assert(VG_(strlen)(log_fsname_unexpanded) <= 900); /* paranoia */
   1064          tmp_log_fd = VG_(connect_via_socket)( log_fsname_unexpanded );
   1065          if (tmp_log_fd == -1) {
   1066             VG_(fmsg)("Invalid --log-socket spec of '%s'\n",
   1067                       log_fsname_unexpanded);
   1068             VG_(exit)(1);
   1069             /*NOTREACHED*/
   1070 	 }
   1071          if (tmp_log_fd == -2) {
   1072             VG_(umsg)("failed to connect to logging server '%s'.\n"
   1073                       "Log messages will sent to stderr instead.\n",
   1074                       log_fsname_unexpanded );
   1075 
   1076             /* We don't change anything here. */
   1077             vg_assert(VG_(log_output_sink).fd == 2);
   1078             tmp_log_fd = 2;
   1079 	 } else {
   1080             vg_assert(tmp_log_fd > 0);
   1081             VG_(log_output_sink).is_socket = True;
   1082          }
   1083          break;
   1084       }
   1085    }
   1086 
   1087    /* --- set up the XML output channel --- */
   1088 
   1089    switch (xml_to) {
   1090 
   1091       case VgLogTo_Fd:
   1092          vg_assert(xml_fsname_unexpanded == NULL);
   1093          break;
   1094 
   1095       case VgLogTo_File: {
   1096          HChar* xmlfilename;
   1097 
   1098          vg_assert(xml_fsname_unexpanded != NULL);
   1099          vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
   1100 
   1101          // Nb: we overwrite an existing file of this name without asking
   1102          // any questions.
   1103          xmlfilename = VG_(expand_file_name)("--xml-file",
   1104                                              xml_fsname_unexpanded);
   1105          sres = VG_(open)(xmlfilename,
   1106                           VKI_O_CREAT|VKI_O_WRONLY|VKI_O_TRUNC,
   1107                           VKI_S_IRUSR|VKI_S_IWUSR|VKI_S_IRGRP|VKI_S_IROTH);
   1108          if (!sr_isError(sres)) {
   1109             tmp_xml_fd = sr_Res(sres);
   1110             VG_(clo_xml_fname_expanded) = xmlfilename;
   1111             *xml_fname_unexpanded = xml_fsname_unexpanded;
   1112          } else {
   1113             VG_(fmsg)("can't create XML file '%s': %s\n",
   1114                       xmlfilename, VG_(strerror)(sr_Err(sres)));
   1115             VG_(exit)(1);
   1116             /*NOTREACHED*/
   1117          }
   1118          break;
   1119       }
   1120 
   1121       case VgLogTo_Socket: {
   1122          vg_assert(xml_fsname_unexpanded != NULL);
   1123          vg_assert(VG_(strlen)(xml_fsname_unexpanded) <= 900); /* paranoia */
   1124          tmp_xml_fd = VG_(connect_via_socket)( xml_fsname_unexpanded );
   1125          if (tmp_xml_fd == -1) {
   1126             VG_(fmsg)("Invalid --xml-socket spec of '%s'\n",
   1127                       xml_fsname_unexpanded );
   1128             VG_(exit)(1);
   1129             /*NOTREACHED*/
   1130 	 }
   1131          if (tmp_xml_fd == -2) {
   1132             VG_(umsg)("failed to connect to XML logging server '%s'.\n"
   1133                       "XML output will sent to stderr instead.\n",
   1134                       xml_fsname_unexpanded);
   1135             /* We don't change anything here. */
   1136             vg_assert(VG_(xml_output_sink).fd == 2);
   1137             tmp_xml_fd = 2;
   1138 	 } else {
   1139             vg_assert(tmp_xml_fd > 0);
   1140             VG_(xml_output_sink).is_socket = True;
   1141          }
   1142          break;
   1143       }
   1144    }
   1145 
   1146    /* If we've got this far, and XML mode was requested, but no XML
   1147       output channel appears to have been specified, just stop.  We
   1148       could continue, and XML output will simply vanish into nowhere,
   1149       but that is likely to confuse the hell out of users, which is
   1150       distinctly Ungood. */
   1151    if (VG_(clo_xml) && tmp_xml_fd == -1) {
   1152       VG_(fmsg_bad_option)(
   1153           "--xml=yes, but no XML destination specified",
   1154           "--xml=yes has been specified, but there is no XML output\n"
   1155           "destination.  You must specify an XML output destination\n"
   1156           "using --xml-fd, --xml-file or --xml-socket.\n"
   1157       );
   1158    }
   1159 
   1160    // Finalise the output fds: the log fd ..
   1161 
   1162    if (tmp_log_fd >= 0) {
   1163       // Move log_fd into the safe range, so it doesn't conflict with
   1164       // any app fds.
   1165       tmp_log_fd = VG_(fcntl)(tmp_log_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
   1166       if (tmp_log_fd < 0) {
   1167          VG_(message)(Vg_UserMsg, "valgrind: failed to move logfile fd "
   1168                                   "into safe range, using stderr\n");
   1169          VG_(log_output_sink).fd = 2;   // stderr
   1170          VG_(log_output_sink).is_socket = False;
   1171       } else {
   1172          VG_(log_output_sink).fd = tmp_log_fd;
   1173          VG_(fcntl)(VG_(log_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
   1174       }
   1175    } else {
   1176       // If they said --log-fd=-1, don't print anything.  Plausible for use in
   1177       // regression testing suites that use client requests to count errors.
   1178       VG_(log_output_sink).fd = -1;
   1179       VG_(log_output_sink).is_socket = False;
   1180    }
   1181 
   1182    // Finalise the output fds: and the XML fd ..
   1183 
   1184    if (tmp_xml_fd >= 0) {
   1185       // Move xml_fd into the safe range, so it doesn't conflict with
   1186       // any app fds.
   1187       tmp_xml_fd = VG_(fcntl)(tmp_xml_fd, VKI_F_DUPFD, VG_(fd_hard_limit));
   1188       if (tmp_xml_fd < 0) {
   1189          VG_(message)(Vg_UserMsg, "valgrind: failed to move XML file fd "
   1190                                   "into safe range, using stderr\n");
   1191          VG_(xml_output_sink).fd = 2;   // stderr
   1192          VG_(xml_output_sink).is_socket = False;
   1193       } else {
   1194          VG_(xml_output_sink).fd = tmp_xml_fd;
   1195          VG_(fcntl)(VG_(xml_output_sink).fd, VKI_F_SETFD, VKI_FD_CLOEXEC);
   1196       }
   1197    } else {
   1198       // If they said --xml-fd=-1, don't print anything.  Plausible for use in
   1199       // regression testing suites that use client requests to count errors.
   1200       VG_(xml_output_sink).fd = -1;
   1201       VG_(xml_output_sink).is_socket = False;
   1202    }
   1203 
   1204    // Suppressions related stuff
   1205 
   1206    if (VG_(clo_default_supp) &&
   1207        (VG_(needs).core_errors || VG_(needs).tool_errors)) {
   1208       /* If we haven't reached the max number of suppressions, load
   1209          the default one. */
   1210       static const HChar default_supp[] = "default.supp";
   1211       Int len = VG_(strlen)(VG_(libdir)) + 1 + sizeof(default_supp);
   1212       HChar *buf = VG_(malloc)("main.mpclo.3", len);
   1213       VG_(sprintf)(buf, "%s/%s", VG_(libdir), default_supp);
   1214       VG_(addToXA)(VG_(clo_suppressions), &buf);
   1215    }
   1216 
   1217    *logging_to_fd = log_to == VgLogTo_Fd || log_to == VgLogTo_Socket;
   1218 }
   1219 
   1220 // Write the name and value of log file qualifiers to the xml file.
   1221 // We can safely assume here that the format string is well-formed.
   1222 // It has been checked earlier in VG_(expand_file_name) when processing
   1223 // command line options.
   1224 static void print_file_vars(const HChar* format)
   1225 {
   1226    Int i = 0;
   1227 
   1228    while (format[i]) {
   1229       if (format[i] == '%') {
   1230          // We saw a '%'.  What's next...
   1231          i++;
   1232 	 if ('q' == format[i]) {
   1233             i++;
   1234             if ('{' == format[i]) {
   1235 	       // Get the env var name, print its contents.
   1236                HChar* qual;
   1237                Int begin_qualname = ++i;
   1238                while (True) {
   1239 		  if ('}' == format[i]) {
   1240                      Int qualname_len = i - begin_qualname;
   1241                      HChar qualname[qualname_len + 1];
   1242                      VG_(strncpy)(qualname, format + begin_qualname,
   1243                                   qualname_len);
   1244                      qualname[qualname_len] = '\0';
   1245                      qual = VG_(getenv)(qualname);
   1246                      i++;
   1247                      VG_(printf_xml)("<logfilequalifier> <var>%pS</var> "
   1248                                      "<value>%pS</value> </logfilequalifier>\n",
   1249                                      qualname, qual);
   1250 		     break;
   1251                   }
   1252                   i++;
   1253                }
   1254 	    }
   1255          }
   1256       } else {
   1257 	 i++;
   1258       }
   1259    }
   1260 }
   1261 
   1262 
   1263 /*====================================================================*/
   1264 /*=== Printing the preamble                                        ===*/
   1265 /*====================================================================*/
   1266 
   1267 // Print the argument, escaping any chars that require it.
   1268 static void umsg_arg(const HChar* arg)
   1269 {
   1270    SizeT len = VG_(strlen)(arg);
   1271    const HChar* special = " \\<>";
   1272    Int i;
   1273    for (i = 0; i < len; i++) {
   1274       if (VG_(strchr)(special, arg[i])) {
   1275          VG_(umsg)("\\");   // escape with a backslash if necessary
   1276       }
   1277       VG_(umsg)("%c", arg[i]);
   1278    }
   1279 }
   1280 
   1281 // Send output to the XML-stream and escape any XML meta-characters.
   1282 static void xml_arg(const HChar* arg)
   1283 {
   1284    VG_(printf_xml)("%pS", arg);
   1285 }
   1286 
   1287 /* Ok, the logging sink is running now.  Print a suitable preamble.
   1288    If logging to file or a socket, write details of parent PID and
   1289    command line args, to help people trying to interpret the
   1290    results of a run which encompasses multiple processes. */
   1291 static void print_preamble ( Bool logging_to_fd,
   1292                              const HChar* xml_fname_unexpanded,
   1293                              const HChar* toolname )
   1294 {
   1295    Int    i;
   1296    const HChar* xpre  = VG_(clo_xml) ? "  <line>" : "";
   1297    const HChar* xpost = VG_(clo_xml) ? "</line>" : "";
   1298    UInt (*umsg_or_xml)( const HChar*, ... )
   1299       = VG_(clo_xml) ? VG_(printf_xml) : VG_(umsg);
   1300 
   1301    void (*umsg_or_xml_arg)( const HChar* )
   1302       = VG_(clo_xml) ? xml_arg : umsg_arg;
   1303 
   1304    vg_assert( VG_(args_for_client) );
   1305    vg_assert( VG_(args_for_valgrind) );
   1306    vg_assert( toolname );
   1307 
   1308    if (VG_(clo_xml)) {
   1309       VG_(printf_xml)("<?xml version=\"1.0\"?>\n");
   1310       VG_(printf_xml)("\n");
   1311       VG_(printf_xml)("<valgrindoutput>\n");
   1312       VG_(printf_xml)("\n");
   1313       VG_(printf_xml)("<protocolversion>4</protocolversion>\n");
   1314       VG_(printf_xml)("<protocoltool>%s</protocoltool>\n", toolname);
   1315       VG_(printf_xml)("\n");
   1316    }
   1317 
   1318    if (VG_(clo_xml) || VG_(clo_verbosity > 0)) {
   1319 
   1320       if (VG_(clo_xml))
   1321          VG_(printf_xml)("<preamble>\n");
   1322 
   1323       /* Tool details */
   1324       umsg_or_xml( VG_(clo_xml) ? "%s%pS%pS%pS, %pS%s\n" : "%s%s%s%s, %s%s\n",
   1325                    xpre,
   1326                    VG_(details).name,
   1327                    NULL == VG_(details).version ? "" : "-",
   1328                    NULL == VG_(details).version
   1329                       ? "" : VG_(details).version,
   1330                    VG_(details).description,
   1331                    xpost );
   1332 
   1333       if (VG_(strlen)(toolname) >= 4 && VG_STREQN(4, toolname, "exp-")) {
   1334          umsg_or_xml(
   1335             "%sNOTE: This is an Experimental-Class Valgrind Tool%s\n",
   1336             xpre, xpost
   1337          );
   1338       }
   1339 
   1340       umsg_or_xml( VG_(clo_xml) ? "%s%pS%s\n" : "%s%s%s\n",
   1341                    xpre, VG_(details).copyright_author, xpost );
   1342 
   1343       /* Core details */
   1344       umsg_or_xml(
   1345          "%sUsing Valgrind-%s and LibVEX; rerun with -h for copyright info%s\n",
   1346          xpre, VERSION, xpost
   1347       );
   1348 
   1349       // Print the command line.  At one point we wrapped at 80 chars and
   1350       // printed a '\' as a line joiner, but that makes it hard to cut and
   1351       // paste the command line (because of the "==pid==" prefixes), so we now
   1352       // favour utility and simplicity over aesthetics.
   1353       umsg_or_xml("%sCommand: ", xpre);
   1354       umsg_or_xml_arg(VG_(args_the_exename));
   1355 
   1356       for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
   1357          HChar* s = *(HChar**)VG_(indexXA)( VG_(args_for_client), i );
   1358          umsg_or_xml(" ");
   1359          umsg_or_xml_arg(s);
   1360       }
   1361       umsg_or_xml("%s\n", xpost);
   1362 
   1363       if (VG_(clo_xml))
   1364          VG_(printf_xml)("</preamble>\n");
   1365    }
   1366 
   1367    // Print the parent PID, and other stuff, if necessary.
   1368    if (!VG_(clo_xml) && VG_(clo_verbosity) > 0 && !logging_to_fd) {
   1369       VG_(umsg)("Parent PID: %d\n", VG_(getppid)());
   1370    }
   1371    else
   1372    if (VG_(clo_xml)) {
   1373       VG_(printf_xml)("\n");
   1374       VG_(printf_xml)("<pid>%d</pid>\n", VG_(getpid)());
   1375       VG_(printf_xml)("<ppid>%d</ppid>\n", VG_(getppid)());
   1376       VG_(printf_xml)("<tool>%pS</tool>\n", toolname);
   1377       if (xml_fname_unexpanded)
   1378          print_file_vars(xml_fname_unexpanded);
   1379       if (VG_(clo_xml_user_comment)) {
   1380          /* Note: the user comment itself is XML and is therefore to
   1381             be passed through verbatim (%s) rather than escaped
   1382             (%pS). */
   1383          VG_(printf_xml)("<usercomment>%s</usercomment>\n",
   1384                          VG_(clo_xml_user_comment));
   1385       }
   1386       VG_(printf_xml)("\n");
   1387       VG_(printf_xml)("<args>\n");
   1388 
   1389       VG_(printf_xml)("  <vargv>\n");
   1390       if (VG_(name_of_launcher))
   1391          VG_(printf_xml)("    <exe>%pS</exe>\n",
   1392                                 VG_(name_of_launcher));
   1393       else
   1394          VG_(printf_xml)("    <exe>%pS</exe>\n",
   1395                                 "(launcher name unknown)");
   1396       for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
   1397          VG_(printf_xml)(
   1398             "    <arg>%pS</arg>\n",
   1399             * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
   1400          );
   1401       }
   1402       VG_(printf_xml)("  </vargv>\n");
   1403 
   1404       VG_(printf_xml)("  <argv>\n");
   1405       VG_(printf_xml)("    <exe>%pS</exe>\n",
   1406                                 VG_(args_the_exename));
   1407       for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
   1408          VG_(printf_xml)(
   1409             "    <arg>%pS</arg>\n",
   1410             * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
   1411          );
   1412       }
   1413       VG_(printf_xml)("  </argv>\n");
   1414 
   1415       VG_(printf_xml)("</args>\n");
   1416    }
   1417 
   1418    // Last thing in the preamble is a blank line.
   1419    if (VG_(clo_xml))
   1420       VG_(printf_xml)("\n");
   1421    else if (VG_(clo_verbosity) > 0)
   1422       VG_(umsg)("\n");
   1423 
   1424    if (VG_(clo_verbosity) > 1) {
   1425 # if defined(VGO_linux)
   1426       SysRes fd;
   1427 # endif
   1428       VexArch vex_arch;
   1429       VexArchInfo vex_archinfo;
   1430       if (!logging_to_fd)
   1431          VG_(message)(Vg_DebugMsg, "\n");
   1432       VG_(message)(Vg_DebugMsg, "Valgrind options:\n");
   1433       for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++) {
   1434          VG_(message)(Vg_DebugMsg,
   1435                      "   %s\n",
   1436                      * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i ));
   1437       }
   1438 
   1439 # if defined(VGO_linux)
   1440       VG_(message)(Vg_DebugMsg, "Contents of /proc/version:\n");
   1441       fd = VG_(open) ( "/proc/version", VKI_O_RDONLY, 0 );
   1442       if (sr_isError(fd)) {
   1443          VG_(message)(Vg_DebugMsg, "  can't open /proc/version\n");
   1444       } else {
   1445          const SizeT bufsiz = 255;
   1446          HChar version_buf[bufsiz+1];
   1447          VG_(message)(Vg_DebugMsg, "  ");
   1448          Int n, fdno = sr_Res(fd);
   1449          do {
   1450             n = VG_(read)(fdno, version_buf, bufsiz);
   1451             if (n < 0) {
   1452                VG_(message)(Vg_DebugMsg, "  error reading /proc/version\n");
   1453                break;
   1454             }
   1455             version_buf[n] = '\0';
   1456             VG_(message)(Vg_DebugMsg, "%s", version_buf);
   1457          } while (n == bufsiz);
   1458          VG_(message)(Vg_DebugMsg, "\n");
   1459          VG_(close)(fdno);
   1460       }
   1461 # elif defined(VGO_darwin)
   1462       VG_(message)(Vg_DebugMsg, "Output from sysctl({CTL_KERN,KERN_VERSION}):\n");
   1463       /* Note: preferable to use sysctlbyname("kern.version", kernelVersion, &len, NULL, 0)
   1464          however that syscall is OS X 10.10+ only. */
   1465       Int mib[] = {CTL_KERN, KERN_VERSION};
   1466       SizeT len;
   1467       VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), NULL, &len, NULL, 0);
   1468       HChar *kernelVersion = VG_(malloc)("main.pp.1", len);
   1469       VG_(sysctl)(mib, sizeof(mib)/sizeof(Int), kernelVersion, &len, NULL, 0);
   1470       VG_(message)(Vg_DebugMsg, "  %s\n", kernelVersion);
   1471       VG_(free)( kernelVersion );
   1472 # elif defined(VGO_solaris)
   1473       /* There is no /proc/version file on Solaris so we try to get some
   1474          system information using the uname(2) syscall. */
   1475       {
   1476          struct vki_utsname uts;
   1477 
   1478          VG_(message)(Vg_DebugMsg, "System information:\n");
   1479          SysRes res = VG_(do_syscall1)(__NR_uname, (UWord)&uts);
   1480          if (sr_isError(res))
   1481             VG_(message)(Vg_DebugMsg, "  uname() failed\n");
   1482          else
   1483             VG_(message)(Vg_DebugMsg, "  %s %s %s %s\n",
   1484                          uts.sysname, uts.release, uts.version, uts.machine);
   1485       }
   1486 # endif
   1487 
   1488       VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
   1489       VG_(message)(
   1490          Vg_DebugMsg,
   1491          "Arch and hwcaps: %s, %s, %s\n",
   1492          LibVEX_ppVexArch    ( vex_arch ),
   1493          LibVEX_ppVexEndness ( vex_archinfo.endness ),
   1494          LibVEX_ppVexHwCaps  ( vex_arch, vex_archinfo.hwcaps )
   1495       );
   1496       VG_(message)(
   1497          Vg_DebugMsg,
   1498          "Page sizes: currently %d, max supported %d\n",
   1499          (Int)VKI_PAGE_SIZE, (Int)VKI_MAX_PAGE_SIZE
   1500       );
   1501       VG_(message)(Vg_DebugMsg,
   1502                    "Valgrind library directory: %s\n", VG_(libdir));
   1503    }
   1504 }
   1505 
   1506 
   1507 /*====================================================================*/
   1508 /*=== File descriptor setup                                        ===*/
   1509 /*====================================================================*/
   1510 
   1511 /* Number of file descriptors that Valgrind tries to reserve for
   1512    it's own use - just a small constant. */
   1513 #define N_RESERVED_FDS (10)
   1514 
   1515 static void setup_file_descriptors(void)
   1516 {
   1517    struct vki_rlimit rl;
   1518    Bool show = False;
   1519 
   1520    /* Get the current file descriptor limits. */
   1521    if (VG_(getrlimit)(VKI_RLIMIT_NOFILE, &rl) < 0) {
   1522       rl.rlim_cur = 1024;
   1523       rl.rlim_max = 1024;
   1524    }
   1525 
   1526 #  if defined(VGO_darwin)
   1527    /* Darwin lies. It reports file max as RLIM_INFINITY but
   1528       silently disallows anything bigger than 10240. */
   1529    if (rl.rlim_cur >= 10240  &&  rl.rlim_max == 0x7fffffffffffffffULL) {
   1530       rl.rlim_max = 10240;
   1531    }
   1532 #  endif
   1533 
   1534    if (show)
   1535       VG_(printf)("fd limits: host, before: cur %llu max %llu\n",
   1536                   (ULong)rl.rlim_cur, (ULong)rl.rlim_max);
   1537 
   1538    /* Work out where to move the soft limit to. */
   1539    if (rl.rlim_cur + N_RESERVED_FDS <= rl.rlim_max) {
   1540       rl.rlim_cur = rl.rlim_cur + N_RESERVED_FDS;
   1541    } else {
   1542       rl.rlim_cur = rl.rlim_max;
   1543    }
   1544 
   1545    /* Reserve some file descriptors for our use. */
   1546    VG_(fd_soft_limit) = rl.rlim_cur - N_RESERVED_FDS;
   1547    VG_(fd_hard_limit) = rl.rlim_cur - N_RESERVED_FDS;
   1548 
   1549    /* Update the soft limit. */
   1550    VG_(setrlimit)(VKI_RLIMIT_NOFILE, &rl);
   1551 
   1552    if (show) {
   1553       VG_(printf)("fd limits: host,  after: cur %lu max %lu\n",
   1554                   (UWord)rl.rlim_cur, (UWord)rl.rlim_max);
   1555       VG_(printf)("fd limits: guest       : cur %d max %d\n",
   1556                   VG_(fd_soft_limit), VG_(fd_hard_limit));
   1557    }
   1558 
   1559    if (VG_(cl_exec_fd) != -1)
   1560       VG_(cl_exec_fd) = VG_(safe_fd)( VG_(cl_exec_fd) );
   1561 }
   1562 
   1563 
   1564 /*====================================================================*/
   1565 /*=== main()                                                       ===*/
   1566 /*====================================================================*/
   1567 
   1568 /* When main() is entered, we should be on the following stack, not
   1569    the one the kernel gave us.  We will run on this stack until
   1570    simulation of the root thread is started, at which point a transfer
   1571    is made to a dynamically allocated stack.  This is for the sake of
   1572    uniform overflow detection for all Valgrind threads.  This is
   1573    marked global even though it isn't, because assembly code below
   1574    needs to reference the name. */
   1575 
   1576 /*static*/ struct {
   1577    HChar bytes [VG_STACK_GUARD_SZB + VG_DEFAULT_STACK_ACTIVE_SZB + VG_STACK_GUARD_SZB];
   1578 } VG_(interim_stack);
   1579 
   1580 /* These are the structures used to hold info for creating the initial
   1581    client image.
   1582 
   1583    'iicii' mostly holds important register state present at system
   1584    startup (_start_valgrind).  valgrind_main() then fills in the rest
   1585    of it and passes it to VG_(ii_create_image)().  That produces
   1586    'iifii', which is later handed to VG_(ii_finalise_image). */
   1587 
   1588 /* In all OS-instantiations, the_iicii has a field .sp_at_startup.
   1589    This should get some address inside the stack on which we gained
   1590    control (eg, it could be the SP at startup).  It doesn't matter
   1591    exactly where in the stack it is.  This value is passed to the
   1592    address space manager at startup.  On Linux, aspacem then uses it
   1593    to identify the initial stack segment and hence the upper end of
   1594    the usable address space. */
   1595 
   1596 static IICreateImageInfo   the_iicii;
   1597 static IIFinaliseImageInfo the_iifii;
   1598 
   1599 
   1600 /* A simple pair structure, used for conveying debuginfo handles to
   1601    calls to VG_TRACK(new_mem_startup, ...). */
   1602 typedef  struct { Addr a; ULong ull; }  Addr_n_ULong;
   1603 
   1604 
   1605 /* --- Forwards decls to do with shutdown --- */
   1606 
   1607 static void final_tidyup(ThreadId tid);
   1608 
   1609 /* Do everything which needs doing when the last thread exits */
   1610 static
   1611 void shutdown_actions_NORETURN( ThreadId tid,
   1612                                 VgSchedReturnCode tids_schedretcode );
   1613 
   1614 /* --- end of Forwards decls to do with shutdown --- */
   1615 
   1616 
   1617 /* By the time we get to valgrind_main, the_iicii should already have
   1618    been filled in with any important details as required by whatever
   1619    OS we have been built for.
   1620 */
   1621 static
   1622 Int valgrind_main ( Int argc, HChar **argv, HChar **envp )
   1623 {
   1624    const HChar* toolname      = "memcheck";    // default to Memcheck
   1625    Int     need_help          = 0; // 0 = no, 1 = --help, 2 = --help-debug
   1626    ThreadId tid_main          = VG_INVALID_THREADID;
   1627    Bool    logging_to_fd      = False;
   1628    const HChar* xml_fname_unexpanded = NULL;
   1629    Int     loglevel, i;
   1630    struct vki_rlimit zero = { 0, 0 };
   1631    XArray* addr2dihandle = NULL;
   1632 
   1633    //============================================================
   1634    //
   1635    // Nb: startup is complex.  Prerequisites are shown at every step.
   1636    // *** Be very careful when messing with the order ***
   1637    //
   1638    // The first order of business is to get debug logging, the address
   1639    // space manager and the dynamic memory manager up and running.
   1640    // Once that's done, we can relax a bit.
   1641    //
   1642    //============================================================
   1643 
   1644    /* This is needed to make VG_(getenv) usable early. */
   1645    VG_(client_envp) = (HChar**)envp;
   1646 
   1647    //--------------------------------------------------------------
   1648    // Start up Mach kernel interface, if any
   1649    //   p: none
   1650    //--------------------------------------------------------------
   1651 #  if defined(VGO_darwin)
   1652    VG_(mach_init)();
   1653 #  endif
   1654 
   1655    //--------------------------------------------------------------
   1656    // Start up the logging mechanism
   1657    //   p: none
   1658    //--------------------------------------------------------------
   1659    /* Start the debugging-log system ASAP.  First find out how many
   1660       "-d"s were specified.  This is a pre-scan of the command line.  Also
   1661       get --profile-heap=yes, --core-redzone-size, --redzone-size
   1662       --aspace-minaddr which are needed by the time we start up dynamic
   1663       memory management.  */
   1664    loglevel = 0;
   1665    for (i = 1; i < argc; i++) {
   1666       const HChar* tmp_str;
   1667       if (argv[i][0] != '-') break;
   1668       if VG_STREQ(argv[i], "--") break;
   1669       if VG_STREQ(argv[i], "-d") loglevel++;
   1670       if VG_BOOL_CLO(argv[i], "--profile-heap", VG_(clo_profile_heap)) {}
   1671       if VG_BINT_CLO(argv[i], "--core-redzone-size", VG_(clo_core_redzone_size),
   1672                      0, MAX_CLO_REDZONE_SZB) {}
   1673       if VG_BINT_CLO(argv[i], "--redzone-size", VG_(clo_redzone_size),
   1674                      0, MAX_CLO_REDZONE_SZB) {}
   1675       if VG_STR_CLO(argv[i], "--aspace-minaddr", tmp_str) {
   1676          Bool ok = VG_(parse_Addr) (&tmp_str, &VG_(clo_aspacem_minAddr));
   1677          if (!ok)
   1678             VG_(fmsg_bad_option)(argv[i], "Invalid address\n");
   1679          const HChar *errmsg;
   1680          if (!VG_(am_is_valid_for_aspacem_minAddr)(VG_(clo_aspacem_minAddr),
   1681                                                    &errmsg))
   1682             VG_(fmsg_bad_option)(argv[i], "%s\n", errmsg);
   1683       }
   1684    }
   1685 
   1686    /* ... and start the debug logger.  Now we can safely emit logging
   1687       messages all through startup. */
   1688    VG_(debugLog_startup)(loglevel, "Stage 2 (main)");
   1689    VG_(debugLog)(1, "main", "Welcome to Valgrind version "
   1690                             VERSION " debug logging\n");
   1691 
   1692    //--------------------------------------------------------------
   1693    // Ensure we're on a plausible stack.
   1694    //   p: logging
   1695    //--------------------------------------------------------------
   1696    VG_(debugLog)(1, "main", "Checking current stack is plausible\n");
   1697    { HChar* limLo  = (HChar*)(&VG_(interim_stack).bytes[0]);
   1698      HChar* limHi  = limLo + sizeof(VG_(interim_stack));
   1699      HChar* volatile
   1700             aLocal = (HChar*)&limLo; /* any auto local will do */
   1701      /* Re "volatile": Apple clang version 4.0
   1702         (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)" appeared
   1703         to miscompile the following check, causing run to abort at
   1704         this point (in 64-bit mode) even though aLocal is within limLo
   1705         .. limHi.  But in fact clang is within its rights to do
   1706         strange things here.  "The reason is that the comparisons
   1707         aLocal < limLo and aLocal >= limHi cause undefined behaviour
   1708         (according to c99 6.5.8) because they compare pointers that do
   1709         not point into the same aggregate."  Adding "volatile" appears
   1710         to fix it because "The compiler would have to prove that there
   1711         is undefined behavior in order to exploit it.  But as a
   1712         volatile variable can change its value in ways invisible to
   1713         the compiler, the compiler must make the conservative
   1714         assumption that it points into the same aggregate as the other
   1715         pointer its compared against.  I.e. the behaviour is possibly
   1716         defined." (Analysis by Florian Krohm). */
   1717      if (aLocal < limLo || aLocal >= limHi) {
   1718         /* something's wrong.  Stop. */
   1719         VG_(debugLog)(0, "main", "Root stack %p to %p, a local %p\n",
   1720                           limLo, limHi, aLocal );
   1721         VG_(debugLog)(0, "main", "Valgrind: FATAL: "
   1722                                  "Initial stack switched failed.\n");
   1723         VG_(debugLog)(0, "main", "   Cannot continue.  Sorry.\n");
   1724         VG_(exit)(1);
   1725      }
   1726    }
   1727 
   1728    //--------------------------------------------------------------
   1729    // Ensure we have a plausible pointer to the stack on which
   1730    // we gained control (not the current stack!)
   1731    //   p: logging
   1732    //--------------------------------------------------------------
   1733    VG_(debugLog)(1, "main", "Checking initial stack was noted\n");
   1734    if (the_iicii.sp_at_startup == 0) {
   1735       VG_(debugLog)(0, "main", "Valgrind: FATAL: "
   1736                                "Initial stack was not noted.\n");
   1737       VG_(debugLog)(0, "main", "   Cannot continue.  Sorry.\n");
   1738       VG_(exit)(1);
   1739    }
   1740 
   1741    //--------------------------------------------------------------
   1742    // Start up the address space manager, and determine the
   1743    // approximate location of the client's stack
   1744    //   p: logging, plausible-stack
   1745    //--------------------------------------------------------------
   1746    VG_(debugLog)(1, "main", "Starting the address space manager\n");
   1747    vg_assert(VKI_PAGE_SIZE     == 4096 || VKI_PAGE_SIZE     == 65536
   1748              || VKI_PAGE_SIZE     == 16384);
   1749    vg_assert(VKI_MAX_PAGE_SIZE == 4096 || VKI_MAX_PAGE_SIZE == 65536
   1750              || VKI_MAX_PAGE_SIZE == 16384);
   1751    vg_assert(VKI_PAGE_SIZE <= VKI_MAX_PAGE_SIZE);
   1752    vg_assert(VKI_PAGE_SIZE     == (1 << VKI_PAGE_SHIFT));
   1753    vg_assert(VKI_MAX_PAGE_SIZE == (1 << VKI_MAX_PAGE_SHIFT));
   1754    the_iicii.clstack_end = VG_(am_startup)( the_iicii.sp_at_startup );
   1755    VG_(debugLog)(1, "main", "Address space manager is running\n");
   1756 
   1757    //--------------------------------------------------------------
   1758    // Start up the dynamic memory manager
   1759    //   p: address space management
   1760    //   p: getting --profile-heap,--core-redzone-size,--redzone-size
   1761    //   In fact m_mallocfree is self-initialising, so there's no
   1762    //   initialisation call to do.  Instead, try a simple malloc/
   1763    //   free pair right now to check that nothing is broken.
   1764    //--------------------------------------------------------------
   1765    VG_(debugLog)(1, "main", "Starting the dynamic memory manager\n");
   1766    { void* p = VG_(malloc)( "main.vm.1", 12345 );
   1767      VG_(free)( p );
   1768    }
   1769    VG_(debugLog)(1, "main", "Dynamic memory manager is running\n");
   1770 
   1771    //============================================================
   1772    //
   1773    // Dynamic memory management is now available.
   1774    //
   1775    //============================================================
   1776 
   1777    //--------------------------------------------------------------
   1778    // Initialise m_debuginfo
   1779    //  p: dynamic memory allocation
   1780    VG_(debugLog)(1, "main", "Initialise m_debuginfo\n");
   1781    VG_(di_initialise)();
   1782 
   1783    //--------------------------------------------------------------
   1784    // Look for alternative libdir
   1785    { HChar *cp = VG_(getenv)(VALGRIND_LIB);
   1786      if (cp != NULL)
   1787         VG_(libdir) = cp;
   1788      VG_(debugLog)(1, "main", "VG_(libdir) = %s\n", VG_(libdir));
   1789    }
   1790 
   1791    //--------------------------------------------------------------
   1792    // Extract the launcher name from the environment.
   1793    VG_(debugLog)(1, "main", "Getting launcher's name ...\n");
   1794    VG_(name_of_launcher) = VG_(getenv)(VALGRIND_LAUNCHER);
   1795    if (VG_(name_of_launcher) == NULL) {
   1796       VG_(printf)("valgrind: You cannot run '%s' directly.\n", argv[0]);
   1797       VG_(printf)("valgrind: You should use $prefix/bin/valgrind.\n");
   1798       VG_(exit)(1);
   1799    }
   1800    VG_(debugLog)(1, "main", "... %s\n", VG_(name_of_launcher));
   1801 
   1802    //--------------------------------------------------------------
   1803    // Get the current process datasize rlimit, and set it to zero.
   1804    // This prevents any internal uses of brk() from having any effect.
   1805    // We remember the old value so we can restore it on exec, so that
   1806    // child processes will have a reasonable brk value.
   1807    VG_(getrlimit)(VKI_RLIMIT_DATA, &VG_(client_rlimit_data));
   1808    zero.rlim_max = VG_(client_rlimit_data).rlim_max;
   1809    VG_(setrlimit)(VKI_RLIMIT_DATA, &zero);
   1810 
   1811    // Get the current process stack rlimit.
   1812    VG_(getrlimit)(VKI_RLIMIT_STACK, &VG_(client_rlimit_stack));
   1813 
   1814    //--------------------------------------------------------------
   1815    // Figure out what sort of CPU we're on, and whether it is
   1816    // able to run V.
   1817    /* The vex_archinfo structure is passed down later to the client
   1818     * to verify the HW info settings are consistent.
   1819     */
   1820    VexArchInfo vex_archinfo;
   1821    VG_(debugLog)(1, "main", "Get hardware capabilities ...\n");
   1822    { VexArch     vex_arch;
   1823      Bool ok = VG_(machine_get_hwcaps)();
   1824      if (!ok) {
   1825         VG_(printf)("\n");
   1826         VG_(printf)("valgrind: fatal error: unsupported CPU.\n");
   1827         VG_(printf)("   Supported CPUs are:\n");
   1828         VG_(printf)("   * x86 (practically any; Pentium-I or above), "
   1829                     "AMD Athlon or above)\n");
   1830         VG_(printf)("   * AMD Athlon64/Opteron\n");
   1831         VG_(printf)("   * ARM (armv7)\n");
   1832         VG_(printf)("   * PowerPC (most; ppc405 and above)\n");
   1833         VG_(printf)("   * System z (64bit only - s390x; z990 and above)\n");
   1834         VG_(printf)("\n");
   1835         VG_(exit)(1);
   1836      }
   1837      VG_(machine_get_VexArchInfo)( &vex_arch, &vex_archinfo );
   1838      VG_(debugLog)(
   1839         1, "main", "... arch = %s, hwcaps = %s\n",
   1840            LibVEX_ppVexArch   ( vex_arch ),
   1841            LibVEX_ppVexHwCaps ( vex_arch, vex_archinfo.hwcaps )
   1842      );
   1843    }
   1844 
   1845    //--------------------------------------------------------------
   1846    // Record the working directory at startup
   1847    //   p: none
   1848    VG_(debugLog)(1, "main", "Getting the working directory at startup\n");
   1849    { Bool ok = VG_(record_startup_wd)();
   1850      if (!ok)
   1851         VG_(err_config_error)( "Can't establish current working "
   1852                                "directory at startup\n");
   1853    }
   1854    VG_(debugLog)(1, "main", "... %s\n", VG_(get_startup_wd)() );
   1855 
   1856    //============================================================
   1857    // Command line argument handling order:
   1858    // * If --help/--help-debug are present, show usage message
   1859    //   (including the tool-specific usage)
   1860    // * (If no --tool option given, default to Memcheck)
   1861    // * Then, if client is missing, abort with error msg
   1862    // * Then, if any cmdline args are bad, abort with error msg
   1863    //============================================================
   1864 
   1865    //--------------------------------------------------------------
   1866    // Split up argv into: C args, V args, V extra args, and exename.
   1867    //   p: dynamic memory allocation
   1868    //--------------------------------------------------------------
   1869    VG_(debugLog)(1, "main", "Split up command line\n");
   1870    VG_(split_up_argv)( argc, argv );
   1871    vg_assert( VG_(args_for_valgrind) );
   1872    vg_assert( VG_(args_for_client) );
   1873    if (0) {
   1874       for (i = 0; i < VG_(sizeXA)( VG_(args_for_valgrind) ); i++)
   1875          VG_(printf)(
   1876             "varg %s\n",
   1877             * (HChar**) VG_(indexXA)( VG_(args_for_valgrind), i )
   1878          );
   1879       VG_(printf)(" exe %s\n", VG_(args_the_exename));
   1880       for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++)
   1881          VG_(printf)(
   1882             "carg %s\n",
   1883             * (HChar**) VG_(indexXA)( VG_(args_for_client), i )
   1884          );
   1885    }
   1886 
   1887    //--------------------------------------------------------------
   1888    // Extract tool name and whether help has been requested.
   1889    // Note we can't print the help message yet, even if requested,
   1890    // because the tool has not been initialised.
   1891    //   p: split_up_argv [for VG_(args_for_valgrind)]
   1892    //--------------------------------------------------------------
   1893    VG_(debugLog)(1, "main",
   1894                     "(early_) Process Valgrind's command line options\n");
   1895    early_process_cmd_line_options(&need_help, &toolname);
   1896 
   1897    // BEGIN HACK
   1898    vg_assert(toolname != NULL);
   1899    vg_assert(VG_(clo_read_inline_info) == False);
   1900 #  if !defined(VGO_darwin)
   1901    if (0 == VG_(strcmp)(toolname, "memcheck")
   1902        || 0 == VG_(strcmp)(toolname, "helgrind")
   1903        || 0 == VG_(strcmp)(toolname, "drd")) {
   1904       /* Change the default setting.  Later on (just below)
   1905          main_process_cmd_line_options should pick up any
   1906          user-supplied setting for it and will override the default
   1907          set here. */
   1908       VG_(clo_read_inline_info) = True;
   1909    }
   1910 #  endif
   1911    // END HACK
   1912 
   1913    // Set default vex control params.
   1914    LibVEX_default_VexControl(& VG_(clo_vex_control));
   1915 
   1916    //--------------------------------------------------------------
   1917    // Load client executable, finding in $PATH if necessary
   1918    //   p: early_process_cmd_line_options()  [for 'exec', 'need_help',
   1919    //                                         clo_max_stackframe,
   1920    //                                         clo_main_stacksize]
   1921    //   p: layout_remaining_space            [so there's space]
   1922    //
   1923    // Set up client's environment
   1924    //   p: set-libdir                     [for VG_(libdir)]
   1925    //   p: early_process_cmd_line_options [for toolname]
   1926    //
   1927    // Setup client stack, eip, and VG_(client_arg[cv])
   1928    //   p: load_client()     [for 'info']
   1929    //   p: fix_environment() [for 'env']
   1930    //
   1931    // Setup client data (brk) segment.  Initially a 1-page segment
   1932    // which abuts a shrinkable reservation.
   1933    //     p: load_client()     [for 'info' and hence VG_(brk_base)]
   1934    //
   1935    // p: _start_in_C (for zeroing out the_iicii and putting some
   1936    //    initial values into it)
   1937    //--------------------------------------------------------------
   1938    if (!need_help) {
   1939       VG_(debugLog)(1, "main", "Create initial image\n");
   1940 
   1941 #     if defined(VGO_linux) || defined(VGO_darwin) || defined(VGO_solaris)
   1942       the_iicii.argv              = argv;
   1943       the_iicii.envp              = envp;
   1944       the_iicii.toolname          = toolname;
   1945 #     else
   1946 #       error "Unknown platform"
   1947 #     endif
   1948 
   1949       /* NOTE: this call reads VG_(clo_main_stacksize). */
   1950       the_iifii = VG_(ii_create_image)( the_iicii, &vex_archinfo );
   1951    }
   1952 
   1953    //==============================================================
   1954    //
   1955    // Finished loading/setting up the client address space.
   1956    //
   1957    //==============================================================
   1958 
   1959    //--------------------------------------------------------------
   1960    // setup file descriptors
   1961    //   p: n/a
   1962    //--------------------------------------------------------------
   1963    VG_(debugLog)(1, "main", "Setup file descriptors\n");
   1964    setup_file_descriptors();
   1965 
   1966    //--------------------------------------------------------------
   1967    // create fake /proc/<pid>/cmdline and /proc/<pid>/auxv files
   1968    // and then unlink them, but hold onto the fds, so we can handr
   1969    // them out to the client when it tries to open
   1970    // /proc/<pid>/cmdline or /proc/<pid>/auxv for itself.
   1971    //   p: setup file descriptors
   1972    //   p: ii_create_image for VG_(client_auxv) setup.
   1973    //--------------------------------------------------------------
   1974    VG_(cl_cmdline_fd) = -1;
   1975    VG_(cl_auxv_fd) = -1;
   1976 #if defined(VGO_solaris)
   1977    VG_(cl_psinfo_fd) = -1;
   1978 #endif
   1979 
   1980 #if defined(VGO_linux) || defined(VGO_solaris)
   1981    if (!need_help) {
   1982       HChar  buf[50];   // large enough
   1983       HChar  buf2[VG_(mkstemp_fullname_bufsz)(sizeof buf - 1)];
   1984       Int    fd, r;
   1985 
   1986 #if defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
   1987       /* Fake /proc/<pid>/cmdline only on Linux and Solaris if supported. */
   1988       HChar  nul[1];
   1989       const HChar* exename;
   1990 
   1991       VG_(debugLog)(1, "main", "Create fake /proc/<pid>/cmdline\n");
   1992 
   1993       VG_(sprintf)(buf, "proc_%d_cmdline", VG_(getpid)());
   1994       fd = VG_(mkstemp)( buf, buf2 );
   1995       if (fd == -1)
   1996          VG_(err_config_error)("Can't create client cmdline file in %s\n", buf2);
   1997 
   1998       nul[0] = 0;
   1999       exename = VG_(args_the_exename);
   2000       VG_(write)(fd, exename, VG_(strlen)( exename ));
   2001       VG_(write)(fd, nul, 1);
   2002 
   2003       for (i = 0; i < VG_(sizeXA)( VG_(args_for_client) ); i++) {
   2004          HChar* arg = * (HChar**) VG_(indexXA)( VG_(args_for_client), i );
   2005          VG_(write)(fd, arg, VG_(strlen)( arg ));
   2006          VG_(write)(fd, nul, 1);
   2007       }
   2008 
   2009       /* Don't bother to seek the file back to the start; instead do
   2010 	 it every time a copy of it is given out (by PRE(sys_open) or
   2011 	 PRE(sys_openat)). That is probably more robust across fork() etc. */
   2012 
   2013       /* Now delete it, but hang on to the fd. */
   2014       r = VG_(unlink)( buf2 );
   2015       if (r)
   2016          VG_(err_config_error)("Can't delete client cmdline file in %s\n", buf2);
   2017 
   2018       VG_(cl_cmdline_fd) = fd;
   2019 #endif // defined(VGO_linux) || defined(SOLARIS_PROC_CMDLINE)
   2020 
   2021       /* Fake /proc/<pid>/auxv on both Linux and Solaris. */
   2022       VG_(debugLog)(1, "main", "Create fake /proc/<pid>/auxv\n");
   2023 
   2024       VG_(sprintf)(buf, "proc_%d_auxv", VG_(getpid)());
   2025       fd = VG_(mkstemp)( buf, buf2 );
   2026       if (fd == -1)
   2027          VG_(err_config_error)("Can't create client auxv file in %s\n", buf2);
   2028 
   2029       UWord *client_auxv = VG_(client_auxv);
   2030       unsigned int client_auxv_len = 0;
   2031       while (*client_auxv != 0) {
   2032          client_auxv++;
   2033          client_auxv++;
   2034          client_auxv_len += 2 * sizeof(UWord);
   2035       }
   2036       client_auxv_len += 2 * sizeof(UWord);
   2037 
   2038       VG_(write)(fd, VG_(client_auxv), client_auxv_len);
   2039 
   2040       /* Don't bother to seek the file back to the start; instead do
   2041 	 it every time a copy of it is given out (by PRE(sys_open)).
   2042 	 That is probably more robust across fork() etc. */
   2043 
   2044       /* Now delete it, but hang on to the fd. */
   2045       r = VG_(unlink)( buf2 );
   2046       if (r)
   2047          VG_(err_config_error)("Can't delete client auxv file in %s\n", buf2);
   2048 
   2049       VG_(cl_auxv_fd) = fd;
   2050 
   2051 #if defined(VGO_solaris)
   2052       /* Fake /proc/<pid>/psinfo on Solaris.
   2053        * Contents will be fetched and partially faked later on the fly. */
   2054       VG_(debugLog)(1, "main", "Create fake /proc/<pid>/psinfo\n");
   2055 
   2056       VG_(sprintf)(buf, "proc_%d_psinfo", VG_(getpid)());
   2057       fd = VG_(mkstemp)( buf, buf2 );
   2058       if (fd == -1)
   2059          VG_(err_config_error)("Can't create client psinfo file in %s\n", buf2);
   2060 
   2061       /* Now delete it, but hang on to the fd. */
   2062       r = VG_(unlink)( buf2 );
   2063       if (r)
   2064          VG_(err_config_error)("Can't delete client psinfo file in %s\n", buf2);
   2065 
   2066       VG_(cl_psinfo_fd) = fd;
   2067 #endif /* VGO_solaris */
   2068    }
   2069 #endif
   2070 
   2071    //--------------------------------------------------------------
   2072    // Init tool part 1: pre_clo_init
   2073    //   p: setup_client_stack()      [for 'VG_(client_arg[cv]']
   2074    //   p: setup_file_descriptors()  [for 'VG_(fd_xxx_limit)']
   2075    //--------------------------------------------------------------
   2076    VG_(debugLog)(1, "main", "Initialise the tool part 1 (pre_clo_init)\n");
   2077    VG_(tl_pre_clo_init)();
   2078    // Activate var info readers, if the tool asked for it:
   2079    if (VG_(needs).var_info)
   2080       VG_(clo_read_var_info) = True;
   2081 
   2082    //--------------------------------------------------------------
   2083    // If --tool and --help/--help-debug was given, now give the core+tool
   2084    // help message
   2085    //   p: early_process_cmd_line_options() [for 'need_help']
   2086    //   p: tl_pre_clo_init                  [for 'VG_(tdict).usage']
   2087    //--------------------------------------------------------------
   2088    VG_(debugLog)(1, "main", "Print help and quit, if requested\n");
   2089    if (need_help) {
   2090       usage_NORETURN(/*--help-debug?*/need_help >= 2);
   2091    }
   2092 
   2093    //--------------------------------------------------------------
   2094    // Process command line options to Valgrind + tool
   2095    //   p: setup_client_stack()      [for 'VG_(client_arg[cv]']
   2096    //   p: setup_file_descriptors()  [for 'VG_(fd_xxx_limit)']
   2097    //--------------------------------------------------------------
   2098    VG_(debugLog)(1, "main",
   2099                     "(main_) Process Valgrind's command line options, "
   2100                     "setup logging\n");
   2101    main_process_cmd_line_options ( &logging_to_fd, &xml_fname_unexpanded,
   2102                                    toolname );
   2103 
   2104    //--------------------------------------------------------------
   2105    // Zeroise the millisecond counter by doing a first read of it.
   2106    //   p: none
   2107    //--------------------------------------------------------------
   2108    (void) VG_(read_millisecond_timer)();
   2109 
   2110    //--------------------------------------------------------------
   2111    // Print the preamble
   2112    //   p: tl_pre_clo_init            [for 'VG_(details).name' and friends]
   2113    //   p: main_process_cmd_line_options()
   2114    //         [for VG_(clo_verbosity), VG_(clo_xml),
   2115    //          logging_to_fd, xml_fname_unexpanded]
   2116    //--------------------------------------------------------------
   2117    VG_(debugLog)(1, "main", "Print the preamble...\n");
   2118    print_preamble(logging_to_fd, xml_fname_unexpanded, toolname);
   2119    VG_(debugLog)(1, "main", "...finished the preamble\n");
   2120 
   2121    //--------------------------------------------------------------
   2122    // Init tool part 2: post_clo_init
   2123    //   p: setup_client_stack()      [for 'VG_(client_arg[cv]']
   2124    //   p: setup_file_descriptors()  [for 'VG_(fd_xxx_limit)']
   2125    //   p: print_preamble()          [so any warnings printed in post_clo_init
   2126    //                                 are shown after the preamble]
   2127    //--------------------------------------------------------------
   2128    VG_(debugLog)(1, "main", "Initialise the tool part 2 (post_clo_init)\n");
   2129    VG_TDICT_CALL(tool_post_clo_init);
   2130    {
   2131       /* The tool's "needs" will by now be finalised, since it has no
   2132          further opportunity to specify them.  So now sanity check
   2133          them. */
   2134       const HChar* s;
   2135       Bool  ok;
   2136       ok = VG_(sanity_check_needs)( &s );
   2137       if (!ok) {
   2138          VG_(core_panic)(s);
   2139       }
   2140    }
   2141 
   2142    //--------------------------------------------------------------
   2143    // Initialise translation table and translation cache
   2144    //   p: aspacem         [??]
   2145    //   p: tl_pre_clo_init [for 'VG_(details).avg_translation_sizeB']
   2146    //--------------------------------------------------------------
   2147    VG_(debugLog)(1, "main", "Initialise TT/TC\n");
   2148    VG_(init_tt_tc)();
   2149 
   2150    //--------------------------------------------------------------
   2151    // Initialise the redirect table.
   2152    //   p: init_tt_tc [so it can call VG_(search_transtab) safely]
   2153    //   p: aspacem [so can change ownership of sysinfo pages]
   2154    //--------------------------------------------------------------
   2155    VG_(debugLog)(1, "main", "Initialise redirects\n");
   2156    VG_(redir_initialise)();
   2157 
   2158    //--------------------------------------------------------------
   2159    // Allow GDB attach
   2160    //   p: main_process_cmd_line_options()  [for VG_(clo_wait_for_gdb)]
   2161    //--------------------------------------------------------------
   2162    /* Hook to delay things long enough so we can get the pid and
   2163       attach GDB in another shell. */
   2164    if (VG_(clo_wait_for_gdb)) {
   2165       ULong iters, q;
   2166       VG_(debugLog)(1, "main", "Wait for GDB\n");
   2167       VG_(printf)("pid=%d, entering delay loop\n", VG_(getpid)());
   2168 
   2169 #     if defined(VGP_x86_linux)
   2170       iters = 10;
   2171 #     elif defined(VGP_amd64_linux) || defined(VGP_ppc64be_linux) \
   2172          || defined(VGP_ppc64le_linux) || defined(VGP_tilegx_linux)
   2173       iters = 10;
   2174 #     elif defined(VGP_ppc32_linux)
   2175       iters = 5;
   2176 #     elif defined(VGP_arm_linux)
   2177       iters = 5;
   2178 #     elif defined(VGP_arm64_linux)
   2179       iters = 5;
   2180 #     elif defined(VGP_s390x_linux)
   2181       iters = 10;
   2182 #     elif defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
   2183       iters = 10;
   2184 #     elif defined(VGO_darwin)
   2185       iters = 3;
   2186 #     elif defined(VGO_solaris)
   2187       iters = 10;
   2188 #     else
   2189 #       error "Unknown plat"
   2190 #     endif
   2191 
   2192       iters *= 1000ULL * 1000 * 1000;
   2193       for (q = 0; q < iters; q++)
   2194          __asm__ __volatile__("" ::: "memory","cc");
   2195    }
   2196 
   2197    //--------------------------------------------------------------
   2198    // Search for file descriptors that are inherited from our parent
   2199    //   p: main_process_cmd_line_options  [for VG_(clo_track_fds)]
   2200    //--------------------------------------------------------------
   2201    if (VG_(clo_track_fds)) {
   2202       VG_(debugLog)(1, "main", "Init preopened fds\n");
   2203       VG_(init_preopened_fds)();
   2204    }
   2205 
   2206 #if defined(VGO_solaris)
   2207    VG_(syswrap_init)();
   2208 #endif
   2209 
   2210    //--------------------------------------------------------------
   2211    // Load debug info for the existing segments.
   2212    //   p: setup_code_redirect_table [so that redirs can be recorded]
   2213    //   p: mallocfree
   2214    //   p: probably: setup fds and process CLOs, so that logging works
   2215    //   p: initialise m_debuginfo
   2216    //
   2217    // While doing this, make a note of the debuginfo-handles that
   2218    // come back from VG_(di_notify_mmap).
   2219    // Later, in "Tell the tool about the initial client memory permissions"
   2220    // (just below) we can then hand these handles off to the tool in
   2221    // calls to VG_TRACK(new_mem_startup, ...).  This gives the tool the
   2222    // opportunity to make further queries to m_debuginfo before the
   2223    // client is started, if it wants.  We put this information into an
   2224    // XArray, each handle along with the associated segment start address,
   2225    // and search the XArray for the handles later, when calling
   2226    // VG_TRACK(new_mem_startup, ...).
   2227    //--------------------------------------------------------------
   2228    VG_(debugLog)(1, "main", "Load initial debug info\n");
   2229 
   2230    vg_assert(!addr2dihandle);
   2231    addr2dihandle = VG_(newXA)( VG_(malloc), "main.vm.2",
   2232                                VG_(free), sizeof(Addr_n_ULong) );
   2233 
   2234 #  if defined(VGO_linux) || defined(VGO_solaris)
   2235    { Addr* seg_starts;
   2236      Int   n_seg_starts;
   2237      Addr_n_ULong anu;
   2238 
   2239      seg_starts = VG_(get_segment_starts)( SkFileC | SkFileV, &n_seg_starts );
   2240      vg_assert(seg_starts && n_seg_starts >= 0);
   2241 
   2242      /* show them all to the debug info reader.  allow_SkFileV has to
   2243         be True here so that we read info from the valgrind executable
   2244         itself. */
   2245      for (i = 0; i < n_seg_starts; i++) {
   2246         anu.ull = VG_(di_notify_mmap)( seg_starts[i], True/*allow_SkFileV*/,
   2247                                        -1/*Don't use_fd*/);
   2248         /* anu.ull holds the debuginfo handle returned by di_notify_mmap,
   2249            if any. */
   2250         if (anu.ull > 0) {
   2251            anu.a = seg_starts[i];
   2252            VG_(addToXA)( addr2dihandle, &anu );
   2253         }
   2254      }
   2255 
   2256      VG_(free)( seg_starts );
   2257    }
   2258 #  elif defined(VGO_darwin)
   2259    { Addr* seg_starts;
   2260      Int   n_seg_starts;
   2261      seg_starts = VG_(get_segment_starts)( SkFileC, &n_seg_starts );
   2262      vg_assert(seg_starts && n_seg_starts >= 0);
   2263 
   2264      /* show them all to the debug info reader.
   2265         Don't read from V segments (unlike Linux) */
   2266      // GrP fixme really?
   2267      for (i = 0; i < n_seg_starts; i++) {
   2268         VG_(di_notify_mmap)( seg_starts[i], False/*don't allow_SkFileV*/,
   2269                              -1/*don't use_fd*/);
   2270      }
   2271 
   2272      VG_(free)( seg_starts );
   2273    }
   2274 #  else
   2275 #    error Unknown OS
   2276 #  endif
   2277 
   2278    //--------------------------------------------------------------
   2279    // Tell aspacem of ownership change of the asm helpers, so that
   2280    // m_translate allows them to be translated.  However, only do this
   2281    // after the initial debug info read, since making a hole in the
   2282    // address range for the stage2 binary confuses the debug info reader.
   2283    //   p: aspacem
   2284    //--------------------------------------------------------------
   2285    { Bool change_ownership_v_c_OK;
   2286      Addr co_start   = VG_PGROUNDDN( (Addr)&VG_(trampoline_stuff_start) );
   2287      Addr co_endPlus = VG_PGROUNDUP( (Addr)&VG_(trampoline_stuff_end) );
   2288      VG_(debugLog)(1,"redir",
   2289                      "transfer ownership V -> C of 0x%llx .. 0x%llx\n",
   2290                      (ULong)co_start, (ULong)co_endPlus-1 );
   2291 
   2292      change_ownership_v_c_OK
   2293         = VG_(am_change_ownership_v_to_c)( co_start, co_endPlus - co_start );
   2294      vg_assert(change_ownership_v_c_OK);
   2295    }
   2296 
   2297    if (VG_(clo_xml)) {
   2298       HChar buf[50];    // large enough
   2299       VG_(elapsed_wallclock_time)(buf, sizeof buf);
   2300       VG_(printf_xml)( "<status>\n"
   2301                        "  <state>RUNNING</state>\n"
   2302                        "  <time>%pS</time>\n"
   2303                        "</status>\n",
   2304                        buf );
   2305       VG_(printf_xml)( "\n" );
   2306    }
   2307 
   2308    VG_(init_Threads)();
   2309 
   2310    //--------------------------------------------------------------
   2311    // Initialise the scheduler (phase 1) [generates tid_main]
   2312    //   p: none, afaics
   2313    //--------------------------------------------------------------
   2314    VG_(debugLog)(1, "main", "Initialise scheduler (phase 1)\n");
   2315    tid_main = VG_(scheduler_init_phase1)();
   2316    vg_assert(tid_main >= 0 && tid_main < VG_N_THREADS
   2317              && tid_main != VG_INVALID_THREADID);
   2318    /* Tell the tool about tid_main */
   2319    VG_TRACK( pre_thread_ll_create, VG_INVALID_THREADID, tid_main );
   2320 
   2321    //--------------------------------------------------------------
   2322    // Tell the tool about the initial client memory permissions
   2323    //   p: aspacem
   2324    //   p: mallocfree
   2325    //   p: setup_client_stack
   2326    //   p: setup_client_dataseg
   2327    //
   2328    // For each segment we tell the client about, look up in
   2329    // addr2dihandle as created above, to see if there's a debuginfo
   2330    // handle associated with the segment, that we can hand along
   2331    // to the tool, to be helpful.
   2332    //--------------------------------------------------------------
   2333    VG_(debugLog)(1, "main", "Tell tool about initial permissions\n");
   2334    { Addr*     seg_starts;
   2335      Int       n_seg_starts;
   2336 
   2337      vg_assert(addr2dihandle);
   2338 
   2339      /* Mark the main thread as running while we tell the tool about
   2340         the client memory so that the tool can associate that memory
   2341         with the main thread. */
   2342      vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
   2343      VG_(running_tid) = tid_main;
   2344 
   2345      seg_starts = VG_(get_segment_starts)( SkFileC | SkAnonC | SkShmC,
   2346                                            &n_seg_starts );
   2347      vg_assert(seg_starts && n_seg_starts >= 0);
   2348 
   2349      /* Show client segments to the tool */
   2350      for (i = 0; i < n_seg_starts; i++) {
   2351         Word j, n;
   2352         NSegment const* seg
   2353            = VG_(am_find_nsegment)( seg_starts[i] );
   2354         vg_assert(seg);
   2355         vg_assert(seg->kind == SkFileC || seg->kind == SkAnonC ||
   2356                   seg->kind == SkShmC);
   2357         vg_assert(seg->start == seg_starts[i]);
   2358         {
   2359            VG_(debugLog)(2, "main",
   2360                             "tell tool about %010lx-%010lx %c%c%c\n",
   2361                              seg->start, seg->end,
   2362                              seg->hasR ? 'r' : '-',
   2363                              seg->hasW ? 'w' : '-',
   2364                              seg->hasX ? 'x' : '-' );
   2365            /* search addr2dihandle to see if we have an entry
   2366               matching seg->start. */
   2367            n = VG_(sizeXA)( addr2dihandle );
   2368            for (j = 0; j < n; j++) {
   2369               Addr_n_ULong* anl = VG_(indexXA)( addr2dihandle, j );
   2370               if (anl->a == seg->start) {
   2371                   vg_assert(anl->ull > 0); /* check it's a valid handle */
   2372                   break;
   2373               }
   2374            }
   2375            vg_assert(j >= 0 && j <= n);
   2376            VG_TRACK( new_mem_startup, seg->start, seg->end+1-seg->start,
   2377                      seg->hasR, seg->hasW, seg->hasX,
   2378                      /* and the retrieved debuginfo handle, if any */
   2379                      j < n
   2380                      ? ((Addr_n_ULong*)VG_(indexXA)( addr2dihandle, j ))->ull
   2381                         : 0 );
   2382         }
   2383      }
   2384 
   2385      VG_(free)( seg_starts );
   2386      VG_(deleteXA)( addr2dihandle );
   2387 
   2388      /* Also do the initial stack permissions. */
   2389      {
   2390        SSizeT inaccessible_len;
   2391        NSegment const* seg
   2392           = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
   2393        vg_assert(seg);
   2394        vg_assert(seg->kind == SkAnonC);
   2395        vg_assert(the_iifii.initial_client_SP >= seg->start);
   2396        vg_assert(the_iifii.initial_client_SP <= seg->end);
   2397 
   2398        /* Stuff below the initial SP is unaddressable.  Take into
   2399 	  account any ABI-mandated space below the stack pointer that
   2400 	  is required (VG_STACK_REDZONE_SZB).  setup_client_stack()
   2401 	  will have allocated an extra page if a red zone is required,
   2402 	  to be on the safe side. */
   2403        inaccessible_len = the_iifii.initial_client_SP - VG_STACK_REDZONE_SZB
   2404                           - seg->start;
   2405        vg_assert(inaccessible_len >= 0);
   2406        if (inaccessible_len > 0)
   2407           VG_TRACK( die_mem_stack,
   2408                     seg->start,
   2409                     inaccessible_len );
   2410        VG_(debugLog)(2, "main", "mark stack inaccessible %010lx-%010lx\n",
   2411                         seg->start,
   2412                         the_iifii.initial_client_SP-1 - VG_STACK_REDZONE_SZB);
   2413      }
   2414 
   2415      /* Also the assembly helpers. */
   2416      VG_TRACK( new_mem_startup,
   2417                (Addr)&VG_(trampoline_stuff_start),
   2418                (Addr)&VG_(trampoline_stuff_end)
   2419                   - (Addr)&VG_(trampoline_stuff_start),
   2420                False, /* readable? */
   2421                False, /* writable? */
   2422                True   /* executable? */,
   2423                0 /* di_handle: no associated debug info */ );
   2424 
   2425      /* Clear the running thread indicator */
   2426      VG_(running_tid) = VG_INVALID_THREADID;
   2427      vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
   2428 
   2429      /* Darwin only: tell the tools where the client's kernel commpage
   2430         is.  It would be better to do this by telling aspacemgr about
   2431         it -- see the now disused record_system_memory() in
   2432         initimg-darwin.c -- but that causes the sync checker to fail,
   2433         since the mapping doesn't appear in the kernel-supplied
   2434         process map.  So do it here instead. */
   2435 #    if defined(VGP_amd64_darwin)
   2436      VG_TRACK( new_mem_startup,
   2437                0x7fffffe00000, 0x7ffffffff000-0x7fffffe00000,
   2438                True, False, True, /* r-x */
   2439                0 /* di_handle: no associated debug info */ );
   2440 #    elif defined(VGP_x86_darwin)
   2441      VG_TRACK( new_mem_startup,
   2442                0xfffec000, 0xfffff000-0xfffec000,
   2443                True, False, True, /* r-x */
   2444                0 /* di_handle: no associated debug info */ );
   2445 #    endif
   2446    }
   2447 
   2448    //--------------------------------------------------------------
   2449    // Initialise the scheduler (phase 2)
   2450    //   p: Initialise the scheduler (phase 1) [for tid_main]
   2451    //   p: setup_file_descriptors() [else VG_(safe_fd)() breaks]
   2452    //   p: setup_client_stack
   2453    //--------------------------------------------------------------
   2454    VG_(debugLog)(1, "main", "Initialise scheduler (phase 2)\n");
   2455    { NSegment const* seg
   2456         = VG_(am_find_nsegment)( the_iifii.initial_client_SP );
   2457      vg_assert(seg);
   2458      vg_assert(seg->kind == SkAnonC);
   2459      vg_assert(the_iifii.initial_client_SP >= seg->start);
   2460      vg_assert(the_iifii.initial_client_SP <= seg->end);
   2461      VG_(scheduler_init_phase2)( tid_main,
   2462                                  seg->end, the_iifii.clstack_max_size );
   2463    }
   2464 
   2465    //--------------------------------------------------------------
   2466    // Set up state for the root thread
   2467    //   p: ?
   2468    //      setup_scheduler()      [for sched-specific thread 1 stuff]
   2469    //      VG_(ii_create_image)   [for 'the_iicii' initial info]
   2470    //--------------------------------------------------------------
   2471    VG_(debugLog)(1, "main", "Finalise initial image\n");
   2472    { /* Mark the main thread as running while we tell the tool about
   2473         the client memory which could be tracked during initial image
   2474         finalisation. So the tool can associate that memory with the
   2475         main thread. */
   2476      vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
   2477      VG_(running_tid) = tid_main;
   2478 
   2479      VG_(ii_finalise_image)( the_iifii );
   2480 
   2481      /* Clear the running thread indicator */
   2482      VG_(running_tid) = VG_INVALID_THREADID;
   2483      vg_assert(VG_(running_tid) == VG_INVALID_THREADID);
   2484    }
   2485 
   2486    //--------------------------------------------------------------
   2487    // Initialise the signal handling subsystem
   2488    //   p: n/a
   2489    //--------------------------------------------------------------
   2490    // Nb: temporarily parks the saved blocking-mask in saved_sigmask.
   2491    VG_(debugLog)(1, "main", "Initialise signal management\n");
   2492    /* Check that the kernel-interface signal definitions look sane */
   2493    VG_(vki_do_initial_consistency_checks)();
   2494    /* .. and go on to use them. */
   2495    VG_(sigstartup_actions)();
   2496 
   2497    //--------------------------------------------------------------
   2498    // Read suppression file
   2499    //   p: main_process_cmd_line_options()  [for VG_(clo_suppressions)]
   2500    //--------------------------------------------------------------
   2501    if (VG_(needs).core_errors || VG_(needs).tool_errors) {
   2502       VG_(debugLog)(1, "main", "Load suppressions\n");
   2503       VG_(load_suppressions)();
   2504    }
   2505 
   2506    //--------------------------------------------------------------
   2507    // register client stack
   2508    //--------------------------------------------------------------
   2509    VG_(clstk_id) = VG_(register_stack)(VG_(clstk_start_base), VG_(clstk_end));
   2510 
   2511    //--------------------------------------------------------------
   2512    // Show the address space state so far
   2513    //--------------------------------------------------------------
   2514    VG_(debugLog)(1, "main", "\n");
   2515    VG_(debugLog)(1, "main", "\n");
   2516    VG_(am_show_nsegments)(1,"Memory layout at client startup");
   2517    VG_(debugLog)(1, "main", "\n");
   2518    VG_(debugLog)(1, "main", "\n");
   2519 
   2520    //--------------------------------------------------------------
   2521    // Run!
   2522    //--------------------------------------------------------------
   2523    VG_(debugLog)(1, "main", "Running thread 1\n");
   2524 
   2525    /* As a result of the following call, the last thread standing
   2526       eventually winds up running shutdown_actions_NORETURN
   2527       just below.  Unfortunately, simply exporting said function
   2528       causes m_main to be part of a module cycle, which is pretty
   2529       nonsensical.  So instead of doing that, the address of said
   2530       function is stored in a global variable 'owned' by m_syswrap,
   2531       and it uses that function pointer to get back here when it needs
   2532       to. */
   2533 
   2534    /* Set continuation address. */
   2535    VG_(address_of_m_main_shutdown_actions_NORETURN)
   2536       = & shutdown_actions_NORETURN;
   2537 
   2538    /* Run the first thread, eventually ending up at the continuation
   2539       address. */
   2540    VG_(main_thread_wrapper_NORETURN)(1);
   2541 
   2542    /*NOTREACHED*/
   2543    vg_assert(0);
   2544 }
   2545 
   2546 /* Do everything which needs doing when the last thread exits or when
   2547    a thread exits requesting a complete process exit.
   2548 
   2549    We enter here holding The Lock.  For the case VgSrc_ExitProcess we
   2550    must never release it, because to do so would allow other threads
   2551    to continue after the system is ostensibly shut down.  So we must
   2552    go to our grave, so to speak, holding the lock.
   2553 
   2554    In fact, there is never any point in releasing the lock at this
   2555    point - we have it, we're shutting down the entire system, and
   2556    for the case VgSrc_ExitProcess doing so positively causes trouble.
   2557    So don't.
   2558 
   2559    The final_tidyup call makes a bit of a nonsense of the ExitProcess
   2560    case, since it will run the libc_freeres function, thus allowing
   2561    other lurking threads to run again.  Hmm. */
   2562 
   2563 static
   2564 void shutdown_actions_NORETURN( ThreadId tid,
   2565                                 VgSchedReturnCode tids_schedretcode )
   2566 {
   2567    VG_(debugLog)(1, "main", "entering VG_(shutdown_actions_NORETURN)\n");
   2568    VG_(am_show_nsegments)(1,"Memory layout at client shutdown");
   2569 
   2570    vg_assert(VG_(is_running_thread)(tid));
   2571    vg_assert(tids_schedretcode == VgSrc_ExitThread
   2572 	     || tids_schedretcode == VgSrc_ExitProcess
   2573              || tids_schedretcode == VgSrc_FatalSig );
   2574 
   2575    if (tids_schedretcode == VgSrc_ExitThread) {
   2576 
   2577       // We are the last surviving thread.  Right?
   2578       vg_assert( VG_(count_living_threads)() == 1 );
   2579 
   2580       // Wait for all other threads to exit.
   2581       // jrs: Huh?  but they surely are already gone
   2582       VG_(reap_threads)(tid);
   2583 
   2584       // Clean the client up before the final report
   2585       // this causes the libc_freeres function to run
   2586       final_tidyup(tid);
   2587 
   2588       /* be paranoid */
   2589       vg_assert(VG_(is_running_thread)(tid));
   2590       vg_assert(VG_(count_living_threads)() == 1);
   2591 
   2592    } else {
   2593 
   2594       // We may not be the last surviving thread.  However, we
   2595       // want to shut down the entire process.  We hold the lock
   2596       // and we need to keep hold of it all the way out, in order
   2597       // that none of the other threads ever run again.
   2598       vg_assert( VG_(count_living_threads)() >= 1 );
   2599 
   2600       // Clean the client up before the final report
   2601       // this causes the libc_freeres function to run
   2602       // perhaps this is unsafe, as per comment above
   2603       final_tidyup(tid);
   2604 
   2605       /* be paranoid */
   2606       vg_assert(VG_(is_running_thread)(tid));
   2607       vg_assert(VG_(count_living_threads)() >= 1);
   2608    }
   2609 
   2610    /* Final call to gdbserver, if requested. */
   2611    if (VG_(gdbserver_stop_at) (VgdbStopAt_Exit)) {
   2612       VG_(umsg)("(action at exit) vgdb me ... \n");
   2613       VG_(gdbserver) (tid);
   2614    }
   2615    VG_(threads)[tid].status = VgTs_Empty;
   2616 
   2617    //--------------------------------------------------------------
   2618    // Finalisation: cleanup, messages, etc.  Order not so important, only
   2619    // affects what order the messages come.
   2620    //--------------------------------------------------------------
   2621    // First thing in the post-amble is a blank line.
   2622    if (VG_(clo_xml))
   2623       VG_(printf_xml)("\n");
   2624    else if (VG_(clo_verbosity) > 0)
   2625       VG_(message)(Vg_UserMsg, "\n");
   2626 
   2627    if (VG_(clo_xml)) {
   2628       HChar buf[50];    // large enough
   2629       VG_(elapsed_wallclock_time)(buf, sizeof buf);
   2630       VG_(printf_xml)( "<status>\n"
   2631                               "  <state>FINISHED</state>\n"
   2632                               "  <time>%pS</time>\n"
   2633                               "</status>\n"
   2634                               "\n",
   2635                               buf);
   2636    }
   2637 
   2638    /* Print out file descriptor summary and stats. */
   2639    if (VG_(clo_track_fds))
   2640       VG_(show_open_fds)("at exit");
   2641 
   2642    /* Call the tool's finalisation function.  This makes Memcheck's
   2643       leak checker run, and possibly chuck a bunch of leak errors into
   2644       the error management machinery. */
   2645    VG_TDICT_CALL(tool_fini, 0/*exitcode*/);
   2646 
   2647    /* Show the error counts. */
   2648    if (VG_(clo_xml)
   2649        && (VG_(needs).core_errors || VG_(needs).tool_errors)) {
   2650       VG_(show_error_counts_as_XML)();
   2651    }
   2652 
   2653    /* In XML mode, this merely prints the used suppressions. */
   2654    if (VG_(needs).core_errors || VG_(needs).tool_errors)
   2655       VG_(show_all_errors)(VG_(clo_verbosity), VG_(clo_xml));
   2656 
   2657    if (VG_(clo_xml)) {
   2658       VG_(printf_xml)("\n");
   2659       VG_(printf_xml)("</valgrindoutput>\n");
   2660       VG_(printf_xml)("\n");
   2661    }
   2662 
   2663    VG_(sanity_check_general)( True /*include expensive checks*/ );
   2664 
   2665    if (VG_(clo_stats))
   2666       VG_(print_all_stats)(VG_(clo_verbosity) >= 1, /* Memory stats */
   2667                            False /* tool prints stats in the tool fini */);
   2668 
   2669    /* Show a profile of the heap(s) at shutdown.  Optionally, first
   2670       throw away all the debug info, as that makes it easy to spot
   2671       leaks in the debuginfo reader. */
   2672    if (VG_(clo_profile_heap)) {
   2673       if (0) VG_(di_discard_ALL_debuginfo)();
   2674       VG_(print_arena_cc_analysis)();
   2675    }
   2676 
   2677    /* If profiling has been requested, but with zero interval, it
   2678       means "profile at the end of the run only".  In which case we
   2679       need to dump the profile now. */
   2680    if (VG_(clo_profyle_sbs) && VG_(clo_profyle_interval) == 0) {
   2681       VG_(get_and_show_SB_profile)(0/*denoting end-of-run*/);
   2682    }
   2683 
   2684    /* Print Vex storage stats */
   2685    if (0)
   2686        LibVEX_ShowAllocStats();
   2687 
   2688    /* Flush any output cached by previous calls to VG_(message). */
   2689    VG_(message_flush)();
   2690 
   2691    /* Terminate gdbserver if ever it was started. We terminate it here
   2692       so that it get the output above if output was redirected to
   2693       gdb */
   2694    VG_(gdbserver_exit) (tid, tids_schedretcode);
   2695 
   2696    /* Ok, finally exit in the os-specific way, according to the scheduler's
   2697       return code.  In short, if the (last) thread exited by calling
   2698       sys_exit, do likewise; if the (last) thread stopped due to a fatal
   2699       signal, terminate the entire system with that same fatal signal. */
   2700    VG_(debugLog)(1, "core_os",
   2701                     "VG_(terminate_NORETURN)(tid=%u)\n", tid);
   2702 
   2703    switch (tids_schedretcode) {
   2704    case VgSrc_ExitThread:  /* the normal way out (Linux, Solaris) */
   2705    case VgSrc_ExitProcess: /* the normal way out (Darwin) */
   2706       /* Change the application return code to user's return code,
   2707          if an error was found */
   2708       if (VG_(clo_error_exitcode) > 0
   2709           && VG_(get_n_errs_found)() > 0) {
   2710          VG_(client_exit)( VG_(clo_error_exitcode) );
   2711       } else {
   2712          /* otherwise, return the client's exit code, in the normal
   2713             way. */
   2714          VG_(client_exit)( VG_(threads)[tid].os_state.exitcode );
   2715       }
   2716       /* NOT ALIVE HERE! */
   2717       VG_(core_panic)("entered the afterlife in main() -- ExitT/P");
   2718       break; /* what the hell :) */
   2719 
   2720    case VgSrc_FatalSig:
   2721       /* We were killed by a fatal signal, so replicate the effect */
   2722       vg_assert(VG_(threads)[tid].os_state.fatalsig != 0);
   2723       VG_(kill_self)(VG_(threads)[tid].os_state.fatalsig);
   2724       /* we shouldn't be alive at this point.  But VG_(kill_self)
   2725          sometimes fails with EPERM on Darwin, for unclear reasons. */
   2726 #     if defined(VGO_darwin)
   2727       VG_(debugLog)(0, "main", "VG_(kill_self) failed.  Exiting normally.\n");
   2728       VG_(exit)(0); /* bogus, but we really need to exit now */
   2729       /* fall through .. */
   2730 #     endif
   2731       VG_(core_panic)("main(): signal was supposed to be fatal");
   2732       break;
   2733 
   2734    default:
   2735       VG_(core_panic)("main(): unexpected scheduler return code");
   2736    }
   2737 }
   2738 
   2739 /* -------------------- */
   2740 
   2741 /* Final clean-up before terminating the process.
   2742    Clean up the client by calling __libc_freeres() (if requested)
   2743    This is Linux-specific?
   2744    GrP fixme glibc-specific, anyway
   2745 */
   2746 static void final_tidyup(ThreadId tid)
   2747 {
   2748 #if !defined(VGO_darwin)
   2749    Addr __libc_freeres_wrapper = VG_(client___libc_freeres_wrapper);
   2750 
   2751    vg_assert(VG_(is_running_thread)(tid));
   2752 
   2753    if ( !VG_(needs).libc_freeres ||
   2754         !VG_(clo_run_libc_freeres) ||
   2755         0 == __libc_freeres_wrapper )
   2756       return;			/* can't/won't do it */
   2757 
   2758 #  if defined(VGP_ppc64be_linux)
   2759    Addr r2 = VG_(get_tocptr)( __libc_freeres_wrapper );
   2760    if (r2 == 0) {
   2761       VG_(message)(Vg_UserMsg,
   2762                    "Caught __NR_exit, but can't run __libc_freeres()\n");
   2763       VG_(message)(Vg_UserMsg,
   2764                    "   since cannot establish TOC pointer for it.\n");
   2765       return;
   2766    }
   2767 #  endif
   2768 
   2769    if (VG_(clo_verbosity) > 2  ||
   2770        VG_(clo_trace_syscalls) ||
   2771        VG_(clo_trace_sched))
   2772       VG_(message)(Vg_DebugMsg,
   2773 		   "Caught __NR_exit; running __libc_freeres()\n");
   2774 
   2775    /* set thread context to point to libc_freeres_wrapper */
   2776    /* ppc64be-linux note: __libc_freeres_wrapper gives us the real
   2777       function entry point, not a fn descriptor, so can use it
   2778       directly.  However, we need to set R2 (the toc pointer)
   2779       appropriately. */
   2780    VG_(set_IP)(tid, __libc_freeres_wrapper);
   2781 #  if defined(VGP_ppc64be_linux)
   2782    VG_(threads)[tid].arch.vex.guest_GPR2 = r2;
   2783 #  elif  defined(VGP_ppc64le_linux)
   2784    /* setting GPR2 but not really needed, GPR12 is needed */
   2785    VG_(threads)[tid].arch.vex.guest_GPR2  = __libc_freeres_wrapper;
   2786    VG_(threads)[tid].arch.vex.guest_GPR12 = __libc_freeres_wrapper;
   2787 #  endif
   2788    /* mips-linux note: we need to set t9 */
   2789 #  if defined(VGP_mips32_linux) || defined(VGP_mips64_linux)
   2790    VG_(threads)[tid].arch.vex.guest_r25 = __libc_freeres_wrapper;
   2791 #  endif
   2792 
   2793    /* Block all blockable signals by copying the real block state into
   2794       the thread's block state*/
   2795    VG_(sigprocmask)(VKI_SIG_BLOCK, NULL, &VG_(threads)[tid].sig_mask);
   2796    VG_(threads)[tid].tmp_sig_mask = VG_(threads)[tid].sig_mask;
   2797 
   2798    /* and restore handlers to default */
   2799    VG_(set_default_handler)(VKI_SIGSEGV);
   2800    VG_(set_default_handler)(VKI_SIGBUS);
   2801    VG_(set_default_handler)(VKI_SIGILL);
   2802    VG_(set_default_handler)(VKI_SIGFPE);
   2803 
   2804    // We were exiting, so assert that...
   2805    vg_assert(VG_(is_exiting)(tid));
   2806    // ...but now we're not again
   2807    VG_(threads)[tid].exitreason = VgSrc_None;
   2808 
   2809    // run until client thread exits - ideally with LIBC_FREERES_DONE,
   2810    // but exit/exitgroup/signal will do
   2811    VG_(scheduler)(tid);
   2812 
   2813    vg_assert(VG_(is_exiting)(tid));
   2814 #endif
   2815 }
   2816 
   2817 
   2818 /*====================================================================*/
   2819 /*=== Getting to main() alive: LINUX                               ===*/
   2820 /*====================================================================*/
   2821 
   2822 #if defined(VGO_linux)
   2823 
   2824 /* If linking of the final executables is done with glibc present,
   2825    then Valgrind starts at main() above as usual, and all of the
   2826    following code is irrelevant.
   2827 
   2828    However, this is not the intended mode of use.  The plan is to
   2829    avoid linking against glibc, by giving gcc the flags
   2830    -nodefaultlibs -lgcc -nostartfiles at startup.
   2831 
   2832    From this derive two requirements:
   2833 
   2834    1. gcc may emit calls to memcpy, memmove and memset to deal with
   2835       structure assignments etc.  Since we have chosen to ignore all the
   2836       "normal" supporting libraries, we have to provide our own
   2837       implementations of them.  No problem.
   2838 
   2839    2. We have to provide a symbol "_start", to which the kernel
   2840       hands control at startup.  Hence the code below.
   2841 */
   2842 
   2843 /* ---------------- Requirement 1 ---------------- */
   2844 
   2845 void* memcpy(void *dest, const void *src, SizeT n);
   2846 void* memcpy(void *dest, const void *src, SizeT n) {
   2847    return VG_(memcpy)(dest,src,n);
   2848 }
   2849 void* memmove(void *dest, const void *src, SizeT n);
   2850 void* memmove(void *dest, const void *src, SizeT n) {
   2851    return VG_(memmove)(dest,src,n);
   2852 }
   2853 void* memset(void *s, int c, SizeT n);
   2854 void* memset(void *s, int c, SizeT n) {
   2855   return VG_(memset)(s,c,n);
   2856 }
   2857 
   2858 /* BVA: abort() for those platforms that need it (PPC and ARM). */
   2859 void abort(void);
   2860 void abort(void){
   2861    VG_(printf)("Something called raise().\n");
   2862    vg_assert(0);
   2863 }
   2864 
   2865 /* EAZG: ARM's EABI will call floating point exception handlers in
   2866    libgcc which boil down to an abort or raise, that's usually defined
   2867    in libc. Instead, define them here. */
   2868 #if defined(VGP_arm_linux)
   2869 void raise(void);
   2870 void raise(void){
   2871    VG_(printf)("Something called raise().\n");
   2872    vg_assert(0);
   2873 }
   2874 
   2875 void __aeabi_unwind_cpp_pr0(void);
   2876 void __aeabi_unwind_cpp_pr0(void){
   2877    VG_(printf)("Something called __aeabi_unwind_cpp_pr0()\n");
   2878    vg_assert(0);
   2879 }
   2880 
   2881 void __aeabi_unwind_cpp_pr1(void);
   2882 void __aeabi_unwind_cpp_pr1(void){
   2883    VG_(printf)("Something called __aeabi_unwind_cpp_pr1()\n");
   2884    vg_assert(0);
   2885 }
   2886 #endif
   2887 
   2888 /* ---------------- Requirement 2 ---------------- */
   2889 
   2890 /* Glibc's sysdeps/i386/elf/start.S has the following gem of a
   2891    comment, which explains how the stack looks right at process start
   2892    (when _start is jumped to).  Hence _start passes %esp to
   2893    _start_in_C_linux, which extracts argc/argv/envp and starts up
   2894    correctly. */
   2895 
   2896 /* This is the canonical entry point, usually the first thing in the text
   2897    segment.  The SVR4/i386 ABI (pages 3-31, 3-32) says that when the entry
   2898    point runs, most registers' values are unspecified, except for:
   2899 
   2900    %edx         Contains a function pointer to be registered with `atexit'.
   2901                 This is how the dynamic linker arranges to have DT_FINI
   2902                 functions called for shared libraries that have been loaded
   2903                 before this code runs.
   2904 
   2905    %esp         The stack contains the arguments and environment:
   2906                 0(%esp)                 argc
   2907                 4(%esp)                 argv[0]
   2908                 ...
   2909                 (4*argc)(%esp)          NULL
   2910                 (4*(argc+1))(%esp)      envp[0]
   2911                 ...
   2912                                         NULL
   2913 */
   2914 
   2915 /* The kernel hands control to _start, which extracts the initial
   2916    stack pointer and calls onwards to _start_in_C_linux.  This also switches
   2917    the new stack.  */
   2918 #if defined(VGP_x86_linux)
   2919 asm("\n"
   2920     ".text\n"
   2921     "\t.globl _start\n"
   2922     "\t.type _start,@function\n"
   2923     "_start:\n"
   2924     /* set up the new stack in %eax */
   2925     "\tmovl  $vgPlain_interim_stack, %eax\n"
   2926     "\taddl  $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
   2927     "\taddl  $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %eax\n"
   2928     "\tsubl  $16, %eax\n"
   2929     "\tandl  $~15, %eax\n"
   2930     /* install it, and collect the original one */
   2931     "\txchgl %eax, %esp\n"
   2932     /* call _start_in_C_linux, passing it the startup %esp */
   2933     "\tpushl %eax\n"
   2934     "\tcall  _start_in_C_linux\n"
   2935     "\thlt\n"
   2936     ".previous\n"
   2937 );
   2938 #elif defined(VGP_amd64_linux)
   2939 asm("\n"
   2940     ".text\n"
   2941     "\t.globl _start\n"
   2942     "\t.type _start,@function\n"
   2943     "_start:\n"
   2944     /* set up the new stack in %rdi */
   2945     "\tmovq  $vgPlain_interim_stack, %rdi\n"
   2946     "\taddq  $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
   2947     "\taddq  $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %rdi\n"
   2948     "\tandq  $~15, %rdi\n"
   2949     /* install it, and collect the original one */
   2950     "\txchgq %rdi, %rsp\n"
   2951     /* call _start_in_C_linux, passing it the startup %rsp */
   2952     "\tcall  _start_in_C_linux\n"
   2953     "\thlt\n"
   2954     ".previous\n"
   2955 );
   2956 #elif defined(VGP_ppc32_linux)
   2957 asm("\n"
   2958     ".text\n"
   2959     "\t.globl _start\n"
   2960     "\t.type _start,@function\n"
   2961     "_start:\n"
   2962     /* set up the new stack in r16 */
   2963     "\tlis 16,vgPlain_interim_stack@ha\n"
   2964     "\tla  16,vgPlain_interim_stack@l(16)\n"
   2965     "\tlis    17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
   2966     "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
   2967     "\tlis    18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" >> 16)\n"
   2968     "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
   2969     "\tadd 16,17,16\n"
   2970     "\tadd 16,18,16\n"
   2971     "\trlwinm 16,16,0,0,27\n"
   2972     /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   2973        VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   2974        boundary.  And r1 is the original SP.  Set the SP to r16 and
   2975        call _start_in_C_linux, passing it the initial SP. */
   2976     "\tmr 3,1\n"
   2977     "\tmr 1,16\n"
   2978     "\tbl _start_in_C_linux\n"
   2979     "\ttrap\n"
   2980     ".previous\n"
   2981 );
   2982 #elif defined(VGP_ppc64be_linux)
   2983 asm("\n"
   2984     /* PPC64 ELF ABI says '_start' points to a function descriptor.
   2985        So we must have one, and that is what goes into the .opd section. */
   2986     "\t.align 2\n"
   2987     "\t.global _start\n"
   2988     "\t.section \".opd\",\"aw\"\n"
   2989     "\t.align 3\n"
   2990     "_start:\n"
   2991     "\t.quad ._start,.TOC.@tocbase,0\n"
   2992     "\t.previous\n"
   2993     "\t.type ._start,@function\n"
   2994     "\t.global  ._start\n"
   2995     "._start:\n"
   2996     /* set up the new stack in r16 */
   2997     "\tlis  16,   vgPlain_interim_stack@highest\n"
   2998     "\tori  16,16,vgPlain_interim_stack@higher\n"
   2999     "\tsldi 16,16,32\n"
   3000     "\toris 16,16,vgPlain_interim_stack@h\n"
   3001     "\tori  16,16,vgPlain_interim_stack@l\n"
   3002     "\txor  17,17,17\n"
   3003     "\tlis    17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
   3004     "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
   3005     "\txor 18,18,18\n"
   3006     "\tlis    18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" >> 16)\n"
   3007     "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
   3008     "\tadd 16,17,16\n"
   3009     "\tadd 16,18,16\n"
   3010     "\trldicr 16,16,0,59\n"
   3011     /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   3012        VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   3013        boundary.  And r1 is the original SP.  Set the SP to r16 and
   3014        call _start_in_C_linux, passing it the initial SP. */
   3015     "\tmr 3,1\n"
   3016     "\tmr 1,16\n"
   3017     "\tlis  14,   _start_in_C_linux@highest\n"
   3018     "\tori  14,14,_start_in_C_linux@higher\n"
   3019     "\tsldi 14,14,32\n"
   3020     "\toris 14,14,_start_in_C_linux@h\n"
   3021     "\tori  14,14,_start_in_C_linux@l\n"
   3022     "\tld 14,0(14)\n"
   3023     "\tmtctr 14\n"
   3024     "\tbctrl\n"
   3025     "\tnop\n"
   3026     "\ttrap\n"
   3027 );
   3028 #elif defined(VGP_ppc64le_linux)
   3029 /* Little Endian uses ELF version 2 but in the future may also
   3030  * support other ELF versions.
   3031  */
   3032 asm("\n"
   3033     "\t.align 2\n"
   3034     "\t.global _start\n"
   3035     "\t.type _start,@function\n"
   3036     "_start:\n"
   3037     "#if _CALL_ELF == 2    \n"
   3038     "0:  addis        2,12,.TOC.-0b@ha\n"
   3039     "    addi         2,2,.TOC.-0b@l\n"
   3040     "    .localentry  _start, .-_start\n"
   3041     "#endif \n"
   3042     /* set up the new stack in r16 */
   3043     "\tlis  16,   vgPlain_interim_stack@highest\n"
   3044     "\tori  16,16,vgPlain_interim_stack@higher\n"
   3045     "\tsldi 16,16,32\n"
   3046     "\toris 16,16,vgPlain_interim_stack@h\n"
   3047     "\tori  16,16,vgPlain_interim_stack@l\n"
   3048     "\txor  17,17,17\n"
   3049     "\tlis    17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" >> 16)\n"
   3050     "\tori 17,17,("VG_STRINGIFY(VG_STACK_GUARD_SZB)" & 0xFFFF)\n"
   3051     "\txor 18,18,18\n"
   3052     "\tlis    18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" >> 16)\n"
   3053     "\tori 18,18,("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)" & 0xFFFF)\n"
   3054     "\tadd 16,17,16\n"
   3055     "\tadd 16,18,16\n"
   3056     "\trldicr 16,16,0,59\n"
   3057     /* now r16 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   3058        VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   3059        boundary.  And r1 is the original SP.  Set the SP to r16 and
   3060        call _start_in_C_linux, passing it the initial SP. */
   3061     "\tmr 3,1\n"
   3062     "\tmr 1,16\n"
   3063     "\tlis  14,   _start_in_C_linux@highest\n"
   3064     "\tori  14,14,_start_in_C_linux@higher\n"
   3065     "\tsldi 14,14,32\n"
   3066     "\toris 14,14,_start_in_C_linux@h\n"
   3067     "\tori  14,14,_start_in_C_linux@l\n"
   3068     "\tmtctr 14\n"
   3069     "\tbctrl\n"
   3070     "\tnop\n"
   3071     "\ttrap\n"
   3072 );
   3073 #elif defined(VGP_s390x_linux)
   3074 /*
   3075     This is the canonical entry point, usually the first thing in the text
   3076     segment. Most registers' values are unspecified, except for:
   3077 
   3078     %r14         Contains a function pointer to be registered with `atexit'.
   3079                  This is how the dynamic linker arranges to have DT_FINI
   3080                  functions called for shared libraries that have been loaded
   3081                  before this code runs.
   3082 
   3083     %r15         The stack contains the arguments and environment:
   3084                  0(%r15)              argc
   3085                  8(%r15)              argv[0]
   3086                  ...
   3087                  (8*argc)(%r15)       NULL
   3088                  (8*(argc+1))(%r15)   envp[0]
   3089                  ...
   3090                                       NULL
   3091 */
   3092 asm("\n\t"
   3093     ".text\n\t"
   3094     ".globl _start\n\t"
   3095     ".type  _start,@function\n\t"
   3096     "_start:\n\t"
   3097     /* set up the new stack in %r1 */
   3098     "larl   %r1,  vgPlain_interim_stack\n\t"
   3099     "larl   %r5,  1f\n\t"
   3100     "ag     %r1,  0(%r5)\n\t"
   3101     "ag     %r1,  2f-1f(%r5)\n\t"
   3102     "nill   %r1,  0xFFF0\n\t"
   3103     /* install it, and collect the original one */
   3104     "lgr    %r2,  %r15\n\t"
   3105     "lgr    %r15, %r1\n\t"
   3106     /* call _start_in_C_linux, passing it the startup %r15 */
   3107     "brasl  %r14, _start_in_C_linux\n\t"
   3108     /* trigger execution of an invalid opcode -> halt machine */
   3109     "j      .+2\n\t"
   3110     "1:   .quad "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n\t"
   3111     "2:   .quad "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)"\n\t"
   3112     ".previous\n"
   3113 );
   3114 #elif defined(VGP_arm_linux)
   3115 asm("\n"
   3116     "\t.text\n"
   3117     "\t.align 4\n"
   3118     "\t.type _start,#function\n"
   3119     "\t.global _start\n"
   3120     "_start:\n"
   3121     "\tldr  r0, [pc, #36]\n"
   3122     "\tldr  r1, [pc, #36]\n"
   3123     "\tadd  r0, r1, r0\n"
   3124     "\tldr  r1, [pc, #32]\n"
   3125     "\tadd  r0, r1, r0\n"
   3126     "\tmvn  r1, #15\n"
   3127     "\tand  r0, r0, r1\n"
   3128     "\tmov  r1, sp\n"
   3129     "\tmov  sp, r0\n"
   3130     "\tmov  r0, r1\n"
   3131     "\tb _start_in_C_linux\n"
   3132     "\t.word vgPlain_interim_stack\n"
   3133     "\t.word "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
   3134     "\t.word "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)"\n"
   3135 );
   3136 #elif defined(VGP_arm64_linux)
   3137 asm("\n"
   3138     "\t.text\n"
   3139     "\t.align 2\n"
   3140     "\t.type _start,#function\n"
   3141     "\t.global _start\n"
   3142     "_start:\n"
   3143     "\tadrp x0, vgPlain_interim_stack\n"
   3144     "\tadd  x0, x0, :lo12:vgPlain_interim_stack\n"
   3145     // The next 2 assume that VG_STACK_GUARD_SZB fits in 32 bits
   3146     "\tmov  x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB)") >> 0) & 0xFFFF\n"
   3147     "\tmovk x1, (("VG_STRINGIFY(VG_STACK_GUARD_SZB)") >> 16) & 0xFFFF,"
   3148                 " lsl 16\n"
   3149     "\tadd  x0, x0, x1\n"
   3150     // The next 2 assume that VG_DEFAULT_STACK_ACTIVE_SZB fits in 32 bits
   3151     "\tmov  x1, (("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)") >> 0) & 0xFFFF\n"
   3152     "\tmovk x1, (("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)") >> 16) & 0xFFFF,"
   3153                 " lsl 16\n"
   3154     "\tadd  x0, x0, x1\n"
   3155     "\tand  x0, x0, -16\n"
   3156     "\tmov  x1, sp\n"
   3157     "\tmov  sp, x0\n"
   3158     "\tmov  x0, x1\n"
   3159     "\tb _start_in_C_linux\n"
   3160 );
   3161 #elif defined(VGP_mips32_linux)
   3162 asm("\n"
   3163     "\t.type _gp_disp,@object\n"
   3164     ".text\n"
   3165     "\t.globl __start\n"
   3166     "\t.type __start,@function\n"
   3167     "__start:\n"
   3168 
   3169     "\tbal 1f\n"
   3170     "\tnop\n"
   3171 
   3172     "1:\n"
   3173 
   3174     "\tlui      $28, %hi(_gp_disp)\n"
   3175     "\taddiu    $28, $28, %lo(_gp_disp)\n"
   3176     "\taddu     $28, $28, $31\n"
   3177     /* t1/$9 <- Addr(interim_stack) */
   3178     "\tlui      $9, %hi(vgPlain_interim_stack)\n"
   3179     /* t1/$9 <- Addr(interim_stack) */
   3180     "\taddiu    $9, %lo(vgPlain_interim_stack)\n"
   3181 
   3182 
   3183     "\tli    $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
   3184     "\tli    $11, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)"\n"
   3185 
   3186     "\taddu     $9, $9, $10\n"
   3187     "\taddu     $9, $9, $11\n"
   3188     "\tli       $12, 0xFFFFFFF0\n"
   3189     "\tand      $9, $9, $12\n"
   3190     /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   3191        VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   3192        boundary.  And $29 is the original SP.  Set the SP to t1 and
   3193        call _start_in_C, passing it the initial SP. */
   3194 
   3195     "\tmove    $4, $29\n"     // a0 <- $sp (_start_in_C first arg)
   3196     "\tmove    $29, $9\n"     // $sp <- t1 (new sp)
   3197 
   3198     "\tlui     $25, %hi(_start_in_C_linux)\n"
   3199     "\taddiu   $25, %lo(_start_in_C_linux)\n"
   3200 
   3201     "\tbal  _start_in_C_linux\n"
   3202     "\tbreak  0x7\n"
   3203     ".previous\n"
   3204 );
   3205 #elif defined(VGP_mips64_linux)
   3206 asm(
   3207 ".text\n"
   3208 ".globl __start\n"
   3209 ".type __start,@function\n"
   3210 "__start:\n"
   3211     "\t.set noreorder\n"
   3212     "\t.cpload $25\n"
   3213     "\t.set reorder\n"
   3214     "\t.cprestore 16\n"
   3215     "\tlui    $9, %hi(vgPlain_interim_stack)\n"
   3216     /* t1/$9 <- Addr(interim_stack) */
   3217     "\tdaddiu $9, %lo(vgPlain_interim_stack)\n"
   3218 
   3219     "\tli     $10, "VG_STRINGIFY(VG_STACK_GUARD_SZB)"\n"
   3220     "\tli     $11, "VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)"\n"
   3221 
   3222     "\tdaddu  $9, $9, $10\n"
   3223     "\tdaddu  $9, $9, $11\n"
   3224     "\tli     $12, 0xFFFFFF00\n"
   3225     "\tand    $9, $9, $12\n"
   3226     /* now t1/$9 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   3227        VG_DEFAULT_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   3228        boundary.  And $29 is the original SP.  Set the SP to t1 and
   3229        call _start_in_C, passing it the initial SP. */
   3230 
   3231     "\tmove   $4, $29\n"     // a0 <- $sp (_start_in_C first arg)
   3232     "\tmove   $29, $9\n"     // $sp <- t1 (new sp)
   3233 
   3234     "\tlui    $9, %highest(_start_in_C_linux)\n"
   3235     "\tori    $9, %higher(_start_in_C_linux)\n"
   3236     "\tdsll32 $9, $9, 0x0\n"
   3237     "\tlui    $10, %hi(_start_in_C_linux)\n"
   3238     "\tdaddiu $10, %lo(_start_in_C_linux)\n"
   3239     "\tdaddu  $25, $9, $10\n"
   3240     "\tjalr   $25\n"
   3241     "\tnop\n"
   3242 ".previous\n"
   3243 );
   3244 #elif defined(VGP_tilegx_linux)
   3245 asm("\n"
   3246     ".text\n"
   3247     "\t.align 8\n"
   3248     "\t.globl _start\n"
   3249     "\t.type _start,@function\n"
   3250     "_start:\n"
   3251 
   3252     "\tjal 1f\n"
   3253     "1:\n"
   3254 
   3255     /* --FIXME, bundle them :) */
   3256     /* r19 <- Addr(interim_stack) */
   3257     "\tmoveli r19, hw2_last(vgPlain_interim_stack)\n"
   3258     "\tshl16insli r19, r19, hw1(vgPlain_interim_stack)\n"
   3259     "\tshl16insli r19, r19, hw0(vgPlain_interim_stack)\n"
   3260 
   3261     "\tmoveli r20, hw1("VG_STRINGIFY(VG_STACK_GUARD_SZB)")\n"
   3262     "\tshl16insli r20, r20, hw0("VG_STRINGIFY(VG_STACK_GUARD_SZB)")\n"
   3263     "\tmoveli r21, hw1("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)")\n"
   3264     "\tshl16insli r21, r21, hw0("VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)")\n"
   3265     "\tadd     r19, r19, r20\n"
   3266     "\tadd     r19, r19, r21\n"
   3267 
   3268     "\tmovei    r12, 0x0F\n"
   3269     "\tnor      r12, zero, r12\n"
   3270 
   3271     "\tand      r19, r19, r12\n"
   3272 
   3273     /* now r19 = &vgPlain_interim_stack + VG_STACK_GUARD_SZB +
   3274        VG_STACK_ACTIVE_SZB rounded down to the nearest 16-byte
   3275        boundary.  And $54 is the original SP.  Set the SP to r0 and
   3276        call _start_in_C, passing it the initial SP. */
   3277 
   3278     "\tmove    r0,  r54\n"    // r0  <- $sp (_start_in_C first arg)
   3279     "\tmove    r54, r19\n"    // $sp <- r19 (new sp)
   3280 
   3281     "\tjal  _start_in_C_linux\n"
   3282 );
   3283 #else
   3284 #  error "Unknown linux platform"
   3285 #endif
   3286 
   3287 /* --- !!! --- EXTERNAL HEADERS start --- !!! --- */
   3288 #define _GNU_SOURCE
   3289 #define _FILE_OFFSET_BITS 64
   3290 /* This is in order to get AT_NULL and AT_PAGESIZE. */
   3291 #include <elf.h>
   3292 /* --- !!! --- EXTERNAL HEADERS end --- !!! --- */
   3293 
   3294 /* Avoid compiler warnings: this fn _is_ used, but labelling it
   3295    'static' causes gcc to complain it isn't.
   3296    attribute 'used' also ensures the code is not eliminated at link
   3297    time */
   3298 __attribute__ ((used))
   3299 void _start_in_C_linux ( UWord* pArgc );
   3300 __attribute__ ((used))
   3301 void _start_in_C_linux ( UWord* pArgc )
   3302 {
   3303    Int     r;
   3304    Word    argc = pArgc[0];
   3305    HChar** argv = (HChar**)&pArgc[1];
   3306    HChar** envp = (HChar**)&pArgc[1+argc+1];
   3307 
   3308    // For an inner Valgrind, register the interim stack asap.
   3309    // This is needed to allow the outer valgrind to do stacktraces during init.
   3310    // Note that this stack is not unregistered when the main thread
   3311    // is switching to the (real) stack. Unregistering this would imply
   3312    // to save the stack id in a global variable, and have a "if"
   3313    // in run_a_thread_NORETURN to do the unregistration only for the
   3314    // main thread. This unregistration is not worth this complexity.
   3315    INNER_REQUEST
   3316       ((void) VALGRIND_STACK_REGISTER
   3317        (&VG_(interim_stack).bytes[0],
   3318         &VG_(interim_stack).bytes[0] + sizeof(VG_(interim_stack))));
   3319 
   3320    VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
   3321    VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
   3322 
   3323    the_iicii.sp_at_startup = (Addr)pArgc;
   3324 
   3325 #  if defined(VGP_ppc32_linux) || defined(VGP_ppc64be_linux) \
   3326       || defined(VGP_ppc64le_linux) || defined(VGP_arm64_linux)
   3327    {
   3328       /* ppc32/ppc64 can be configured with different page sizes.
   3329          Determine this early.  This is an ugly hack and really should
   3330          be moved into valgrind_main. */
   3331       UWord *sp = &pArgc[1+argc+1];
   3332       while (*sp++ != 0)
   3333          ;
   3334       for (; *sp != AT_NULL && *sp != AT_PAGESZ; sp += 2);
   3335       if (*sp == AT_PAGESZ) {
   3336          VKI_PAGE_SIZE = sp[1];
   3337          for (VKI_PAGE_SHIFT = 12;
   3338               VKI_PAGE_SHIFT <= VKI_MAX_PAGE_SHIFT; VKI_PAGE_SHIFT++)
   3339             if (VKI_PAGE_SIZE == (1UL << VKI_PAGE_SHIFT))
   3340          break;
   3341       }
   3342    }
   3343 #  endif
   3344 
   3345    r = valgrind_main( (Int)argc, argv, envp );
   3346    /* NOTREACHED */
   3347    VG_(exit)(r);
   3348 }
   3349 
   3350 
   3351 /*====================================================================*/
   3352 /*=== Getting to main() alive: darwin                              ===*/
   3353 /*====================================================================*/
   3354 
   3355 #elif defined(VGO_darwin)
   3356 
   3357 /*
   3358    Memory layout established by kernel:
   3359 
   3360    0(%esp)   argc
   3361    4(%esp)   argv[0]
   3362              ...
   3363              argv[argc-1]
   3364              NULL
   3365              envp[0]
   3366              ...
   3367              envp[n]
   3368              NULL
   3369              executable name (presumably, a pointer to it)
   3370              NULL
   3371 
   3372    Ditto in the 64-bit case, except all offsets from SP are obviously
   3373    twice as large.
   3374 */
   3375 
   3376 /* The kernel hands control to _start, which extracts the initial
   3377    stack pointer and calls onwards to _start_in_C_darwin.  This also
   3378    switches to the new stack.  */
   3379 #if defined(VGP_x86_darwin)
   3380 asm("\n"
   3381     ".text\n"
   3382     ".align 2,0x90\n"
   3383     "\t.globl __start\n"
   3384     "__start:\n"
   3385     /* set up the new stack in %eax */
   3386     "\tmovl  $_vgPlain_interim_stack, %eax\n"
   3387     "\taddl  $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
   3388     "\taddl  $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %eax\n"
   3389     "\tsubl  $16, %eax\n"
   3390     "\tandl  $~15, %eax\n"
   3391     /* install it, and collect the original one */
   3392     "\txchgl %eax, %esp\n"
   3393     "\tsubl  $12, %esp\n"  // keep stack 16 aligned; see #295428
   3394     /* call _start_in_C_darwin, passing it the startup %esp */
   3395     "\tpushl %eax\n"
   3396     "\tcall  __start_in_C_darwin\n"
   3397     "\tint $3\n"
   3398     "\tint $3\n"
   3399 );
   3400 #elif defined(VGP_amd64_darwin)
   3401 asm("\n"
   3402     ".text\n"
   3403     "\t.globl __start\n"
   3404     ".align 3,0x90\n"
   3405     "__start:\n"
   3406     /* set up the new stack in %rdi */
   3407     "\tmovabsq $_vgPlain_interim_stack, %rdi\n"
   3408     "\taddq    $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
   3409     "\taddq    $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %rdi\n"
   3410     "\tandq    $~15, %rdi\n"
   3411     /* install it, and collect the original one */
   3412     "\txchgq %rdi, %rsp\n"
   3413     /* call _start_in_C_darwin, passing it the startup %rsp */
   3414     "\tcall  __start_in_C_darwin\n"
   3415     "\tint $3\n"
   3416     "\tint $3\n"
   3417 );
   3418 #endif
   3419 
   3420 void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2);
   3421 void* __memcpy_chk(void *dest, const void *src, SizeT n, SizeT n2) {
   3422     // skip check
   3423    return VG_(memcpy)(dest,src,n);
   3424 }
   3425 void* __memset_chk(void *s, int c, SizeT n, SizeT n2);
   3426 void* __memset_chk(void *s, int c, SizeT n, SizeT n2) {
   3427     // skip check
   3428   return VG_(memset)(s,c,n);
   3429 }
   3430 void bzero(void *s, SizeT n);
   3431 void bzero(void *s, SizeT n) {
   3432     VG_(memset)(s,0,n);
   3433 }
   3434 
   3435 void* memcpy(void *dest, const void *src, SizeT n);
   3436 void* memcpy(void *dest, const void *src, SizeT n) {
   3437    return VG_(memcpy)(dest,src,n);
   3438 }
   3439 void* memset(void *s, int c, SizeT n);
   3440 void* memset(void *s, int c, SizeT n) {
   3441   return VG_(memset)(s,c,n);
   3442 }
   3443 
   3444 /* Avoid compiler warnings: this fn _is_ used, but labelling it
   3445    'static' causes gcc to complain it isn't. */
   3446 void _start_in_C_darwin ( UWord* pArgc );
   3447 void _start_in_C_darwin ( UWord* pArgc )
   3448 {
   3449    Int     r;
   3450    Int     argc = *(Int *)pArgc;  // not pArgc[0] on LP64
   3451    HChar** argv = (HChar**)&pArgc[1];
   3452    HChar** envp = (HChar**)&pArgc[1+argc+1];
   3453 
   3454    // See _start_in_C_linux
   3455    INNER_REQUEST
   3456       ((void) VALGRIND_STACK_REGISTER
   3457        (&VG_(interim_stack).bytes[0],
   3458         &VG_(interim_stack).bytes[0] + sizeof(VG_(interim_stack))));
   3459 
   3460    VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
   3461    VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
   3462 
   3463    the_iicii.sp_at_startup = (Addr)pArgc;
   3464 
   3465    r = valgrind_main( (Int)argc, argv, envp );
   3466    /* NOTREACHED */
   3467    VG_(exit)(r);
   3468 }
   3469 
   3470 /*====================================================================*/
   3471 /*=== Getting to main() alive: Solaris                             ===*/
   3472 /*====================================================================*/
   3473 #elif defined(VGO_solaris)
   3474 #if defined(VGP_x86_solaris)
   3475 /* The kernel hands control to _start, which extracts the initial stack
   3476    pointer and calls onwards to _start_in_C_solaris.  This also switches to
   3477    the new stack. */
   3478 asm("\n"
   3479     "\t.text\n"
   3480     "\t.globl _start\n"
   3481     "\t.type _start, @function\n"
   3482     "_start:\n"
   3483     /* Set up the new stack in %eax. */
   3484     "\tmovl  $vgPlain_interim_stack, %eax\n"
   3485     "\taddl  $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %eax\n"
   3486     "\taddl  $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %eax\n"
   3487     "\tandl  $~15, %eax\n"
   3488     /* Install it, and collect the original one. */
   3489     "\txchgl %eax, %esp\n"
   3490     "\tsubl  $12, %esp\n"  /* Keep stack 16-byte aligned. */
   3491     /* Call _start_in_C_solaris, passing it the startup %esp. */
   3492     "\tpushl %eax\n"
   3493     "\tcall  _start_in_C_solaris\n"
   3494     /* NOTREACHED */
   3495     "\thlt\n"
   3496     "\t.previous\n"
   3497 );
   3498 #elif defined(VGP_amd64_solaris)
   3499 asm("\n"
   3500     ".text\n"
   3501     "\t.globl _start\n"
   3502     "\t.type _start, @function\n"
   3503     "_start:\n"
   3504     /* Set up the new stack in %rdi. */
   3505     "\tmovq  $vgPlain_interim_stack, %rdi\n"
   3506     "\taddq  $"VG_STRINGIFY(VG_STACK_GUARD_SZB)", %rdi\n"
   3507     "\taddq  $"VG_STRINGIFY(VG_DEFAULT_STACK_ACTIVE_SZB)", %rdi\n"
   3508     "\tandq  $~15, %rdi\n"
   3509     /* Install it, and collect the original one. */
   3510     "\txchgq %rdi, %rsp\n"
   3511     /* Call _start_in_C_solaris, passing it the startup %rsp. */
   3512     "\tcall  _start_in_C_solaris\n"
   3513     /* NOTREACHED */
   3514     "\thlt\n"
   3515     ".previous\n"
   3516 );
   3517 #else
   3518 #  error "Unknown Solaris platform"
   3519 #endif
   3520 
   3521 void *memcpy(void *dest, const void *src, size_t n);
   3522 void *memcpy(void *dest, const void *src, size_t n) {
   3523    return VG_(memcpy)(dest, src, n);
   3524 }
   3525 
   3526 __attribute__ ((used))
   3527 void _start_in_C_solaris ( UWord* pArgc );
   3528 __attribute__ ((used))
   3529 void _start_in_C_solaris ( UWord* pArgc )
   3530 {
   3531    Int     r;
   3532    Word    argc = pArgc[0];
   3533    HChar** argv = (HChar**)&pArgc[1];
   3534    HChar** envp = (HChar**)&pArgc[1 + argc + 1];
   3535 
   3536    VG_(memset)( &the_iicii, 0, sizeof(the_iicii) );
   3537    VG_(memset)( &the_iifii, 0, sizeof(the_iifii) );
   3538 
   3539    the_iicii.sp_at_startup = (Addr)pArgc;
   3540 
   3541    r = valgrind_main((Int)argc, argv, envp);
   3542    /* NOTREACHED */
   3543    VG_(exit)(r);
   3544 }
   3545 
   3546 #else
   3547 #  error "Unknown OS"
   3548 #endif
   3549 
   3550 
   3551 Addr VG_(get_initial_client_SP)( void )
   3552 {
   3553    return the_iifii.initial_client_SP;
   3554 }
   3555 
   3556 /*====================================================================*/
   3557 /*=== {u,}{div,mod}di3 replacements                                ===*/
   3558 /*====================================================================*/
   3559 
   3560 /* For static linking on x86-darwin, we need to supply our own 64-bit
   3561    integer division code, else the link dies thusly:
   3562 
   3563    ld_classic: Undefined symbols:
   3564      ___udivdi3
   3565      ___umoddi3
   3566 */
   3567 #if defined(VGP_x86_darwin)
   3568 
   3569 /* Routines for doing signed/unsigned 64 x 64 ==> 64 div and mod
   3570    (udivdi3, umoddi3, divdi3, moddi3) using only 32 x 32 ==> 32
   3571    division.  Cobbled together from
   3572 
   3573    http://www.hackersdelight.org/HDcode/divlu.c
   3574    http://www.hackersdelight.org/HDcode/divls.c
   3575    http://www.hackersdelight.org/HDcode/newCode/divDouble.c
   3576 
   3577    The code from those three files is covered by the following license,
   3578    as it appears at:
   3579 
   3580    http://www.hackersdelight.org/permissions.htm
   3581 
   3582       You are free to use, copy, and distribute any of the code on
   3583       this web site, whether modified by you or not. You need not give
   3584       attribution. This includes the algorithms (some of which appear
   3585       in Hacker's Delight), the Hacker's Assistant, and any code
   3586       submitted by readers. Submitters implicitly agree to this.
   3587 */
   3588 
   3589 /* Long division, unsigned (64/32 ==> 32).
   3590    This procedure performs unsigned "long division" i.e., division of a
   3591 64-bit unsigned dividend by a 32-bit unsigned divisor, producing a
   3592 32-bit quotient.  In the overflow cases (divide by 0, or quotient
   3593 exceeds 32 bits), it returns a remainder of 0xFFFFFFFF (an impossible
   3594 value).
   3595    The dividend is u1 and u0, with u1 being the most significant word.
   3596 The divisor is parameter v. The value returned is the quotient.
   3597    Max line length is 57, to fit in hacker.book. */
   3598 
   3599 static Int nlz32(UInt x)
   3600 {
   3601    Int n;
   3602    if (x == 0) return(32);
   3603    n = 0;
   3604    if (x <= 0x0000FFFF) {n = n +16; x = x <<16;}
   3605    if (x <= 0x00FFFFFF) {n = n + 8; x = x << 8;}
   3606    if (x <= 0x0FFFFFFF) {n = n + 4; x = x << 4;}
   3607    if (x <= 0x3FFFFFFF) {n = n + 2; x = x << 2;}
   3608    if (x <= 0x7FFFFFFF) {n = n + 1;}
   3609    return n;
   3610 }
   3611 
   3612 /* 64 x 32 ==> 32 unsigned division, using only 32 x 32 ==> 32
   3613    division as a primitive. */
   3614 static UInt divlu2(UInt u1, UInt u0, UInt v, UInt *r)
   3615 {
   3616    const UInt b = 65536;     // Number base (16 bits).
   3617    UInt un1, un0,            // Norm. dividend LSD's.
   3618         vn1, vn0,            // Norm. divisor digits.
   3619         q1, q0,              // Quotient digits.
   3620         un32, un21, un10,    // Dividend digit pairs.
   3621         rhat;                // A remainder.
   3622    Int s;                    // Shift amount for norm.
   3623 
   3624    if (u1 >= v) {            // If overflow, set rem.
   3625       if (r != NULL)         // to an impossible value,
   3626          *r = 0xFFFFFFFF;    // and return the largest
   3627       return 0xFFFFFFFF;}    // possible quotient.
   3628 
   3629    s = nlz32(v);             // 0 <= s <= 31.
   3630    v = v << s;               // Normalize divisor.
   3631    vn1 = v >> 16;            // Break divisor up into
   3632    vn0 = v & 0xFFFF;         // two 16-bit digits.
   3633 
   3634    un32 = (u1 << s) | ((u0 >> (32 - s)) & (-s >> 31));
   3635    un10 = u0 << s;           // Shift dividend left.
   3636 
   3637    un1 = un10 >> 16;         // Break right half of
   3638    un0 = un10 & 0xFFFF;      // dividend into two digits.
   3639 
   3640    q1 = un32/vn1;            // Compute the first
   3641    rhat = un32 - q1*vn1;     // quotient digit, q1.
   3642  again1:
   3643    if (q1 >= b || q1*vn0 > b*rhat + un1) {
   3644      q1 = q1 - 1;
   3645      rhat = rhat + vn1;
   3646      if (rhat < b) goto again1;}
   3647 
   3648    un21 = un32*b + un1 - q1*v;  // Multiply and subtract.
   3649 
   3650    q0 = un21/vn1;            // Compute the second
   3651    rhat = un21 - q0*vn1;     // quotient digit, q0.
   3652  again2:
   3653    if (q0 >= b || q0*vn0 > b*rhat + un0) {
   3654      q0 = q0 - 1;
   3655      rhat = rhat + vn1;
   3656      if (rhat < b) goto again2;}
   3657 
   3658    if (r != NULL)            // If remainder is wanted,
   3659       *r = (un21*b + un0 - q0*v) >> s;     // return it.
   3660    return q1*b + q0;
   3661 }
   3662 
   3663 
   3664 /* 64 x 32 ==> 32 signed division, using only 32 x 32 ==> 32 division
   3665    as a primitive. */
   3666 static Int divls(Int u1, UInt u0, Int v, Int *r)
   3667 {
   3668    Int q, uneg, vneg, diff, borrow;
   3669 
   3670    uneg = u1 >> 31;          // -1 if u < 0.
   3671    if (uneg) {               // Compute the absolute
   3672       u0 = -u0;              // value of the dividend u.
   3673       borrow = (u0 != 0);
   3674       u1 = -u1 - borrow;}
   3675 
   3676    vneg = v >> 31;           // -1 if v < 0.
   3677    v = (v ^ vneg) - vneg;    // Absolute value of v.
   3678 
   3679    if ((UInt)u1 >= (UInt)v) goto overflow;
   3680 
   3681    q = divlu2(u1, u0, v, (UInt *)r);
   3682 
   3683    diff = uneg ^ vneg;       // Negate q if signs of
   3684    q = (q ^ diff) - diff;    // u and v differed.
   3685    if (uneg && r != NULL)
   3686       *r = -*r;
   3687 
   3688    if ((diff ^ q) < 0 && q != 0) {  // If overflow,
   3689  overflow:                    // set remainder
   3690       if (r != NULL)         // to an impossible value,
   3691          *r = 0x80000000;    // and return the largest
   3692       q = 0x80000000;}       // possible neg. quotient.
   3693    return q;
   3694 }
   3695 
   3696 
   3697 
   3698 /* This file contains a program for doing 64/64 ==> 64 division, on a
   3699 machine that does not have that instruction but that does have
   3700 instructions for "long division" (64/32 ==> 32). Code for unsigned
   3701 division is given first, followed by a simple program for doing the
   3702 signed version by using the unsigned version.
   3703    These programs are useful in implementing "long long" (64-bit)
   3704 arithmetic on a machine that has the long division instruction. It will
   3705 work on 64- and 32-bit machines, provided the compiler implements long
   3706 long's (64-bit integers). It is desirable that the machine have the
   3707 Count Leading Zeros instruction.
   3708    In the GNU world, these programs are known as __divdi3 and __udivdi3,
   3709 and similar names are used here.
   3710    This material is not in HD, but may be in a future edition.
   3711 Max line length is 57, to fit in hacker.book. */
   3712 
   3713 
   3714 static Int nlz64(ULong x)
   3715 {
   3716    Int n;
   3717    if (x == 0) return(64);
   3718    n = 0;
   3719    if (x <= 0x00000000FFFFFFFFULL) {n = n + 32; x = x << 32;}
   3720    if (x <= 0x0000FFFFFFFFFFFFULL) {n = n + 16; x = x << 16;}
   3721    if (x <= 0x00FFFFFFFFFFFFFFULL) {n = n +  8; x = x <<  8;}
   3722    if (x <= 0x0FFFFFFFFFFFFFFFULL) {n = n +  4; x = x <<  4;}
   3723    if (x <= 0x3FFFFFFFFFFFFFFFULL) {n = n +  2; x = x <<  2;}
   3724    if (x <= 0x7FFFFFFFFFFFFFFFULL) {n = n +  1;}
   3725    return n;
   3726 }
   3727 
   3728 // ---------------------------- udivdi3 --------------------------------
   3729 
   3730    /* The variables u0, u1, etc. take on only 32-bit values, but they
   3731    are declared long long to avoid some compiler warning messages and to
   3732    avoid some unnecessary EXTRs that the compiler would put in, to
   3733    convert long longs to ints.
   3734 
   3735    First the procedure takes care of the case in which the divisor is a
   3736    32-bit quantity. There are two subcases: (1) If the left half of the
   3737    dividend is less than the divisor, one execution of DIVU is all that
   3738    is required (overflow is not possible). (2) Otherwise it does two
   3739    divisions, using the grade school method, with variables used as
   3740    suggested below.
   3741 
   3742        q1 q0
   3743     ________
   3744    v)  u1 u0
   3745      q1*v
   3746      ____
   3747         k u0   */
   3748 
   3749 /* These macros must be used with arguments of the appropriate type
   3750 (unsigned long long for DIVU and long long for DIVS. They are
   3751 simulations of the presumed machines ops. I.e., they look at only the
   3752 low-order 32 bits of the divisor, they return garbage if the division
   3753 overflows, and they return garbage in the high-order half of the
   3754 quotient doubleword.
   3755    In practice, these would be replaced with uses of the machine's DIVU
   3756 and DIVS instructions (e.g., by using the GNU "asm" facility). */
   3757 
   3758 static UInt DIVU ( ULong u, UInt v )
   3759 {
   3760   UInt uHi = (UInt)(u >> 32);
   3761   UInt uLo = (UInt)u;
   3762   return divlu2(uHi, uLo, v, NULL);
   3763 }
   3764 
   3765 static Int DIVS ( Long u, Int v )
   3766 {
   3767   Int  uHi = (Int)(u >> 32);
   3768   UInt uLo = (UInt)u;
   3769   return divls(uHi, uLo, v, NULL);
   3770 }
   3771 
   3772 /* 64 x 64 ==> 64 unsigned division, using only 32 x 32 ==> 32
   3773    division as a primitive. */
   3774 static ULong udivdi3(ULong u, ULong v)
   3775 {
   3776    ULong u0, u1, v1, q0, q1, k, n;
   3777 
   3778    if (v >> 32 == 0) {          // If v < 2**32:
   3779       if (u >> 32 < v)          // If u/v cannot overflow,
   3780          return DIVU(u, v)      // just do one division.
   3781             & 0xFFFFFFFF;
   3782       else {                    // If u/v would overflow:
   3783          u1 = u >> 32;          // Break u up into two
   3784          u0 = u & 0xFFFFFFFF;   // halves.
   3785          q1 = DIVU(u1, v)       // First quotient digit.
   3786             & 0xFFFFFFFF;
   3787          k = u1 - q1*v;         // First remainder, < v.
   3788          q0 = DIVU((k << 32) + u0, v) // 2nd quot. digit.
   3789             & 0xFFFFFFFF;
   3790          return (q1 << 32) + q0;
   3791       }
   3792    }
   3793                                 // Here v >= 2**32.
   3794    n = nlz64(v);                // 0 <= n <= 31.
   3795    v1 = (v << n) >> 32;         // Normalize the divisor
   3796                                 // so its MSB is 1.
   3797    u1 = u >> 1;                 // To ensure no overflow.
   3798    q1 = DIVU(u1, v1)            // Get quotient from
   3799        & 0xFFFFFFFF;            // divide unsigned insn.
   3800    q0 = (q1 << n) >> 31;        // Undo normalization and
   3801                                 // division of u by 2.
   3802    if (q0 != 0)                 // Make q0 correct or
   3803       q0 = q0 - 1;              // too small by 1.
   3804    if ((u - q0*v) >= v)
   3805       q0 = q0 + 1;              // Now q0 is correct.
   3806    return q0;
   3807 }
   3808 
   3809 
   3810 // ----------------------------- divdi3 --------------------------------
   3811 
   3812 /* This routine presumes that smallish cases (those which can be done in
   3813 one execution of DIVS) are common. If this is not the case, the test for
   3814 this case should be deleted.
   3815    Note that the test for when DIVS can be used is not entirely
   3816 accurate. For example, DIVS is not used if v = 0xFFFFFFFF8000000,
   3817 whereas if could be (if u is sufficiently small in magnitude). */
   3818 
   3819 // ------------------------------ cut ----------------------------------
   3820 
   3821 static ULong my_llabs ( Long x )
   3822 {
   3823    ULong t = x >> 63;
   3824    return (x ^ t) - t;
   3825 }
   3826 
   3827 /* 64 x 64 ==> 64 signed division, using only 32 x 32 ==> 32 division
   3828    as a primitive. */
   3829 static Long divdi3(Long u, Long v)
   3830 {
   3831    ULong au, av;
   3832    Long q, t;
   3833    au = my_llabs(u);
   3834    av = my_llabs(v);
   3835    if (av >> 31 == 0) {         // If |v| < 2**31 and
   3836    // if (v << 32 >> 32 == v) { // If v is in range and
   3837       if (au < av << 31) {      // |u|/|v| cannot
   3838          q = DIVS(u, v);        // overflow, use DIVS.
   3839          return (q << 32) >> 32;
   3840       }
   3841    }
   3842    q = udivdi3(au,av);          // Invoke udivdi3.
   3843    t = (u ^ v) >> 63;           // If u, v have different
   3844    return (q ^ t) - t;          // signs, negate q.
   3845 }
   3846 
   3847 // ---------------------------- end cut --------------------------------
   3848 
   3849 ULong __udivdi3 (ULong u, ULong v);
   3850 ULong __udivdi3 (ULong u, ULong v)
   3851 {
   3852   return udivdi3(u,v);
   3853 }
   3854 
   3855 Long __divdi3 (Long u, Long v);
   3856 Long __divdi3 (Long u, Long v)
   3857 {
   3858   return divdi3(u,v);
   3859 }
   3860 
   3861 ULong __umoddi3 (ULong u, ULong v);
   3862 ULong __umoddi3 (ULong u, ULong v)
   3863 {
   3864   ULong q = __udivdi3(u, v);
   3865   ULong r = u - q * v;
   3866   return r;
   3867 }
   3868 
   3869 Long __moddi3 (Long u, Long v);
   3870 Long __moddi3 (Long u, Long v)
   3871 {
   3872   Long q = __divdi3(u, v);
   3873   Long r = u - q * v;
   3874   return r;
   3875 }
   3876 
   3877 /* ------------------------------------------------
   3878    ld_classic: Undefined symbols:
   3879       ___fixunsdfdi
   3880    ------------------------------------------------
   3881 */
   3882 
   3883 /* ===-- fixunsdfdi.c - Implement __fixunsdfdi -----------------------------===
   3884  *
   3885  *                     The LLVM Compiler Infrastructure
   3886  *
   3887  * This file is dual licensed under the MIT and the University of Illinois Open
   3888  * Source Licenses. See LICENSE.TXT for details.
   3889  *
   3890  * ===----------------------------------------------------------------------===
   3891  *
   3892  * This file implements __fixunsdfdi for the compiler_rt library.
   3893  *
   3894  * ===----------------------------------------------------------------------===
   3895  */
   3896 
   3897 /* As per http://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses,
   3898 
   3899    the "NCSA/University of Illinois Open Source License" is compatible
   3900    with the GPL (both version 2 and 3).  What is claimed to be
   3901    compatible is this
   3902 
   3903    http://www.opensource.org/licenses/UoI-NCSA.php
   3904 
   3905    and the LLVM documentation at
   3906 
   3907    http://www.llvm.org/docs/DeveloperPolicy.html#license
   3908 
   3909    says all the code in LLVM is available under the University of
   3910    Illinois/NCSA Open Source License, at this URL
   3911 
   3912    http://www.opensource.org/licenses/UoI-NCSA.php
   3913 
   3914    viz, the same one that the FSF pages claim is compatible.  So I
   3915    think it's OK to include it.
   3916 */
   3917 
   3918 /* Returns: convert a to a unsigned long long, rounding toward zero.
   3919  *          Negative values all become zero.
   3920  */
   3921 
   3922 /* Assumption: double is a IEEE 64 bit floating point type
   3923  *             du_int is a 64 bit integral type
   3924  *             value in double is representable in du_int or is negative
   3925  *                 (no range checking performed)
   3926  */
   3927 
   3928 /* seee eeee eeee mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm */
   3929 
   3930 typedef unsigned long long du_int;
   3931 typedef unsigned su_int;
   3932 
   3933 typedef union
   3934 {
   3935     du_int all;
   3936     struct
   3937     {
   3938 #if VG_LITTLEENDIAN
   3939         su_int low;
   3940         su_int high;
   3941 #else
   3942         su_int high;
   3943         su_int low;
   3944 #endif /* VG_LITTLEENDIAN */
   3945     }s;
   3946 } udwords;
   3947 
   3948 typedef union
   3949 {
   3950     udwords u;
   3951     double  f;
   3952 } double_bits;
   3953 
   3954 du_int __fixunsdfdi(double a);
   3955 
   3956 du_int
   3957 __fixunsdfdi(double a)
   3958 {
   3959     double_bits fb;
   3960     fb.f = a;
   3961     int e = ((fb.u.s.high & 0x7FF00000) >> 20) - 1023;
   3962     if (e < 0 || (fb.u.s.high & 0x80000000))
   3963         return 0;
   3964     udwords r;
   3965     r.s.high = (fb.u.s.high & 0x000FFFFF) | 0x00100000;
   3966     r.s.low = fb.u.s.low;
   3967     if (e > 52)
   3968         r.all <<= (e - 52);
   3969     else
   3970         r.all >>= (52 - e);
   3971     return r.all;
   3972 }
   3973 
   3974 
   3975 #endif
   3976 
   3977 
   3978 /*====================================================================*/
   3979 /*=== Dummy _voucher_mach_msg_set for OSX 10.10                    ===*/
   3980 /*====================================================================*/
   3981 
   3982 #if defined(VGO_darwin) && DARWIN_VERS >= DARWIN_10_10
   3983 
   3984 /* Builds on MacOSX 10.10+ seem to need this for some reason. */
   3985 /* extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg)
   3986                     __attribute__((weak_import));
   3987    I haven't a clue what the return value means, so just return 0.
   3988    Looks like none of the generated uses in the tree look at the
   3989    return value anyway.
   3990 */
   3991 UWord voucher_mach_msg_set ( UWord arg1 );
   3992 UWord voucher_mach_msg_set ( UWord arg1 )
   3993 {
   3994    return 0;
   3995 }
   3996 
   3997 #endif
   3998 
   3999 
   4000 /*--------------------------------------------------------------------*/
   4001 /*--- end                                                          ---*/
   4002 /*--------------------------------------------------------------------*/
   4003