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
100f157ddb404bcde7815a1c5bf2d7e41c114f3d73sewardj   Copyright (C) 2000-2013 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)
41d0720e4a624bdfe7ce2494d690e7a88f986b93c1philippe#include "pub_core_aspacemgr.h"
4232824028b51461062a5a282bfd775d4bd4ad6a47sewardj
43a3506d39c8c94f09837558d33c54b110e1ac0ea1njn// See pub_{core,tool}_options.h for explanations of all these.
44a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
45a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
46a3506d39c8c94f09837558d33c54b110e1ac0ea1njn/* Define, and set defaults. */
478d47a61e503b69ffbc783717f5faf09d0bbc4723sewardj
48a3506d39c8c94f09837558d33c54b110e1ac0ea1njnVexControl VG_(clo_vex_control);
498d47a61e503b69ffbc783717f5faf09d0bbc4723sewardjVexRegisterUpdates VG_(clo_px_file_backed) = VexRegUpd_INVALID;
508d47a61e503b69ffbc783717f5faf09d0bbc4723sewardj
51a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_error_limit)    = True;
52b9779088c43db2a576ae43bde0694411c036b1c4sewardjInt    VG_(clo_error_exitcode) = 0;
537b3d3565c1559b88c67f629bd6613c8b1a89691bphilippeHChar *VG_(clo_error_markers)[2] = {NULL, NULL};
540ba37c90c4674515da387b30a6e5f23fa75a173csewardj
5526ed419d60369d0545510eba0832566e24452e1esewardj#if defined(VGPV_arm_linux_android) \
5626ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_x86_linux_android) \
5726ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_mips32_linux_android) \
5826ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_arm64_linux_android)
59deddfdfbd13203804737b95b6bf5861f758ac865sewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
60deddfdfbd13203804737b95b6bf5861f758ac865sewardj#else
610ba37c90c4674515da387b30a6e5f23fa75a173csewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
62deddfdfbd13203804737b95b6bf5861f758ac865sewardj#endif
633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_poll)      = 5000;
643b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_error)     = 999999999;
65180a7500bf2464d5b16cddb5618b91fb3f095998philippeUInt   VG_(clo_vgdb_stop_at)   = 0;
66cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(clo_vgdb_prefix)    = NULL;
67cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(arg_vgdb_prefix)    = NULL;
683b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool   VG_(clo_vgdb_shadow_registers) = False;
690ba37c90c4674515da387b30a6e5f23fa75a173csewardj
70a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_db_attach)      = False;
7119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar*  VG_(clo_db_command)     = GDB_PATH " -nw %f %p";
72a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_gen_suppressions) = 0;
73a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_sanity_level)   = 1;
74a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_verbosity)      = 1;
752d9e874b7a628ada216f09cc4f065798c65fffa4sewardjBool   VG_(clo_stats)          = False;
7671bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardjBool   VG_(clo_xml)            = False;
7719f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_xml_user_comment) = NULL;
78a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_demangle)       = True;
7919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_soname_synonyms)    = NULL;
80a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_children) = False;
8119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip) = NULL;
8219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
836e31f80899f1c79a54f164955069f3f74fe8b7e2sewardjBool   VG_(clo_child_silent_after_fork) = False;
84518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* VG_(clo_log_fname_expanded) = NULL;
85518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* VG_(clo_xml_fname_expanded) = NULL;
86a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_time_stamp)     = False;
87a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_input_fd)       = 0; /* stdin */
882c68e3eff3850e2d466774d152231e628107a28fbartBool   VG_(clo_default_supp)   = True;
897931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_suppressions);   // array of strings
907931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_fullpath_after); // array of strings
9171826f77dbaefb6a9c694d9711aa649ed0980cc7sewardjconst HChar* VG_(clo_extra_debuginfo_path) = NULL;
925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjconst HChar* VG_(clo_debuginfo_server) = NULL;
935d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjBool   VG_(clo_allow_mismatched_debuginfo) = False;
94a3506d39c8c94f09837558d33c54b110e1ac0ea1njnUChar  VG_(clo_trace_flags)    = 0; // 00000000b
9517c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjBool   VG_(clo_profyle_sbs)    = False;
9617c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjUChar  VG_(clo_profyle_flags)  = 0; // 00000000b
9717c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjULong  VG_(clo_profyle_interval) = 0;
9829e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notbelow) = -1;  // unspecified
9929e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notabove) = -1;  // unspecified
100a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_syscalls) = False;
101a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_signals)  = False;
102a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_symtab)   = False;
10319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_symtab_patt) = "*";
104a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_cfi)      = False;
105f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_syms) = False;
106f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_line) = False;
107f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_frames) = False;
108a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_redir)    = False;
10978bfc711d3e684c76eeab5f89a94a78d40ed6f4bbartenum FairSchedType
11078bfc711d3e684c76eeab5f89a94a78d40ed6f4bbart       VG_(clo_fair_sched)     = disable_fair_sched;
111a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_sched)    = False;
1129c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjBool   VG_(clo_profile_heap)   = False;
113d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_core_redzone_size) = CORE_REDZONE_DEFAULT_SZB;
114d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// A value != -1 overrides the tool-specific value
115d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// VG_(needs_malloc_replacement).tool_client_redzone_szB
116d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_redzone_size)   = -1;
117a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_dump_error)     = 0;
118a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_backtrace_size) = 12;
11946207652a0c99a2c8b0f05eafce3ca3ec533c121philippeInt    VG_(clo_merge_recursive_frames) = 0; // default value: no merge
120ec905f7ed1659f2251045114c785659fbb11ea88philippeUInt   VG_(clo_sim_hints)      = 0;
12141ded2cf9711091a1bc7a6c1dd2d177e978b05e9sewardjBool   VG_(clo_sym_offsets)    = False;
122a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool   VG_(clo_read_inline_info) = False; // Or should be put it to True by default ???
123b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool   VG_(clo_read_var_info)  = False;
1247931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_req_tsyms);  // array of strings
125a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_run_libc_freeres) = True;
126a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_track_fds)      = False;
127a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_below_main)= False;
128a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_emwarns)   = False;
12991b470c367836f65177413ca2a19b25f32fb8ef0sewardjWord   VG_(clo_max_stackframe) = 2000000;
1301e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianUInt   VG_(clo_max_threads)    = MAX_THREADS_DEFAULT;
13195d86c091a218e904e912354efa4f952a9712e82sewardjWord   VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */
132d0720e4a624bdfe7ce2494d690e7a88f986b93c1philippeWord   VG_(clo_valgrind_stacksize) = VG_DEFAULT_STACK_ACTIVE_SZB;
133a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_wait_for_gdb)   = False;
1346c3a219727dead14309abf431f72ca1f99b8ca37sewardjVgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
135ec905f7ed1659f2251045114c785659fbb11ea88philippeUInt   VG_(clo_kernel_variant) = 0;
13697db761d2a94fc7a349aee9359ef85828d9618b6njnBool   VG_(clo_dsymutil)       = False;
137c30cd9bdc3c13c79a2e0281302b115c3d220bc9dsewardjBool   VG_(clo_sigill_diag)    = True;
13849984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
13949984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_frames) = 5;
14049984eadbda78d8edea43f7839f4651a04ca419asewardj
14167f7c0384ad9a590a8c8a9737074168f897e1678sewardj#if defined(VGO_darwin)
14267f7c0384ad9a590a8c8a9737074168f897e1678sewardjUInt VG_(clo_resync_filter) = 1; /* enabled, but quiet */
14367f7c0384ad9a590a8c8a9737074168f897e1678sewardj#else
14467f7c0384ad9a590a8c8a9737074168f897e1678sewardjUInt VG_(clo_resync_filter) = 0; /* disabled */
14567f7c0384ad9a590a8c8a9737074168f897e1678sewardj#endif
14667f7c0384ad9a590a8c8a9737074168f897e1678sewardj
14732824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1486893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
149b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*=== File expansion                                               ===*/
1506893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
1516893d65852940741dbebbc6ba1480e89cf34e30fsewardj
152374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// Copies the string, prepending it with the startup working directory, and
153374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// expanding %p and %q entries.  Returns a new, malloc'd string.
15419f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format)
155374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn{
15629d82f6e5ff3af28950ef6071d231b9633f82a49florian   const HChar *base_dir;
157374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Int len, i = 0, j = 0;
15819f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* out;
159f34ee4e2fec720d392fe8db5b7de57884174654cflorian   const HChar *message = NULL;
160374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
16129d82f6e5ff3af28950ef6071d231b9633f82a49florian   base_dir = VG_(get_startup_wd)();
162374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
163374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (VG_STREQ(format, "")) {
164374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      // Empty name, bad.
165f34ee4e2fec720d392fe8db5b7de57884174654cflorian      message = "No filename given\n";
1665542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn      goto bad;
1675542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   }
1685542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn
1695542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // If 'format' starts with a '~', abort -- the user probably expected the
1705542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // shell to expand but it didn't (see bug 195268 for details).  This means
1715542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // that we don't allow a legitimate filename beginning with '~' but that
1725542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // seems very unlikely.
1735542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   if (format[0] == '~') {
174f34ee4e2fec720d392fe8db5b7de57884174654cflorian      message =
175f34ee4e2fec720d392fe8db5b7de57884174654cflorian         "Filename begins with '~'\n"
176b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You probably expected the shell to expand the '~', but it\n"
177b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "didn't.  The rules for '~'-expansion vary from shell to shell.\n"
178f34ee4e2fec720d392fe8db5b7de57884174654cflorian         "You might have more luck using $HOME instead.\n";
179374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      goto bad;
180374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
181374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
1823e172748981d06fff6b14aaebbabcca898553e98florian   len = VG_(strlen)(format) + 1;
1839c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   out = VG_(malloc)( "options.efn.1", len );
184374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
185374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#define ENSURE_THIS_MUCH_SPACE(x) \
186374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (j + x >= len) { \
187374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      len += (10 + x); \
1889c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      out = VG_(realloc)("options.efn.2(multiple)", out, len); \
189374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
190374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
191374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   while (format[i]) {
192374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      if (format[i] != '%') {
193374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         ENSURE_THIS_MUCH_SPACE(1);
194374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         out[j++] = format[i++];
195374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
196374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      } else {
197374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         // We saw a '%'.  What's next...
198374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         i++;
199374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         if      ('%' == format[i]) {
200374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Replace '%%' with '%'.
201374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(1);
202374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            out[j++] = format[i++];
203374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
204374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else if ('p' == format[i]) {
205374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Print the PID.  Assume that it's not longer than 10 chars --
206374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // reasonable since 'pid' is an Int (ie. 32 bits).
207374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            Int pid = VG_(getpid)();
208374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(10);
209374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            j += VG_(sprintf)(&out[j], "%d", pid);
210374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            i++;
211374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
2122dd08f575042c604cebf32f2c2002a0fba0ed800njn         else if ('q' == format[i]) {
2132dd08f575042c604cebf32f2c2002a0fba0ed800njn            i++;
2142dd08f575042c604cebf32f2c2002a0fba0ed800njn            if ('{' == format[i]) {
2152dd08f575042c604cebf32f2c2002a0fba0ed800njn               // Get the env var name, print its contents.
21657d534d331f7a4ad56e401511a9bca3128c2d671florian               HChar *qual;
21757d534d331f7a4ad56e401511a9bca3128c2d671florian               Int begin_qualname = ++i;
2182dd08f575042c604cebf32f2c2002a0fba0ed800njn               while (True) {
2192dd08f575042c604cebf32f2c2002a0fba0ed800njn                  if (0 == format[i]) {
220f34ee4e2fec720d392fe8db5b7de57884174654cflorian                     message = "Missing '}' in %q specifier\n";
221374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                     goto bad;
2222dd08f575042c604cebf32f2c2002a0fba0ed800njn                  } else if ('}' == format[i]) {
22357d534d331f7a4ad56e401511a9bca3128c2d671florian                     Int qualname_len = i - begin_qualname;
22457d534d331f7a4ad56e401511a9bca3128c2d671florian                     HChar qualname[qualname_len + 1];
22557d534d331f7a4ad56e401511a9bca3128c2d671florian                     VG_(strncpy)(qualname, format + begin_qualname,
22657d534d331f7a4ad56e401511a9bca3128c2d671florian                                  qualname_len);
22757d534d331f7a4ad56e401511a9bca3128c2d671florian                     qualname[qualname_len] = '\0';
2282dd08f575042c604cebf32f2c2002a0fba0ed800njn                     qual = VG_(getenv)(qualname);
2292dd08f575042c604cebf32f2c2002a0fba0ed800njn                     if (NULL == qual) {
230f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        // This memory will leak, But we don't care because
231f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        // VG_(fmsg_bad_option) will terminate the process.
232f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        HChar *str = VG_(malloc)("options.efn.3",
233f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                                 100 + qualname_len);
234f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        VG_(sprintf)(str,
235f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                     "Environment variable '%s' is not set\n",
236f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                     qualname);
237f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        message = str;
2382dd08f575042c604cebf32f2c2002a0fba0ed800njn                        goto bad;
2392dd08f575042c604cebf32f2c2002a0fba0ed800njn                     }
2402dd08f575042c604cebf32f2c2002a0fba0ed800njn                     i++;
2412dd08f575042c604cebf32f2c2002a0fba0ed800njn                     break;
242374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  }
243374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  i++;
244374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn               }
2452dd08f575042c604cebf32f2c2002a0fba0ed800njn               ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual));
2462dd08f575042c604cebf32f2c2002a0fba0ed800njn               j += VG_(sprintf)(&out[j], "%s", qual);
2472dd08f575042c604cebf32f2c2002a0fba0ed800njn            } else {
248f34ee4e2fec720d392fe8db5b7de57884174654cflorian               message = "Expected '{' after '%q'\n";
2492dd08f575042c604cebf32f2c2002a0fba0ed800njn               goto bad;
250374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            }
251374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
252374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else {
253374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Something else, abort.
254f34ee4e2fec720d392fe8db5b7de57884174654cflorian            message = "Expected 'p' or 'q' or '%' after '%'\n";
255374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            goto bad;
256374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
257374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      }
258374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
259374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   ENSURE_THIS_MUCH_SPACE(1);
260374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   out[j++] = 0;
261374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
2623e172748981d06fff6b14aaebbabcca898553e98florian   // If 'out' is not an absolute path name, prefix it with the startup dir.
2633e172748981d06fff6b14aaebbabcca898553e98florian   if (out[0] != '/') {
2643e172748981d06fff6b14aaebbabcca898553e98florian      len = VG_(strlen)(base_dir) + 1 + VG_(strlen)(out) + 1;
2653e172748981d06fff6b14aaebbabcca898553e98florian
2663e172748981d06fff6b14aaebbabcca898553e98florian      HChar *absout = VG_(malloc)("options.efn.4", len);
2673e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcpy)(absout, base_dir);
2683e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, "/");
2693e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, out);
2703e172748981d06fff6b14aaebbabcca898553e98florian      VG_(free)(out);
2713e172748981d06fff6b14aaebbabcca898553e98florian      out = absout;
2723e172748981d06fff6b14aaebbabcca898553e98florian   }
2733e172748981d06fff6b14aaebbabcca898553e98florian
274374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   return out;
275374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
276374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  bad: {
277f34ee4e2fec720d392fe8db5b7de57884174654cflorian   vg_assert(message != NULL);
278f34ee4e2fec720d392fe8db5b7de57884174654cflorian   // 2:  1 for the '=', 1 for the NUL.
279f34ee4e2fec720d392fe8db5b7de57884174654cflorian   HChar opt[VG_(strlen)(option_name) + VG_(strlen)(format) + 2];
280f34ee4e2fec720d392fe8db5b7de57884174654cflorian   VG_(sprintf)(opt, "%s=%s", option_name, format);
281f34ee4e2fec720d392fe8db5b7de57884174654cflorian   VG_(fmsg_bad_option)(opt, "%s", message);
282374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  }
283374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn}
284374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
285064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
286064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*=== --trace-children= support                                    ===*/
287064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
288064212709dc8988a48d2cbde5b90528952d8cd74sewardj
289064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_commas ( HChar const* c ) {
290064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c == ',') {
291064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
292064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
293064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
294064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
295064212709dc8988a48d2cbde5b90528952d8cd74sewardj
296064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_field ( HChar const* c ) {
297064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c != ',') {
298064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
299064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
300064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
301064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
302064212709dc8988a48d2cbde5b90528952d8cd74sewardj
303064212709dc8988a48d2cbde5b90528952d8cd74sewardj/* Should we trace into this child executable (across execve etc) ?
3049ab64a4d3043c251561419d0e0f51492172b1072sewardj   This involves considering --trace-children=,
3059ab64a4d3043c251561419d0e0f51492172b1072sewardj   --trace-children-skip=, --trace-children-skip-by-arg=, and the name
3069ab64a4d3043c251561419d0e0f51492172b1072sewardj   of the executable.  'child_argv' must not include the name of the
3079ab64a4d3043c251561419d0e0f51492172b1072sewardj   executable itself; iow child_argv[0] must be the first arg, if any,
3089ab64a4d3043c251561419d0e0f51492172b1072sewardj   for the child. */
309518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool VG_(should_we_trace_this_child) ( const HChar* child_exe_name,
310518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                       const HChar** child_argv )
311064212709dc8988a48d2cbde5b90528952d8cd74sewardj{
312064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // child_exe_name is pulled out of the guest's space.  We
313064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // should be at least marginally cautious with it, lest it
314064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // explode or burst into flames unexpectedly.
315064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0)
316064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return VG_(clo_trace_children);  // we know narfink
317064212709dc8988a48d2cbde5b90528952d8cd74sewardj
318064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // If --trace-children=no, the answer is simply NO.
319064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (! VG_(clo_trace_children))
320064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return False;
321064212709dc8988a48d2cbde5b90528952d8cd74sewardj
3229ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Otherwise, look for other reasons to say NO.  First,
3239ab64a4d3043c251561419d0e0f51492172b1072sewardj   // see if the exe name matches any of the patterns specified
3249ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip=.
325064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (VG_(clo_trace_children_skip)) {
326064212709dc8988a48d2cbde5b90528952d8cd74sewardj      HChar const* last = VG_(clo_trace_children_skip);
32719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar const* name = child_exe_name;
328064212709dc8988a48d2cbde5b90528952d8cd74sewardj      while (*last) {
329064212709dc8988a48d2cbde5b90528952d8cd74sewardj         Bool   matches;
330064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar* patt;
331064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar const* first = consume_commas(last);
332064212709dc8988a48d2cbde5b90528952d8cd74sewardj         last = consume_field(first);
333064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (first == last)
334064212709dc8988a48d2cbde5b90528952d8cd74sewardj            break;
335064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(last > first);
336064212709dc8988a48d2cbde5b90528952d8cd74sewardj         /* copy the candidate string into a temporary malloc'd block
337064212709dc8988a48d2cbde5b90528952d8cd74sewardj            so we can use VG_(string_match) on it. */
338064212709dc8988a48d2cbde5b90528952d8cd74sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
339064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(memcpy)(patt, first, last - first);
340064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(patt[last-first] == 0);
341064212709dc8988a48d2cbde5b90528952d8cd74sewardj         matches = VG_(string_match)(patt, name);
342064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(free)(patt);
343064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (matches)
344064212709dc8988a48d2cbde5b90528952d8cd74sewardj            return False;
345064212709dc8988a48d2cbde5b90528952d8cd74sewardj      }
346064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
3479ab64a4d3043c251561419d0e0f51492172b1072sewardj
3489ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Check if any of the args match any of the patterns specified
3499ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip-by-arg=.
3509ab64a4d3043c251561419d0e0f51492172b1072sewardj   if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) {
3519ab64a4d3043c251561419d0e0f51492172b1072sewardj      HChar const* last = VG_(clo_trace_children_skip_by_arg);
3529ab64a4d3043c251561419d0e0f51492172b1072sewardj      while (*last) {
3539ab64a4d3043c251561419d0e0f51492172b1072sewardj         Int    i;
3549ab64a4d3043c251561419d0e0f51492172b1072sewardj         Bool   matches;
3559ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar* patt;
3569ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar const* first = consume_commas(last);
3579ab64a4d3043c251561419d0e0f51492172b1072sewardj         last = consume_field(first);
3589ab64a4d3043c251561419d0e0f51492172b1072sewardj         if (first == last)
3599ab64a4d3043c251561419d0e0f51492172b1072sewardj            break;
3609ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(last > first);
3619ab64a4d3043c251561419d0e0f51492172b1072sewardj         /* copy the candidate string into a temporary malloc'd block
3629ab64a4d3043c251561419d0e0f51492172b1072sewardj            so we can use VG_(string_match) on it. */
3639ab64a4d3043c251561419d0e0f51492172b1072sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
3649ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(memcpy)(patt, first, last - first);
3659ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(patt[last-first] == 0);
3669ab64a4d3043c251561419d0e0f51492172b1072sewardj         for (i = 0; child_argv[i]; i++) {
3679ab64a4d3043c251561419d0e0f51492172b1072sewardj            matches = VG_(string_match)(patt, child_argv[i]);
3689ab64a4d3043c251561419d0e0f51492172b1072sewardj            if (matches) {
3699ab64a4d3043c251561419d0e0f51492172b1072sewardj               VG_(free)(patt);
3709ab64a4d3043c251561419d0e0f51492172b1072sewardj               return False;
3719ab64a4d3043c251561419d0e0f51492172b1072sewardj            }
3729ab64a4d3043c251561419d0e0f51492172b1072sewardj         }
3739ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(free)(patt);
3749ab64a4d3043c251561419d0e0f51492172b1072sewardj      }
3759ab64a4d3043c251561419d0e0f51492172b1072sewardj   }
3769ab64a4d3043c251561419d0e0f51492172b1072sewardj
377064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // --trace-children=yes, and this particular executable isn't
378064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // excluded
379064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return True;
380064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
381374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
3826893d65852940741dbebbc6ba1480e89cf34e30fsewardj
38332824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
384b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*--- end                                                          ---*/
38532824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
386