m_options.c revision 1e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3
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)
4132824028b51461062a5a282bfd775d4bd4ad6a47sewardj
42a3506d39c8c94f09837558d33c54b110e1ac0ea1njn// See pub_{core,tool}_options.h for explanations of all these.
43a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
44a3506d39c8c94f09837558d33c54b110e1ac0ea1njn
45a3506d39c8c94f09837558d33c54b110e1ac0ea1njn/* Define, and set defaults. */
468d47a61e503b69ffbc783717f5faf09d0bbc4723sewardj
47a3506d39c8c94f09837558d33c54b110e1ac0ea1njnVexControl VG_(clo_vex_control);
488d47a61e503b69ffbc783717f5faf09d0bbc4723sewardjVexRegisterUpdates VG_(clo_px_file_backed) = VexRegUpd_INVALID;
498d47a61e503b69ffbc783717f5faf09d0bbc4723sewardj
50a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_error_limit)    = True;
51b9779088c43db2a576ae43bde0694411c036b1c4sewardjInt    VG_(clo_error_exitcode) = 0;
527b3d3565c1559b88c67f629bd6613c8b1a89691bphilippeHChar *VG_(clo_error_markers)[2] = {NULL, NULL};
530ba37c90c4674515da387b30a6e5f23fa75a173csewardj
5426ed419d60369d0545510eba0832566e24452e1esewardj#if defined(VGPV_arm_linux_android) \
5526ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_x86_linux_android) \
5626ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_mips32_linux_android) \
5726ed419d60369d0545510eba0832566e24452e1esewardj    || defined(VGPV_arm64_linux_android)
58deddfdfbd13203804737b95b6bf5861f758ac865sewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
59deddfdfbd13203804737b95b6bf5861f758ac865sewardj#else
600ba37c90c4674515da387b30a6e5f23fa75a173csewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
61deddfdfbd13203804737b95b6bf5861f758ac865sewardj#endif
623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_poll)      = 5000;
633b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_error)     = 999999999;
64180a7500bf2464d5b16cddb5618b91fb3f095998philippeUInt   VG_(clo_vgdb_stop_at)   = 0;
65cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(clo_vgdb_prefix)    = NULL;
66cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(arg_vgdb_prefix)    = NULL;
673b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool   VG_(clo_vgdb_shadow_registers) = False;
680ba37c90c4674515da387b30a6e5f23fa75a173csewardj
69a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_db_attach)      = False;
7019f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar*  VG_(clo_db_command)     = GDB_PATH " -nw %f %p";
71a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_gen_suppressions) = 0;
72a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_sanity_level)   = 1;
73a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_verbosity)      = 1;
742d9e874b7a628ada216f09cc4f065798c65fffa4sewardjBool   VG_(clo_stats)          = False;
7571bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardjBool   VG_(clo_xml)            = False;
7619f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_xml_user_comment) = NULL;
77a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_demangle)       = True;
7819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_soname_synonyms)    = NULL;
79a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_children) = False;
8019f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip) = NULL;
8119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
826e31f80899f1c79a54f164955069f3f74fe8b7e2sewardjBool   VG_(clo_child_silent_after_fork) = False;
83518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* VG_(clo_log_fname_expanded) = NULL;
84518850bf0da07ed3e2244e307268ae0fd80e93a8florianconst HChar* VG_(clo_xml_fname_expanded) = NULL;
85a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_time_stamp)     = False;
86a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_input_fd)       = 0; /* stdin */
872c68e3eff3850e2d466774d152231e628107a28fbartBool   VG_(clo_default_supp)   = True;
887931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_suppressions);   // array of strings
897931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_fullpath_after); // array of strings
9071826f77dbaefb6a9c694d9711aa649ed0980cc7sewardjconst HChar* VG_(clo_extra_debuginfo_path) = NULL;
915d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjconst HChar* VG_(clo_debuginfo_server) = NULL;
925d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjBool   VG_(clo_allow_mismatched_debuginfo) = False;
93a3506d39c8c94f09837558d33c54b110e1ac0ea1njnUChar  VG_(clo_trace_flags)    = 0; // 00000000b
9417c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjBool   VG_(clo_profyle_sbs)    = False;
9517c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjUChar  VG_(clo_profyle_flags)  = 0; // 00000000b
9617c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjULong  VG_(clo_profyle_interval) = 0;
9729e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notbelow) = -1;  // unspecified
9829e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notabove) = -1;  // unspecified
99a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_syscalls) = False;
100a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_signals)  = False;
101a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_symtab)   = False;
10219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_symtab_patt) = "*";
103a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_cfi)      = False;
104f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_syms) = False;
105f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_line) = False;
106f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_frames) = False;
107a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_redir)    = False;
10878bfc711d3e684c76eeab5f89a94a78d40ed6f4bbartenum FairSchedType
10978bfc711d3e684c76eeab5f89a94a78d40ed6f4bbart       VG_(clo_fair_sched)     = disable_fair_sched;
110a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_sched)    = False;
1119c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjBool   VG_(clo_profile_heap)   = False;
112d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_core_redzone_size) = CORE_REDZONE_DEFAULT_SZB;
113d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// A value != -1 overrides the tool-specific value
114d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// VG_(needs_malloc_replacement).tool_client_redzone_szB
115d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_redzone_size)   = -1;
116a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_dump_error)     = 0;
117a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_backtrace_size) = 12;
11846207652a0c99a2c8b0f05eafce3ca3ec533c121philippeInt    VG_(clo_merge_recursive_frames) = 0; // default value: no merge
119ec905f7ed1659f2251045114c785659fbb11ea88philippeUInt   VG_(clo_sim_hints)      = 0;
12041ded2cf9711091a1bc7a6c1dd2d177e978b05e9sewardjBool   VG_(clo_sym_offsets)    = False;
121a0a73939b0398b6608fd6dbde49820ce6530d12cphilippeBool   VG_(clo_read_inline_info) = False; // Or should be put it to True by default ???
122b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool   VG_(clo_read_var_info)  = False;
1237931627282eede4440f3f329b657c3ec68371e8aflorianXArray *VG_(clo_req_tsyms);  // array of strings
124a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_run_libc_freeres) = True;
125a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_track_fds)      = False;
126a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_below_main)= False;
127a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_emwarns)   = False;
12891b470c367836f65177413ca2a19b25f32fb8ef0sewardjWord   VG_(clo_max_stackframe) = 2000000;
1291e802b6a8d0d4b7b630d2a1dd9683c7c889b01a3florianUInt   VG_(clo_max_threads)    = MAX_THREADS_DEFAULT;
13095d86c091a218e904e912354efa4f952a9712e82sewardjWord   VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */
131a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_wait_for_gdb)   = False;
1326c3a219727dead14309abf431f72ca1f99b8ca37sewardjVgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
133ec905f7ed1659f2251045114c785659fbb11ea88philippeUInt   VG_(clo_kernel_variant) = 0;
13497db761d2a94fc7a349aee9359ef85828d9618b6njnBool   VG_(clo_dsymutil)       = False;
135c30cd9bdc3c13c79a2e0281302b115c3d220bc9dsewardjBool   VG_(clo_sigill_diag)    = True;
13649984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
13749984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_frames) = 5;
13849984eadbda78d8edea43f7839f4651a04ca419asewardj
13967f7c0384ad9a590a8c8a9737074168f897e1678sewardj#if defined(VGO_darwin)
14067f7c0384ad9a590a8c8a9737074168f897e1678sewardjUInt VG_(clo_resync_filter) = 1; /* enabled, but quiet */
14167f7c0384ad9a590a8c8a9737074168f897e1678sewardj#else
14267f7c0384ad9a590a8c8a9737074168f897e1678sewardjUInt VG_(clo_resync_filter) = 0; /* disabled */
14367f7c0384ad9a590a8c8a9737074168f897e1678sewardj#endif
14467f7c0384ad9a590a8c8a9737074168f897e1678sewardj
14532824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1466893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
147b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*=== File expansion                                               ===*/
1486893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
1496893d65852940741dbebbc6ba1480e89cf34e30fsewardj
150374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// Copies the string, prepending it with the startup working directory, and
151374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// expanding %p and %q entries.  Returns a new, malloc'd string.
15219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format)
153374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn{
15429d82f6e5ff3af28950ef6071d231b9633f82a49florian   const HChar *base_dir;
155374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Int len, i = 0, j = 0;
15619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* out;
157f34ee4e2fec720d392fe8db5b7de57884174654cflorian   const HChar *message = NULL;
158374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
15929d82f6e5ff3af28950ef6071d231b9633f82a49florian   base_dir = VG_(get_startup_wd)();
160374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
161374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (VG_STREQ(format, "")) {
162374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      // Empty name, bad.
163f34ee4e2fec720d392fe8db5b7de57884174654cflorian      message = "No filename given\n";
1645542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn      goto bad;
1655542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   }
1665542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn
1675542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // If 'format' starts with a '~', abort -- the user probably expected the
1685542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // shell to expand but it didn't (see bug 195268 for details).  This means
1695542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // that we don't allow a legitimate filename beginning with '~' but that
1705542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // seems very unlikely.
1715542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   if (format[0] == '~') {
172f34ee4e2fec720d392fe8db5b7de57884174654cflorian      message =
173f34ee4e2fec720d392fe8db5b7de57884174654cflorian         "Filename begins with '~'\n"
174b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You probably expected the shell to expand the '~', but it\n"
175b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "didn't.  The rules for '~'-expansion vary from shell to shell.\n"
176f34ee4e2fec720d392fe8db5b7de57884174654cflorian         "You might have more luck using $HOME instead.\n";
177374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      goto bad;
178374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
179374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
1803e172748981d06fff6b14aaebbabcca898553e98florian   len = VG_(strlen)(format) + 1;
1819c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   out = VG_(malloc)( "options.efn.1", len );
182374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
183374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#define ENSURE_THIS_MUCH_SPACE(x) \
184374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (j + x >= len) { \
185374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      len += (10 + x); \
1869c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      out = VG_(realloc)("options.efn.2(multiple)", out, len); \
187374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
188374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
189374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   while (format[i]) {
190374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      if (format[i] != '%') {
191374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         ENSURE_THIS_MUCH_SPACE(1);
192374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         out[j++] = format[i++];
193374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
194374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      } else {
195374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         // We saw a '%'.  What's next...
196374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         i++;
197374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         if      ('%' == format[i]) {
198374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Replace '%%' with '%'.
199374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(1);
200374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            out[j++] = format[i++];
201374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
202374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else if ('p' == format[i]) {
203374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Print the PID.  Assume that it's not longer than 10 chars --
204374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // reasonable since 'pid' is an Int (ie. 32 bits).
205374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            Int pid = VG_(getpid)();
206374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(10);
207374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            j += VG_(sprintf)(&out[j], "%d", pid);
208374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            i++;
209374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
2102dd08f575042c604cebf32f2c2002a0fba0ed800njn         else if ('q' == format[i]) {
2112dd08f575042c604cebf32f2c2002a0fba0ed800njn            i++;
2122dd08f575042c604cebf32f2c2002a0fba0ed800njn            if ('{' == format[i]) {
2132dd08f575042c604cebf32f2c2002a0fba0ed800njn               // Get the env var name, print its contents.
21457d534d331f7a4ad56e401511a9bca3128c2d671florian               HChar *qual;
21557d534d331f7a4ad56e401511a9bca3128c2d671florian               Int begin_qualname = ++i;
2162dd08f575042c604cebf32f2c2002a0fba0ed800njn               while (True) {
2172dd08f575042c604cebf32f2c2002a0fba0ed800njn                  if (0 == format[i]) {
218f34ee4e2fec720d392fe8db5b7de57884174654cflorian                     message = "Missing '}' in %q specifier\n";
219374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                     goto bad;
2202dd08f575042c604cebf32f2c2002a0fba0ed800njn                  } else if ('}' == format[i]) {
22157d534d331f7a4ad56e401511a9bca3128c2d671florian                     Int qualname_len = i - begin_qualname;
22257d534d331f7a4ad56e401511a9bca3128c2d671florian                     HChar qualname[qualname_len + 1];
22357d534d331f7a4ad56e401511a9bca3128c2d671florian                     VG_(strncpy)(qualname, format + begin_qualname,
22457d534d331f7a4ad56e401511a9bca3128c2d671florian                                  qualname_len);
22557d534d331f7a4ad56e401511a9bca3128c2d671florian                     qualname[qualname_len] = '\0';
2262dd08f575042c604cebf32f2c2002a0fba0ed800njn                     qual = VG_(getenv)(qualname);
2272dd08f575042c604cebf32f2c2002a0fba0ed800njn                     if (NULL == qual) {
228f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        // This memory will leak, But we don't care because
229f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        // VG_(fmsg_bad_option) will terminate the process.
230f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        HChar *str = VG_(malloc)("options.efn.3",
231f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                                 100 + qualname_len);
232f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        VG_(sprintf)(str,
233f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                     "Environment variable '%s' is not set\n",
234f34ee4e2fec720d392fe8db5b7de57884174654cflorian                                     qualname);
235f34ee4e2fec720d392fe8db5b7de57884174654cflorian                        message = str;
2362dd08f575042c604cebf32f2c2002a0fba0ed800njn                        goto bad;
2372dd08f575042c604cebf32f2c2002a0fba0ed800njn                     }
2382dd08f575042c604cebf32f2c2002a0fba0ed800njn                     i++;
2392dd08f575042c604cebf32f2c2002a0fba0ed800njn                     break;
240374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  }
241374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  i++;
242374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn               }
2432dd08f575042c604cebf32f2c2002a0fba0ed800njn               ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual));
2442dd08f575042c604cebf32f2c2002a0fba0ed800njn               j += VG_(sprintf)(&out[j], "%s", qual);
2452dd08f575042c604cebf32f2c2002a0fba0ed800njn            } else {
246f34ee4e2fec720d392fe8db5b7de57884174654cflorian               message = "Expected '{' after '%q'\n";
2472dd08f575042c604cebf32f2c2002a0fba0ed800njn               goto bad;
248374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            }
249374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
250374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else {
251374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Something else, abort.
252f34ee4e2fec720d392fe8db5b7de57884174654cflorian            message = "Expected 'p' or 'q' or '%' after '%'\n";
253374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            goto bad;
254374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
255374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      }
256374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
257374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   ENSURE_THIS_MUCH_SPACE(1);
258374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   out[j++] = 0;
259374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
2603e172748981d06fff6b14aaebbabcca898553e98florian   // If 'out' is not an absolute path name, prefix it with the startup dir.
2613e172748981d06fff6b14aaebbabcca898553e98florian   if (out[0] != '/') {
2623e172748981d06fff6b14aaebbabcca898553e98florian      len = VG_(strlen)(base_dir) + 1 + VG_(strlen)(out) + 1;
2633e172748981d06fff6b14aaebbabcca898553e98florian
2643e172748981d06fff6b14aaebbabcca898553e98florian      HChar *absout = VG_(malloc)("options.efn.4", len);
2653e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcpy)(absout, base_dir);
2663e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, "/");
2673e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, out);
2683e172748981d06fff6b14aaebbabcca898553e98florian      VG_(free)(out);
2693e172748981d06fff6b14aaebbabcca898553e98florian      out = absout;
2703e172748981d06fff6b14aaebbabcca898553e98florian   }
2713e172748981d06fff6b14aaebbabcca898553e98florian
272374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   return out;
273374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
274374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  bad: {
275f34ee4e2fec720d392fe8db5b7de57884174654cflorian   vg_assert(message != NULL);
276f34ee4e2fec720d392fe8db5b7de57884174654cflorian   // 2:  1 for the '=', 1 for the NUL.
277f34ee4e2fec720d392fe8db5b7de57884174654cflorian   HChar opt[VG_(strlen)(option_name) + VG_(strlen)(format) + 2];
278f34ee4e2fec720d392fe8db5b7de57884174654cflorian   VG_(sprintf)(opt, "%s=%s", option_name, format);
279f34ee4e2fec720d392fe8db5b7de57884174654cflorian   VG_(fmsg_bad_option)(opt, "%s", message);
280374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  }
281374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn}
282374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
283064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
284064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*=== --trace-children= support                                    ===*/
285064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
286064212709dc8988a48d2cbde5b90528952d8cd74sewardj
287064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_commas ( HChar const* c ) {
288064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c == ',') {
289064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
290064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
291064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
292064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
293064212709dc8988a48d2cbde5b90528952d8cd74sewardj
294064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_field ( HChar const* c ) {
295064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c != ',') {
296064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
297064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
298064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
299064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
300064212709dc8988a48d2cbde5b90528952d8cd74sewardj
301064212709dc8988a48d2cbde5b90528952d8cd74sewardj/* Should we trace into this child executable (across execve etc) ?
3029ab64a4d3043c251561419d0e0f51492172b1072sewardj   This involves considering --trace-children=,
3039ab64a4d3043c251561419d0e0f51492172b1072sewardj   --trace-children-skip=, --trace-children-skip-by-arg=, and the name
3049ab64a4d3043c251561419d0e0f51492172b1072sewardj   of the executable.  'child_argv' must not include the name of the
3059ab64a4d3043c251561419d0e0f51492172b1072sewardj   executable itself; iow child_argv[0] must be the first arg, if any,
3069ab64a4d3043c251561419d0e0f51492172b1072sewardj   for the child. */
307518850bf0da07ed3e2244e307268ae0fd80e93a8florianBool VG_(should_we_trace_this_child) ( const HChar* child_exe_name,
308518850bf0da07ed3e2244e307268ae0fd80e93a8florian                                       const HChar** child_argv )
309064212709dc8988a48d2cbde5b90528952d8cd74sewardj{
310064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // child_exe_name is pulled out of the guest's space.  We
311064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // should be at least marginally cautious with it, lest it
312064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // explode or burst into flames unexpectedly.
313064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0)
314064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return VG_(clo_trace_children);  // we know narfink
315064212709dc8988a48d2cbde5b90528952d8cd74sewardj
316064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // If --trace-children=no, the answer is simply NO.
317064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (! VG_(clo_trace_children))
318064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return False;
319064212709dc8988a48d2cbde5b90528952d8cd74sewardj
3209ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Otherwise, look for other reasons to say NO.  First,
3219ab64a4d3043c251561419d0e0f51492172b1072sewardj   // see if the exe name matches any of the patterns specified
3229ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip=.
323064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (VG_(clo_trace_children_skip)) {
324064212709dc8988a48d2cbde5b90528952d8cd74sewardj      HChar const* last = VG_(clo_trace_children_skip);
32519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar const* name = child_exe_name;
326064212709dc8988a48d2cbde5b90528952d8cd74sewardj      while (*last) {
327064212709dc8988a48d2cbde5b90528952d8cd74sewardj         Bool   matches;
328064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar* patt;
329064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar const* first = consume_commas(last);
330064212709dc8988a48d2cbde5b90528952d8cd74sewardj         last = consume_field(first);
331064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (first == last)
332064212709dc8988a48d2cbde5b90528952d8cd74sewardj            break;
333064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(last > first);
334064212709dc8988a48d2cbde5b90528952d8cd74sewardj         /* copy the candidate string into a temporary malloc'd block
335064212709dc8988a48d2cbde5b90528952d8cd74sewardj            so we can use VG_(string_match) on it. */
336064212709dc8988a48d2cbde5b90528952d8cd74sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
337064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(memcpy)(patt, first, last - first);
338064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(patt[last-first] == 0);
339064212709dc8988a48d2cbde5b90528952d8cd74sewardj         matches = VG_(string_match)(patt, name);
340064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(free)(patt);
341064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (matches)
342064212709dc8988a48d2cbde5b90528952d8cd74sewardj            return False;
343064212709dc8988a48d2cbde5b90528952d8cd74sewardj      }
344064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
3459ab64a4d3043c251561419d0e0f51492172b1072sewardj
3469ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Check if any of the args match any of the patterns specified
3479ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip-by-arg=.
3489ab64a4d3043c251561419d0e0f51492172b1072sewardj   if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) {
3499ab64a4d3043c251561419d0e0f51492172b1072sewardj      HChar const* last = VG_(clo_trace_children_skip_by_arg);
3509ab64a4d3043c251561419d0e0f51492172b1072sewardj      while (*last) {
3519ab64a4d3043c251561419d0e0f51492172b1072sewardj         Int    i;
3529ab64a4d3043c251561419d0e0f51492172b1072sewardj         Bool   matches;
3539ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar* patt;
3549ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar const* first = consume_commas(last);
3559ab64a4d3043c251561419d0e0f51492172b1072sewardj         last = consume_field(first);
3569ab64a4d3043c251561419d0e0f51492172b1072sewardj         if (first == last)
3579ab64a4d3043c251561419d0e0f51492172b1072sewardj            break;
3589ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(last > first);
3599ab64a4d3043c251561419d0e0f51492172b1072sewardj         /* copy the candidate string into a temporary malloc'd block
3609ab64a4d3043c251561419d0e0f51492172b1072sewardj            so we can use VG_(string_match) on it. */
3619ab64a4d3043c251561419d0e0f51492172b1072sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
3629ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(memcpy)(patt, first, last - first);
3639ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(patt[last-first] == 0);
3649ab64a4d3043c251561419d0e0f51492172b1072sewardj         for (i = 0; child_argv[i]; i++) {
3659ab64a4d3043c251561419d0e0f51492172b1072sewardj            matches = VG_(string_match)(patt, child_argv[i]);
3669ab64a4d3043c251561419d0e0f51492172b1072sewardj            if (matches) {
3679ab64a4d3043c251561419d0e0f51492172b1072sewardj               VG_(free)(patt);
3689ab64a4d3043c251561419d0e0f51492172b1072sewardj               return False;
3699ab64a4d3043c251561419d0e0f51492172b1072sewardj            }
3709ab64a4d3043c251561419d0e0f51492172b1072sewardj         }
3719ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(free)(patt);
3729ab64a4d3043c251561419d0e0f51492172b1072sewardj      }
3739ab64a4d3043c251561419d0e0f51492172b1072sewardj   }
3749ab64a4d3043c251561419d0e0f51492172b1072sewardj
375064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // --trace-children=yes, and this particular executable isn't
376064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // excluded
377064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return True;
378064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
379374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
3806893d65852940741dbebbc6ba1480e89cf34e30fsewardj
38132824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
382b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*--- end                                                          ---*/
38332824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
384