m_options.c revision 180a7500bf2464d5b16cddb5618b91fb3f095998
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. */
46a3506d39c8c94f09837558d33c54b110e1ac0ea1njnVexControl VG_(clo_vex_control);
47a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_error_limit)    = True;
48b9779088c43db2a576ae43bde0694411c036b1c4sewardjInt    VG_(clo_error_exitcode) = 0;
490ba37c90c4674515da387b30a6e5f23fa75a173csewardj
509c6b05db45362b1afb981aa8298ab12ab4027b1adejanj#if defined(VGPV_arm_linux_android) || defined(VGPV_x86_linux_android) \
51f0c1250e324f6684757c6a15545366447ef1d64fsewardj    || defined(VGPV_mips32_linux_android) \
52f0c1250e324f6684757c6a15545366447ef1d64fsewardj    || defined(VGP_arm64_linux) // temporarily disabled on arm64-linux
53deddfdfbd13203804737b95b6bf5861f758ac865sewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbNo; // currently disabled on Android
54deddfdfbd13203804737b95b6bf5861f758ac865sewardj#else
550ba37c90c4674515da387b30a6e5f23fa75a173csewardjVgVgdb VG_(clo_vgdb)           = Vg_VgdbYes;
56deddfdfbd13203804737b95b6bf5861f758ac865sewardj#endif
573b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_poll)      = 5000;
583b290486cd4cd601b20e04340e593c9ed9717e5fsewardjInt    VG_(clo_vgdb_error)     = 999999999;
59180a7500bf2464d5b16cddb5618b91fb3f095998philippeUInt   VG_(clo_vgdb_stop_at)   = 0;
60cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(clo_vgdb_prefix)    = NULL;
61cffe2a55d903655761ccc6025a23b823bee10170philippeconst HChar *VG_(arg_vgdb_prefix)    = NULL;
623b290486cd4cd601b20e04340e593c9ed9717e5fsewardjBool   VG_(clo_vgdb_shadow_registers) = False;
630ba37c90c4674515da387b30a6e5f23fa75a173csewardj
64a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_db_attach)      = False;
6519f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar*  VG_(clo_db_command)     = GDB_PATH " -nw %f %p";
66a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_gen_suppressions) = 0;
67a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_sanity_level)   = 1;
68a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_verbosity)      = 1;
692d9e874b7a628ada216f09cc4f065798c65fffa4sewardjBool   VG_(clo_stats)          = False;
7071bc3cbb1b6da72fe1d3a9fea90e53847c5b0a6fsewardjBool   VG_(clo_xml)            = False;
7119f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_xml_user_comment) = NULL;
72a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_demangle)       = True;
7319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_soname_synonyms)    = NULL;
74a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_children) = False;
7519f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip) = NULL;
7619f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_children_skip_by_arg) = NULL;
776e31f80899f1c79a54f164955069f3f74fe8b7e2sewardjBool   VG_(clo_child_silent_after_fork) = False;
7819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(clo_log_fname_expanded) = NULL;
7919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(clo_xml_fname_expanded) = NULL;
80a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_time_stamp)     = False;
81a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_input_fd)       = 0; /* stdin */
82a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_n_suppressions) = 0;
8319f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_suppressions)[VG_CLO_MAX_SFILES];
8414cdbf8f4ac7e49de2bced6546f7867b2e0655f0sewardjInt    VG_(clo_n_fullpath_after) = 0;
8519f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_fullpath_after)[VG_CLO_MAX_FULLPATH_AFTER];
8671826f77dbaefb6a9c694d9711aa649ed0980cc7sewardjconst HChar* VG_(clo_extra_debuginfo_path) = NULL;
875d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjconst HChar* VG_(clo_debuginfo_server) = NULL;
885d616dfbb8439dfd51a40ddf1dba970938baa1ebsewardjBool   VG_(clo_allow_mismatched_debuginfo) = False;
89a3506d39c8c94f09837558d33c54b110e1ac0ea1njnUChar  VG_(clo_trace_flags)    = 0; // 00000000b
9017c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjBool   VG_(clo_profyle_sbs)    = False;
9117c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjUChar  VG_(clo_profyle_flags)  = 0; // 00000000b
9217c5e2e3a2f48970063ea43a9abee3e11c72cb04sewardjULong  VG_(clo_profyle_interval) = 0;
9329e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notbelow) = -1;  // unspecified
9429e022d85378cd303e00c1ec7a8dd60aaed9145aflorianInt    VG_(clo_trace_notabove) = -1;  // unspecified
95a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_syscalls) = False;
96a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_signals)  = False;
97a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_symtab)   = False;
9819f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_trace_symtab_patt) = "*";
99a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_cfi)      = False;
100f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_syms) = False;
101f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_line) = False;
102f767d967b9ef331dcd7d0cd4584f6570cd829333sewardjBool   VG_(clo_debug_dump_frames) = False;
103a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_redir)    = False;
10478bfc711d3e684c76eeab5f89a94a78d40ed6f4bbartenum FairSchedType
10578bfc711d3e684c76eeab5f89a94a78d40ed6f4bbart       VG_(clo_fair_sched)     = disable_fair_sched;
106a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_trace_sched)    = False;
1079c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardjBool   VG_(clo_profile_heap)   = False;
108d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_core_redzone_size) = CORE_REDZONE_DEFAULT_SZB;
109d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// A value != -1 overrides the tool-specific value
110d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippe// VG_(needs_malloc_replacement).tool_client_redzone_szB
111d99c26a4bc18fd3b17c4626c9c1fbd1583388660philippeInt    VG_(clo_redzone_size)   = -1;
112a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_dump_error)     = 0;
113a3506d39c8c94f09837558d33c54b110e1ac0ea1njnInt    VG_(clo_backtrace_size) = 12;
11446207652a0c99a2c8b0f05eafce3ca3ec533c121philippeInt    VG_(clo_merge_recursive_frames) = 0; // default value: no merge
11519f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_sim_hints)      = NULL;
11641ded2cf9711091a1bc7a6c1dd2d177e978b05e9sewardjBool   VG_(clo_sym_offsets)    = False;
117b8b79addf04dd5d0b558916e26df0b1927cbd758sewardjBool   VG_(clo_read_var_info)  = False;
118f9ebc3956087ce01561c4ab3faf5a8983b0f7c1csewardjInt    VG_(clo_n_req_tsyms)    = 0;
11919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_req_tsyms)[VG_CLO_MAX_REQ_TSYMS];
120f9ebc3956087ce01561c4ab3faf5a8983b0f7c1csewardjHChar* VG_(clo_require_text_symbol) = NULL;
121a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_run_libc_freeres) = True;
122a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_track_fds)      = False;
123a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_below_main)= False;
124a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_show_emwarns)   = False;
12591b470c367836f65177413ca2a19b25f32fb8ef0sewardjWord   VG_(clo_max_stackframe) = 2000000;
12695d86c091a218e904e912354efa4f952a9712e82sewardjWord   VG_(clo_main_stacksize) = 0; /* use client's rlimit.stack */
127a3506d39c8c94f09837558d33c54b110e1ac0ea1njnBool   VG_(clo_wait_for_gdb)   = False;
1286c3a219727dead14309abf431f72ca1f99b8ca37sewardjVgSmc  VG_(clo_smc_check)      = Vg_SmcStack;
12919f91bbaedb4caef8a60ce94b0f507193cc0bc10florianconst HChar* VG_(clo_kernel_variant) = NULL;
13097db761d2a94fc7a349aee9359ef85828d9618b6njnBool   VG_(clo_dsymutil)       = False;
131c30cd9bdc3c13c79a2e0281302b115c3d220bc9dsewardjBool   VG_(clo_sigill_diag)    = True;
13249984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_thresh) = 0; /* disabled by default */
13349984eadbda78d8edea43f7839f4651a04ca419asewardjUInt   VG_(clo_unw_stack_scan_frames) = 5;
13449984eadbda78d8edea43f7839f4651a04ca419asewardj
13532824028b51461062a5a282bfd775d4bd4ad6a47sewardj
1366893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
137b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*=== File expansion                                               ===*/
1386893d65852940741dbebbc6ba1480e89cf34e30fsewardj/*====================================================================*/
1396893d65852940741dbebbc6ba1480e89cf34e30fsewardj
140374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// Copies the string, prepending it with the startup working directory, and
141374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn// expanding %p and %q entries.  Returns a new, malloc'd string.
14219f91bbaedb4caef8a60ce94b0f507193cc0bc10florianHChar* VG_(expand_file_name)(const HChar* option_name, const HChar* format)
143374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn{
14419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   static HChar base_dir[VKI_PATH_MAX];
145374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Int len, i = 0, j = 0;
14619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* out;
147374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
148374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   Bool ok = VG_(get_startup_wd)(base_dir, VKI_PATH_MAX);
149374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   tl_assert(ok);
150374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
151374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (VG_STREQ(format, "")) {
152374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      // Empty name, bad.
153b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      VG_(fmsg)("%s: filename is empty", option_name);
1545542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn      goto bad;
1555542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   }
1565542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn
1575542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // If 'format' starts with a '~', abort -- the user probably expected the
1585542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // shell to expand but it didn't (see bug 195268 for details).  This means
1595542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // that we don't allow a legitimate filename beginning with '~' but that
1605542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   // seems very unlikely.
1615542d8f5047c4f59ed60e72c2d0f1b1d4d149ea8njn   if (format[0] == '~') {
162b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      VG_(fmsg)(
163b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "%s: filename begins with '~'\n"
164b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You probably expected the shell to expand the '~', but it\n"
165b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "didn't.  The rules for '~'-expansion vary from shell to shell.\n"
166b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         "You might have more luck using $HOME instead.\n",
167b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn         option_name
168b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn      );
169374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      goto bad;
170374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
171374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
1723e172748981d06fff6b14aaebbabcca898553e98florian   len = VG_(strlen)(format) + 1;
1739c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj   out = VG_(malloc)( "options.efn.1", len );
174374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
175374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn#define ENSURE_THIS_MUCH_SPACE(x) \
176374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   if (j + x >= len) { \
177374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      len += (10 + x); \
1789c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      out = VG_(realloc)("options.efn.2(multiple)", out, len); \
179374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
180374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
181374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   while (format[i]) {
182374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      if (format[i] != '%') {
183374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         ENSURE_THIS_MUCH_SPACE(1);
184374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         out[j++] = format[i++];
185374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
186374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      } else {
187374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         // We saw a '%'.  What's next...
188374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         i++;
189374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         if      ('%' == format[i]) {
190374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Replace '%%' with '%'.
191374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(1);
192374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            out[j++] = format[i++];
193374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
194374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else if ('p' == format[i]) {
195374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Print the PID.  Assume that it's not longer than 10 chars --
196374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // reasonable since 'pid' is an Int (ie. 32 bits).
197374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            Int pid = VG_(getpid)();
198374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            ENSURE_THIS_MUCH_SPACE(10);
199374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            j += VG_(sprintf)(&out[j], "%d", pid);
200374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            i++;
201374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
2022dd08f575042c604cebf32f2c2002a0fba0ed800njn         else if ('q' == format[i]) {
2032dd08f575042c604cebf32f2c2002a0fba0ed800njn            i++;
2042dd08f575042c604cebf32f2c2002a0fba0ed800njn            if ('{' == format[i]) {
2052dd08f575042c604cebf32f2c2002a0fba0ed800njn               // Get the env var name, print its contents.
20619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian               const HChar* qualname;
20719f91bbaedb4caef8a60ce94b0f507193cc0bc10florian               HChar* qual;
2082dd08f575042c604cebf32f2c2002a0fba0ed800njn               i++;
2092dd08f575042c604cebf32f2c2002a0fba0ed800njn               qualname = &format[i];
2102dd08f575042c604cebf32f2c2002a0fba0ed800njn               while (True) {
2112dd08f575042c604cebf32f2c2002a0fba0ed800njn                  if (0 == format[i]) {
212b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                     VG_(fmsg)("%s: malformed %%q specifier\n", option_name);
213374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                     goto bad;
2142dd08f575042c604cebf32f2c2002a0fba0ed800njn                  } else if ('}' == format[i]) {
2152dd08f575042c604cebf32f2c2002a0fba0ed800njn                     // Temporarily replace the '}' with NUL to extract var
2162dd08f575042c604cebf32f2c2002a0fba0ed800njn                     // name.
217cfea784f4432d0ec79e9360ad324b820faada649florian                     // FIXME: this is not safe as FORMAT is sometimes a
218cfea784f4432d0ec79e9360ad324b820faada649florian                     // string literal which may reside in read-only memory
21919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                    ((HChar *)format)[i] = 0;
2202dd08f575042c604cebf32f2c2002a0fba0ed800njn                     qual = VG_(getenv)(qualname);
2212dd08f575042c604cebf32f2c2002a0fba0ed800njn                     if (NULL == qual) {
222b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                        VG_(fmsg)("%s: environment variable %s is not set\n",
223b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                                  option_name, qualname);
22419f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // FIXME: this is not safe as FORMAT is sometimes a
22519f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // string literal which may reside in read-only memory
22619f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                        ((HChar *)format)[i] = '}';  // Put the '}' back.
2272dd08f575042c604cebf32f2c2002a0fba0ed800njn                        goto bad;
2282dd08f575042c604cebf32f2c2002a0fba0ed800njn                     }
22919f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // FIXME: this is not safe as FORMAT is sometimes a
23019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     // string literal which may reside in read-only memory
23119f91bbaedb4caef8a60ce94b0f507193cc0bc10florian                     ((HChar *)format)[i] = '}';     // Put the '}' back.
2322dd08f575042c604cebf32f2c2002a0fba0ed800njn                     i++;
2332dd08f575042c604cebf32f2c2002a0fba0ed800njn                     break;
234374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  }
235374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn                  i++;
236374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn               }
2372dd08f575042c604cebf32f2c2002a0fba0ed800njn               ENSURE_THIS_MUCH_SPACE(VG_(strlen)(qual));
2382dd08f575042c604cebf32f2c2002a0fba0ed800njn               j += VG_(sprintf)(&out[j], "%s", qual);
2392dd08f575042c604cebf32f2c2002a0fba0ed800njn            } else {
240b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn               VG_(fmsg)("%s: expected '{' after '%%q'\n", option_name);
2412dd08f575042c604cebf32f2c2002a0fba0ed800njn               goto bad;
242374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            }
243374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
244374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         else {
245374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            // Something else, abort.
246b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn            VG_(fmsg)("%s: expected 'p' or 'q' or '%%' after '%%'\n",
247b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn                      option_name);
248374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn            goto bad;
249374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn         }
250374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn      }
251374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   }
252374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   ENSURE_THIS_MUCH_SPACE(1);
253374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   out[j++] = 0;
254374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
2553e172748981d06fff6b14aaebbabcca898553e98florian   // If 'out' is not an absolute path name, prefix it with the startup dir.
2563e172748981d06fff6b14aaebbabcca898553e98florian   if (out[0] != '/') {
2573e172748981d06fff6b14aaebbabcca898553e98florian      len = VG_(strlen)(base_dir) + 1 + VG_(strlen)(out) + 1;
2583e172748981d06fff6b14aaebbabcca898553e98florian
2593e172748981d06fff6b14aaebbabcca898553e98florian      HChar *absout = VG_(malloc)("options.efn.4", len);
2603e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcpy)(absout, base_dir);
2613e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, "/");
2623e172748981d06fff6b14aaebbabcca898553e98florian      VG_(strcat)(absout, out);
2633e172748981d06fff6b14aaebbabcca898553e98florian      VG_(free)(out);
2643e172748981d06fff6b14aaebbabcca898553e98florian      out = absout;
2653e172748981d06fff6b14aaebbabcca898553e98florian   }
2663e172748981d06fff6b14aaebbabcca898553e98florian
267374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   return out;
268374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
269374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  bad: {
27019f91bbaedb4caef8a60ce94b0f507193cc0bc10florian   HChar* opt =    // 2:  1 for the '=', 1 for the NUL.
2719c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj      VG_(malloc)( "options.efn.3",
2729c606bd8634cd6b67bb41fa645b5c639668cfa2dsewardj                   VG_(strlen)(option_name) + VG_(strlen)(format) + 2 );
273374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcpy)(opt, option_name);
274374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcat)(opt, "=");
275374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn   VG_(strcat)(opt, format);
276b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn   VG_(fmsg_bad_option)(opt, "");
277374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn  }
278374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn}
279374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
280064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
281064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*=== --trace-children= support                                    ===*/
282064212709dc8988a48d2cbde5b90528952d8cd74sewardj/*====================================================================*/
283064212709dc8988a48d2cbde5b90528952d8cd74sewardj
284064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_commas ( HChar const* c ) {
285064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c == ',') {
286064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
287064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
288064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
289064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
290064212709dc8988a48d2cbde5b90528952d8cd74sewardj
291064212709dc8988a48d2cbde5b90528952d8cd74sewardjstatic HChar const* consume_field ( HChar const* c ) {
292064212709dc8988a48d2cbde5b90528952d8cd74sewardj   while (*c && *c != ',') {
293064212709dc8988a48d2cbde5b90528952d8cd74sewardj      ++c;
294064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
295064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return c;
296064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
297064212709dc8988a48d2cbde5b90528952d8cd74sewardj
298064212709dc8988a48d2cbde5b90528952d8cd74sewardj/* Should we trace into this child executable (across execve etc) ?
2999ab64a4d3043c251561419d0e0f51492172b1072sewardj   This involves considering --trace-children=,
3009ab64a4d3043c251561419d0e0f51492172b1072sewardj   --trace-children-skip=, --trace-children-skip-by-arg=, and the name
3019ab64a4d3043c251561419d0e0f51492172b1072sewardj   of the executable.  'child_argv' must not include the name of the
3029ab64a4d3043c251561419d0e0f51492172b1072sewardj   executable itself; iow child_argv[0] must be the first arg, if any,
3039ab64a4d3043c251561419d0e0f51492172b1072sewardj   for the child. */
3049ab64a4d3043c251561419d0e0f51492172b1072sewardjBool VG_(should_we_trace_this_child) ( HChar* child_exe_name,
3059ab64a4d3043c251561419d0e0f51492172b1072sewardj                                       HChar** child_argv )
306064212709dc8988a48d2cbde5b90528952d8cd74sewardj{
307064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // child_exe_name is pulled out of the guest's space.  We
308064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // should be at least marginally cautious with it, lest it
309064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // explode or burst into flames unexpectedly.
310064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (child_exe_name == NULL || VG_(strlen)(child_exe_name) == 0)
311064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return VG_(clo_trace_children);  // we know narfink
312064212709dc8988a48d2cbde5b90528952d8cd74sewardj
313064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // If --trace-children=no, the answer is simply NO.
314064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (! VG_(clo_trace_children))
315064212709dc8988a48d2cbde5b90528952d8cd74sewardj      return False;
316064212709dc8988a48d2cbde5b90528952d8cd74sewardj
3179ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Otherwise, look for other reasons to say NO.  First,
3189ab64a4d3043c251561419d0e0f51492172b1072sewardj   // see if the exe name matches any of the patterns specified
3199ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip=.
320064212709dc8988a48d2cbde5b90528952d8cd74sewardj   if (VG_(clo_trace_children_skip)) {
321064212709dc8988a48d2cbde5b90528952d8cd74sewardj      HChar const* last = VG_(clo_trace_children_skip);
32219f91bbaedb4caef8a60ce94b0f507193cc0bc10florian      HChar const* name = child_exe_name;
323064212709dc8988a48d2cbde5b90528952d8cd74sewardj      while (*last) {
324064212709dc8988a48d2cbde5b90528952d8cd74sewardj         Bool   matches;
325064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar* patt;
326064212709dc8988a48d2cbde5b90528952d8cd74sewardj         HChar const* first = consume_commas(last);
327064212709dc8988a48d2cbde5b90528952d8cd74sewardj         last = consume_field(first);
328064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (first == last)
329064212709dc8988a48d2cbde5b90528952d8cd74sewardj            break;
330064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(last > first);
331064212709dc8988a48d2cbde5b90528952d8cd74sewardj         /* copy the candidate string into a temporary malloc'd block
332064212709dc8988a48d2cbde5b90528952d8cd74sewardj            so we can use VG_(string_match) on it. */
333064212709dc8988a48d2cbde5b90528952d8cd74sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
334064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(memcpy)(patt, first, last - first);
335064212709dc8988a48d2cbde5b90528952d8cd74sewardj         vg_assert(patt[last-first] == 0);
336064212709dc8988a48d2cbde5b90528952d8cd74sewardj         matches = VG_(string_match)(patt, name);
337064212709dc8988a48d2cbde5b90528952d8cd74sewardj         VG_(free)(patt);
338064212709dc8988a48d2cbde5b90528952d8cd74sewardj         if (matches)
339064212709dc8988a48d2cbde5b90528952d8cd74sewardj            return False;
340064212709dc8988a48d2cbde5b90528952d8cd74sewardj      }
341064212709dc8988a48d2cbde5b90528952d8cd74sewardj   }
3429ab64a4d3043c251561419d0e0f51492172b1072sewardj
3439ab64a4d3043c251561419d0e0f51492172b1072sewardj   // Check if any of the args match any of the patterns specified
3449ab64a4d3043c251561419d0e0f51492172b1072sewardj   // by --trace-children-skip-by-arg=.
3459ab64a4d3043c251561419d0e0f51492172b1072sewardj   if (VG_(clo_trace_children_skip_by_arg) && child_argv != NULL) {
3469ab64a4d3043c251561419d0e0f51492172b1072sewardj      HChar const* last = VG_(clo_trace_children_skip_by_arg);
3479ab64a4d3043c251561419d0e0f51492172b1072sewardj      while (*last) {
3489ab64a4d3043c251561419d0e0f51492172b1072sewardj         Int    i;
3499ab64a4d3043c251561419d0e0f51492172b1072sewardj         Bool   matches;
3509ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar* patt;
3519ab64a4d3043c251561419d0e0f51492172b1072sewardj         HChar const* first = consume_commas(last);
3529ab64a4d3043c251561419d0e0f51492172b1072sewardj         last = consume_field(first);
3539ab64a4d3043c251561419d0e0f51492172b1072sewardj         if (first == last)
3549ab64a4d3043c251561419d0e0f51492172b1072sewardj            break;
3559ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(last > first);
3569ab64a4d3043c251561419d0e0f51492172b1072sewardj         /* copy the candidate string into a temporary malloc'd block
3579ab64a4d3043c251561419d0e0f51492172b1072sewardj            so we can use VG_(string_match) on it. */
3589ab64a4d3043c251561419d0e0f51492172b1072sewardj         patt = VG_(calloc)("m_options.swttc.1", last - first + 1, 1);
3599ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(memcpy)(patt, first, last - first);
3609ab64a4d3043c251561419d0e0f51492172b1072sewardj         vg_assert(patt[last-first] == 0);
3619ab64a4d3043c251561419d0e0f51492172b1072sewardj         for (i = 0; child_argv[i]; i++) {
3629ab64a4d3043c251561419d0e0f51492172b1072sewardj            matches = VG_(string_match)(patt, child_argv[i]);
3639ab64a4d3043c251561419d0e0f51492172b1072sewardj            if (matches) {
3649ab64a4d3043c251561419d0e0f51492172b1072sewardj               VG_(free)(patt);
3659ab64a4d3043c251561419d0e0f51492172b1072sewardj               return False;
3669ab64a4d3043c251561419d0e0f51492172b1072sewardj            }
3679ab64a4d3043c251561419d0e0f51492172b1072sewardj         }
3689ab64a4d3043c251561419d0e0f51492172b1072sewardj         VG_(free)(patt);
3699ab64a4d3043c251561419d0e0f51492172b1072sewardj      }
3709ab64a4d3043c251561419d0e0f51492172b1072sewardj   }
3719ab64a4d3043c251561419d0e0f51492172b1072sewardj
372064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // --trace-children=yes, and this particular executable isn't
373064212709dc8988a48d2cbde5b90528952d8cd74sewardj   // excluded
374064212709dc8988a48d2cbde5b90528952d8cd74sewardj   return True;
375064212709dc8988a48d2cbde5b90528952d8cd74sewardj}
376374a36dbfb6d08ed8d77c31a88e198a861ffadf0njn
3776893d65852940741dbebbc6ba1480e89cf34e30fsewardj
37832824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
379b1cc5d666cc8f8065419e4a8c819ed0b8256a764njn/*--- end                                                          ---*/
38032824028b51461062a5a282bfd775d4bd4ad6a47sewardj/*--------------------------------------------------------------------*/
381