m_options.c revision 46207652a0c99a2c8b0f05eafce3ca3ec533c121
132824028b51461062a5a282bfd775d4bd4ad6a47sewardj
232824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
3b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*--- Command line options.                            m_options.c ---*/
432824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
532824028b51461062a5a282bfd775d4bd4ad6a47sewardj
632824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*
732824028b51461062a5a282bfd775d4bd4ad6a47sewardj   This file is part of Valgrind, a dynamic binary instrumentation
832824028b51461062a5a282bfd775d4bd4ad6a47sewardj   framework.
932824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1003f8d3fc25f5a45c5826259d1b33b7f310117279sewardj   Copyright (C) 2000-2012 Nicholas Nethercote
1132824028b51461062a5a282bfd775d4bd4ad6a47sewardj      njn@valgrind.org
1232824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1332824028b51461062a5a282bfd775d4bd4ad6a47sewardj   This program is free software; you can redistribute it and/or
1432824028b51461062a5a282bfd775d4bd4ad6a47sewardj   modify it under the terms of the GNU General Public License as
1532824028b51461062a5a282bfd775d4bd4ad6a47sewardj   published by the Free Software Foundation; either version 2 of the
1632824028b51461062a5a282bfd775d4bd4ad6a47sewardj   License, or (at your option) any later version.
1732824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1832824028b51461062a5a282bfd775d4bd4ad6a47sewardj   This program is distributed in the hope that it will be useful, but
1932824028b51461062a5a282bfd775d4bd4ad6a47sewardj   WITHOUT ANY WARRANTY; without even the implied warranty of
2032824028b51461062a5a282bfd775d4bd4ad6a47sewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
2132824028b51461062a5a282bfd775d4bd4ad6a47sewardj   General Public License for more details.
2232824028b51461062a5a282bfd775d4bd4ad6a47sewardj
2332824028b51461062a5a282bfd775d4bd4ad6a47sewardj   You should have received a copy of the GNU General Public License
2432824028b51461062a5a282bfd775d4bd4ad6a47sewardj   along with this program; if not, write to the Free Software
2532824028b51461062a5a282bfd775d4bd4ad6a47sewardj   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
2632824028b51461062a5a282bfd775d4bd4ad6a47sewardj   02111-1307, USA.
2732824028b51461062a5a282bfd775d4bd4ad6a47sewardj
2832824028b51461062a5a282bfd775d4bd4ad6a47sewardj   The GNU General Public License is contained in the file COPYING.
2932824028b51461062a5a282bfd775d4bd4ad6a47sewardj*/
3032824028b51461062a5a282bfd775d4bd4ad6a47sewardj
31c7561b931e249acf3768ead77638545b0ccaa8f1njn#include "pub_core_basics.h"
32374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#include "pub_core_vki.h"
33a3506d39c8c94f09837558d33c54b110e1ac0ea1njn#include "pub_core_options.h"
346893d65852940741dbebbc6ba1480e89cf34e30fsewardj#include "pub_core_libcassert.h"
35374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#include "pub_core_libcbase.h"
36374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#include "pub_core_libcfile.h"
376893d65852940741dbebbc6ba1480e89cf34e30fsewardj#include "pub_core_libcprint.h"
38374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#include "pub_core_libcproc.h"
39374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#include "pub_core_mallocfree.h"
40064212709dc8988a48d2cbde5b90528952d8cd74sewardj#include "pub_core_seqmatch.h"     // VG_(string_match)
4132824028b51461062a5a282bfd775d4bd4ad6a47sewardj
42a3506d39c8c94f09837558d33c54b110e1ac0ea1njn// See pub_{core,tool}_options.h for explanations of all these.
43a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
44a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
45a3506d39c8c94f09837558d33c54b110e1ac0ea1njn/* Define, and set defaults. */
46a3506d39c8c94f09837558d33c54b110e1ac0ea1njnVexControl VG_(clo_vex_control);
47a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_error_limit)    = True;
48b9779088c43db2a576ae43bde0694411c036b1c4sewardjInt    VG_(clo_error_exitcode) = 0;
490ba37c90c4674515da387b30a6e5f23fa75a173csewardj
505d5dd8e6b7ff782fc89f5b96cecf04839742882bphilippe#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android)
51deddfdfbd13203804737b95b6bf5861f758ac865sewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
52deddfdfbd13203804737b95b6bf5861f758ac865sewardj#else
530ba37c90c4674515da387b30a6e5f23fa75a173csewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
54deddfdfbd13203804737b95b6bf5861f758ac865sewardj#endif
553b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_poll)      = 5000;
563b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_error)     = 999999999;
5719f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_vgdb_prefix)    = NULL;
583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool   VG_(clo_vgdb_shadow_registers) = False;
590ba37c90c4674515da387b30a6e5f23fa75a173csewardj
60a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_db_attach)      = False;
6119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar*  VG_(clo_db_command)     = GDB_PATH " -nw %f %p";
62a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_gen_suppressions) = 0;
63a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_sanity_level)   = 1;
64a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_verbosity)      = 1;
652d9e874b7a628ada216f09cc4f065798c65fffa4sewardjBool   VG_(clo_stats)          = False;
6671bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardjBool   VG_(clo_xml)            = False;
6719f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_xml_user_comment) = NULL;
68a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_demangle)       = True;
6919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_soname_synonyms)    = NULL;
70a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_children) = False;
7119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip) = NULL;
7219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
736e31f80899f1c79a54f164955069f3f74fe8b7e2sewardjBool   VG_(clo_child_silent_after_fork) = False;
7419f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(clo_log_fname_expanded) = NULL;
7519f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(clo_xml_fname_expanded) = NULL;
76a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_time_stamp)     = False;
77a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_input_fd)       = 0; /* stdin */
78a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_n_suppressions) = 0;
7919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
8014cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardjInt    VG_(clo_n_fullpath_after) = 0;
8119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
8271826f77dbaefb6a9c694d9711aa649ed0980cc7sewardjconst HChar* VG_(clo_extra_debuginfo_path) = NULL;
83a3506d39c8c94f09837558d33c54b110e1ac0ea1njnUChar  VG_(clo_trace_flags)    = 0; // 00000000b
8417c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjBool   VG_(clo_profyle_sbs)    = False;
8517c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjUChar  VG_(clo_profyle_flags)  = 0; // 00000000b
8617c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjULong  VG_(clo_profyle_interval) = 0;
8729e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notbelow) = -1;  // unspecified
8829e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notabove) = -1;  // unspecified
89a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_syscalls) = False;
90a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_signals)  = False;
91a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_symtab)   = False;
9219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_symtab_patt) = "*";
93a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_cfi)      = False;
94f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_syms) = False;
95f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_line) = False;
96f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_frames) = False;
97a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_redir)    = False;
9878bfc711d3e684c76eeab5f89a94a78d40ed6f4bbartenum FairSchedType
9978bfc711d3e684c76eeab5f89a94a78d40ed6f4bbart       VG_(clo_fair_sched)     = disable_fair_sched;
100a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_sched)    = False;
1019c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjBool   VG_(clo_profile_heap)   = False;
102d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_core_redzone_size) = CORE_REDZONE_DEFAULT_SZB;
103d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// A value != -1 overrides the tool-specific value
104d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// VG_(needs_malloc_replacement).tool_client_redzone_szB
105d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_redzone_size)   = -1;
106a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_dump_error)     = 0;
107a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_backtrace_size) = 12;
10846207652a0c99a2c8b0f05eafce3ca3ec533c121philippeInt    VG_(clo_merge_recursive_frames) = 0; // default value: no merge
10919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_sim_hints)      = NULL;
11041ded2cf9711091a1bc7a6c1dd2d177e978b05e9sewardjBool   VG_(clo_sym_offsets)    = False;
111b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool   VG_(clo_read_var_info)  = False;
112f9ebc3956087ce01561c4ab3faf5a8983b0f7c1csewardjInt    VG_(clo_n_req_tsyms)    = 0;
11319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS];
114f9ebc3956087ce01561c4ab3faf5a8983b0f7c1csewardjHChar* VG_(clo_require_text_symbol) = NULL;
115a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_run_libc_freeres) = True;
116a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_track_fds)      = False;
117a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_below_main)= False;
118a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_emwarns)   = False;
11991b470c367836f65177413ca2a19b25f32fb8ef0sewardjWord   VG_(clo_max_stackframe) = 2000000;
12095d86c091a218e904e912354efa4f952a9712e82sewardjWord   VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */
121a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_wait_for_gdb)   = False;
1226c3a219727dead14309abf431f72ca1f99b8ca37sewardjVgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
12319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_kernel_variant) = NULL;
12497db761d2a94fc7a349aee9359ef85828d9618b6njnBool   VG_(clo_dsymutil)       = False;
125c30cd9bdc3c13c79a2e0281302b115c3d220bc9dsewardjBool   VG_(clo_sigill_diag)    = True;
12632824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1276893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
128b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*=== File expansion                                               ===*/
1296893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
1306893d65852940741dbebbc6ba1480e89cf34e30fsewardj
131374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// Copies the string, prepending it with the startup working directory, and
132374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// expanding %p and %q entries.  Returns a new, malloc'd string.
13319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format)
134374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn{
13519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   static HChar base_dir[VKI_PATH_MAX];
136374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Int len, i = 0, j = 0;
13719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* out;
138374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
139374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Bool ok = VG_(get_startup_wd)(base_dir, VKI_PATH_MAX);
140374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   tl_assert(ok);
141374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
142374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (VG_STREQ(format, "")) {
143374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      // Empty name, bad.
144b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      VG_(fmsg)("%s: filename is empty", option_name);
1455542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn      goto bad;
1465542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   }
1475542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn
1485542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // If 'format' starts with a '~', abort -- the user probably expected the
1495542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // shell to expand but it didn't (see bug 195268 for details).  This means
1505542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // that we don't allow a legitimate filename beginning with '~' but that
1515542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // seems very unlikely.
1525542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   if (format[0] == '~') {
153b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      VG_(fmsg)(
154b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "%s: filename begins with '~'\n"
155b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You probably expected the shell to expand the '~', but it\n"
156b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "didn't.  The rules for '~'-expansion vary from shell to shell.\n"
157b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You might have more luck using $HOME instead.\n",
158b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         option_name
159b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      );
160374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      goto bad;
161374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
162374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
1632dd08f575042c604cebf32f2c2002a0fba0ed800njn   // If 'format' starts with a '/', do not prefix with startup dir.
1642dd08f575042c604cebf32f2c2002a0fba0ed800njn   if (format[0] != '/') {
1652dd08f575042c604cebf32f2c2002a0fba0ed800njn      j += VG_(strlen)(base_dir);
1662dd08f575042c604cebf32f2c2002a0fba0ed800njn   }
1672dd08f575042c604cebf32f2c2002a0fba0ed800njn
168374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   // The 10 is slop, it should be enough in most cases.
169374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   len = j + VG_(strlen)(format) + 10;
1709c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   out = VG_(malloc)( "options.efn.1", len );
1712dd08f575042c604cebf32f2c2002a0fba0ed800njn   if (format[0] != '/') {
1722dd08f575042c604cebf32f2c2002a0fba0ed800njn      VG_(strcpy)(out, base_dir);
1732dd08f575042c604cebf32f2c2002a0fba0ed800njn      out[j++] = '/';
1742dd08f575042c604cebf32f2c2002a0fba0ed800njn   }
175374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
176374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#define ENSURE_THIS_MUCH_SPACE(x) \
177374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (j + x >= len) { \
178374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      len += (10 + x); \
1799c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      out = VG_(realloc)("options.efn.2(multiple)", out, len); \
180374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
181374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
182374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   while (format[i]) {
183374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      if (format[i] != '%') {
184374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         ENSURE_THIS_MUCH_SPACE(1);
185374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         out[j++] = format[i++];
186374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
187374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      } else {
188374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         // We saw a '%'.  What's next...
189374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         i++;
190374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         if      ('%' == format[i]) {
191374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Replace '%%' with '%'.
192374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(1);
193374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            out[j++] = format[i++];
194374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
195374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else if ('p' == format[i]) {
196374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Print the PID.  Assume that it's not longer than 10 chars --
197374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // reasonable since 'pid' is an Int (ie. 32 bits).
198374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            Int pid = VG_(getpid)();
199374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(10);
200374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            j += VG_(sprintf)(&out[j], "%d", pid);
201374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            i++;
202374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
2032dd08f575042c604cebf32f2c2002a0fba0ed800njn         else if ('q' == format[i]) {
2042dd08f575042c604cebf32f2c2002a0fba0ed800njn            i++;
2052dd08f575042c604cebf32f2c2002a0fba0ed800njn            if ('{' == format[i]) {
2062dd08f575042c604cebf32f2c2002a0fba0ed800njn               // Get the env var name, print its contents.
20719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian               const HChar* qualname;
20819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian               HChar* qual;
2092dd08f575042c604cebf32f2c2002a0fba0ed800njn               i++;
2102dd08f575042c604cebf32f2c2002a0fba0ed800njn               qualname = &format[i];
2112dd08f575042c604cebf32f2c2002a0fba0ed800njn               while (True) {
2122dd08f575042c604cebf32f2c2002a0fba0ed800njn                  if (0 == format[i]) {
213b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                     VG_(fmsg)("%s: malformed %%q specifier\n", option_name);
214374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                     goto bad;
2152dd08f575042c604cebf32f2c2002a0fba0ed800njn                  } else if ('}' == format[i]) {
2162dd08f575042c604cebf32f2c2002a0fba0ed800njn                     // Temporarily replace the '}' with NUL to extract var
2172dd08f575042c604cebf32f2c2002a0fba0ed800njn                     // name.
218cfea784f4432d0ec79e9360ad324b820faada649florian                     // FIXME: this is not safe as FORMAT is sometimes a
219cfea784f4432d0ec79e9360ad324b820faada649florian                     // string literal which may reside in read-only memory
22019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                    ((HChar *)format)[i] = 0;
2212dd08f575042c604cebf32f2c2002a0fba0ed800njn                     qual = VG_(getenv)(qualname);
2222dd08f575042c604cebf32f2c2002a0fba0ed800njn                     if (NULL == qual) {
223b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                        VG_(fmsg)("%s: environment variable %s is not set\n",
224b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                                  option_name, qualname);
22519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // FIXME: this is not safe as FORMAT is sometimes a
22619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // string literal which may reside in read-only memory
22719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                        ((HChar *)format)[i] = '}';  // Put the '}' back.
2282dd08f575042c604cebf32f2c2002a0fba0ed800njn                        goto bad;
2292dd08f575042c604cebf32f2c2002a0fba0ed800njn                     }
23019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // FIXME: this is not safe as FORMAT is sometimes a
23119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // string literal which may reside in read-only memory
23219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     ((HChar *)format)[i] = '}';     // Put the '}' back.
2332dd08f575042c604cebf32f2c2002a0fba0ed800njn                     i++;
2342dd08f575042c604cebf32f2c2002a0fba0ed800njn                     break;
235374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  }
236374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  i++;
237374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn               }
2382dd08f575042c604cebf32f2c2002a0fba0ed800njn               ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual));
2392dd08f575042c604cebf32f2c2002a0fba0ed800njn               j += VG_(sprintf)(&out[j], "%s", qual);
2402dd08f575042c604cebf32f2c2002a0fba0ed800njn            } else {
241b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn               VG_(fmsg)("%s: expected '{' after '%%q'\n", option_name);
2422dd08f575042c604cebf32f2c2002a0fba0ed800njn               goto bad;
243374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            }
244374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
245374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else {
246374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Something else, abort.
247b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn            VG_(fmsg)("%s: expected 'p' or 'q' or '%%' after '%%'\n",
248b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                      option_name);
249374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            goto bad;
250374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
251374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      }
252374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
253374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   ENSURE_THIS_MUCH_SPACE(1);
254374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   out[j++] = 0;
255374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
256374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   return out;
257374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
258374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  bad: {
25919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* opt =    // 2:  1 for the '=', 1 for the NUL.
2609c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(malloc)( "options.efn.3",
2619c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   VG_(strlen)(option_name) + VG_(strlen)(format) + 2 );
262374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcpy)(opt, option_name);
263374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcat)(opt, "=");
264374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcat)(opt, format);
265b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn   VG_(fmsg_bad_option)(opt, "");
266374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  }
267374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn}
268374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
269064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
270064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*=== --trace-children= support                                    ===*/
271064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
272064212709dc8988a48d2cbde5b90528952d8cd74sewardj
273064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_commas ( HChar const* c ) {
274064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c == ',') {
275064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
276064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
277064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
278064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
279064212709dc8988a48d2cbde5b90528952d8cd74sewardj
280064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_field ( HChar const* c ) {
281064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c != ',') {
282064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
283064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
284064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
285064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
286064212709dc8988a48d2cbde5b90528952d8cd74sewardj
287064212709dc8988a48d2cbde5b90528952d8cd74sewardj/* Should we trace into this child executable (across execve etc) ?
2889ab64a4d3043c251561419d0e0f51492172b1072sewardj   This involves considering --trace-children=,
2899ab64a4d3043c251561419d0e0f51492172b1072sewardj   --trace-children-skip=, --trace-children-skip-by-arg=, and the name
2909ab64a4d3043c251561419d0e0f51492172b1072sewardj   of the executable.  'child_argv' must not include the name of the
2919ab64a4d3043c251561419d0e0f51492172b1072sewardj   executable itself; iow child_argv[0] must be the first arg, if any,
2929ab64a4d3043c251561419d0e0f51492172b1072sewardj   for the child. */
2939ab64a4d3043c251561419d0e0f51492172b1072sewardjBool VG_(should_we_trace_this_child) ( HChar* child_exe_name,
2949ab64a4d3043c251561419d0e0f51492172b1072sewardj                                       HChar** child_argv )
295064212709dc8988a48d2cbde5b90528952d8cd74sewardj{
296064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // child_exe_name is pulled out of the guest's space.  We
297064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // should be at least marginally cautious with it, lest it
298064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // explode or burst into flames unexpectedly.
299064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0)
300064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return VG_(clo_trace_children);  // we know narfink
301064212709dc8988a48d2cbde5b90528952d8cd74sewardj
302064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // If --trace-children=no, the answer is simply NO.
303064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (! VG_(clo_trace_children))
304064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return False;
305064212709dc8988a48d2cbde5b90528952d8cd74sewardj
3069ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Otherwise, look for other reasons to say NO.  First,
3079ab64a4d3043c251561419d0e0f51492172b1072sewardj   // see if the exe name matches any of the patterns specified
3089ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip=.
309064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (VG_(clo_trace_children_skip)) {
310064212709dc8988a48d2cbde5b90528952d8cd74sewardj      HChar const* last = VG_(clo_trace_children_skip);
31119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar const* name = child_exe_name;
312064212709dc8988a48d2cbde5b90528952d8cd74sewardj      while (*last) {
313064212709dc8988a48d2cbde5b90528952d8cd74sewardj         Bool   matches;
314064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar* patt;
315064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar const* first = consume_commas(last);
316064212709dc8988a48d2cbde5b90528952d8cd74sewardj         last = consume_field(first);
317064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (first == last)
318064212709dc8988a48d2cbde5b90528952d8cd74sewardj            break;
319064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(last > first);
320064212709dc8988a48d2cbde5b90528952d8cd74sewardj         /* copy the candidate string into a temporary malloc'd block
321064212709dc8988a48d2cbde5b90528952d8cd74sewardj            so we can use VG_(string_match) on it. */
322064212709dc8988a48d2cbde5b90528952d8cd74sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
323064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(memcpy)(patt, first, last - first);
324064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(patt[last-first] == 0);
325064212709dc8988a48d2cbde5b90528952d8cd74sewardj         matches = VG_(string_match)(patt, name);
326064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(free)(patt);
327064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (matches)
328064212709dc8988a48d2cbde5b90528952d8cd74sewardj            return False;
329064212709dc8988a48d2cbde5b90528952d8cd74sewardj      }
330064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
3319ab64a4d3043c251561419d0e0f51492172b1072sewardj
3329ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Check if any of the args match any of the patterns specified
3339ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip-by-arg=.
3349ab64a4d3043c251561419d0e0f51492172b1072sewardj   if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) {
3359ab64a4d3043c251561419d0e0f51492172b1072sewardj      HChar const* last = VG_(clo_trace_children_skip_by_arg);
3369ab64a4d3043c251561419d0e0f51492172b1072sewardj      while (*last) {
3379ab64a4d3043c251561419d0e0f51492172b1072sewardj         Int    i;
3389ab64a4d3043c251561419d0e0f51492172b1072sewardj         Bool   matches;
3399ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar* patt;
3409ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar const* first = consume_commas(last);
3419ab64a4d3043c251561419d0e0f51492172b1072sewardj         last = consume_field(first);
3429ab64a4d3043c251561419d0e0f51492172b1072sewardj         if (first == last)
3439ab64a4d3043c251561419d0e0f51492172b1072sewardj            break;
3449ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(last > first);
3459ab64a4d3043c251561419d0e0f51492172b1072sewardj         /* copy the candidate string into a temporary malloc'd block
3469ab64a4d3043c251561419d0e0f51492172b1072sewardj            so we can use VG_(string_match) on it. */
3479ab64a4d3043c251561419d0e0f51492172b1072sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
3489ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(memcpy)(patt, first, last - first);
3499ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(patt[last-first] == 0);
3509ab64a4d3043c251561419d0e0f51492172b1072sewardj         for (i = 0; child_argv[i]; i++) {
3519ab64a4d3043c251561419d0e0f51492172b1072sewardj            matches = VG_(string_match)(patt, child_argv[i]);
3529ab64a4d3043c251561419d0e0f51492172b1072sewardj            if (matches) {
3539ab64a4d3043c251561419d0e0f51492172b1072sewardj               VG_(free)(patt);
3549ab64a4d3043c251561419d0e0f51492172b1072sewardj               return False;
3559ab64a4d3043c251561419d0e0f51492172b1072sewardj            }
3569ab64a4d3043c251561419d0e0f51492172b1072sewardj         }
3579ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(free)(patt);
3589ab64a4d3043c251561419d0e0f51492172b1072sewardj      }
3599ab64a4d3043c251561419d0e0f51492172b1072sewardj   }
3609ab64a4d3043c251561419d0e0f51492172b1072sewardj
361064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // --trace-children=yes, and this particular executable isn't
362064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // excluded
363064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return True;
364064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
365374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
3666893d65852940741dbebbc6ba1480e89cf34e30fsewardj
36732824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
368b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*--- end                                                          ---*/
36932824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
370