Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-15 09:14:27

0001 
0002 /*--------------------------------------------------------------------*/
0003 /*--- Command line options.                     pub_tool_options.h ---*/
0004 /*--------------------------------------------------------------------*/
0005 
0006 /*
0007    This file is part of Valgrind, a dynamic binary instrumentation
0008    framework.
0009 
0010    Copyright (C) 2000-2017 Julian Seward
0011       jseward@acm.org
0012 
0013    This program is free software; you can redistribute it and/or
0014    modify it under the terms of the GNU General Public License as
0015    published by the Free Software Foundation; either version 2 of the
0016    License, or (at your option) any later version.
0017 
0018    This program is distributed in the hope that it will be useful, but
0019    WITHOUT ANY WARRANTY; without even the implied warranty of
0020    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0021    General Public License for more details.
0022 
0023    You should have received a copy of the GNU General Public License
0024    along with this program; if not, see <http://www.gnu.org/licenses/>.
0025 
0026    The GNU General Public License is contained in the file COPYING.
0027 */
0028 
0029 #ifndef __PUB_TOOL_OPTIONS_H
0030 #define __PUB_TOOL_OPTIONS_H
0031 
0032 #include "pub_tool_basics.h"     // for VG_ macro
0033 #include "pub_tool_libcbase.h"   // for VG__ str functions
0034 #include "pub_tool_libcprint.h"  // for VG_(fmsg_bad_option)
0035 #include "libvex.h"              // for VexControl
0036 
0037 // Command line option parsing happens in the following modes:
0038 //   cloE : Early processing, used by coregrind m_main.c to parse the
0039 //      command line  options that must be handled early on.
0040 //   cloP : Processing,  used by coregrind and tools during startup, when
0041 //      doing command line options Processing.
0042 //   clodD : Dynamic, used to dynamically change options after startup.
0043 //      A subset of the command line options can be changed dynamically
0044 //      after startup.
0045 //   cloH : Help, special mode to produce the list of dynamically changeable
0046 //      options for --help-dyn-options.
0047 typedef
0048    enum {
0049       cloE = 1,
0050       cloP = 2,
0051       cloD = 4,
0052       cloH = 8
0053    } Clo_Mode;
0054 
0055 // Defines often used mode sets, e.g. for options used in several modes.
0056 #define cloEP (cloE | cloP)
0057 #define cloED (cloE | cloD)
0058 #define cloPD (cloP | cloD)
0059 
0060 // Sets and gets the current option parsing mode.
0061 // VG_(set_Clo_Mode) also resets the value of VG_(Clo_Recognised) to False.
0062 void VG_(set_Clo_Mode) (Clo_Mode mode);
0063 
0064 Clo_Mode VG_(Clo_Mode) (void);
0065 
0066 // This is called by the various macros below to indicate that
0067 // the currently parsed option has been recognised.
0068 void VG_(set_Clo_Recognised) (void);
0069 Bool VG_(Clo_Recognised) (void);
0070 
0071 
0072 /* Once the system is started up, the dynamic options can be changed
0073    (mode CloD) or listed (mode cloH) using the below.  */
0074 void VG_(process_dynamic_option) (Clo_Mode mode, HChar *value);
0075 
0076 // Macros below are calling VG_(check_clom) to handle an option according
0077 // to the current Clo_Mode.
0078 // If recognised, it marks the option as recognised, and then returns True
0079 // if the current mode matches the modes allowed for this option,
0080 // False if option should not be processed according to current mode
0081 // and qq_mode.
0082 // It produces a warning if mode is cloD and cloD is not allowed by
0083 // modes.  If current mode is cloH, CHECK_CLOM calls VG_(list_clo) if cloD
0084 // is allowed by modes.
0085 Bool VG_(check_clom) (Clo_Mode modes, const HChar* arg, const HChar* option,
0086                       Bool recognised);
0087 
0088 // Higher-level command-line option recognisers;  use in if/else chains. 
0089 // Note that they assign a value to the 'qq_var' argument.  So often they
0090 // can be used like this:
0091 //
0092 //   if VG_STR_CLO(arg, "--foo", clo_foo) { }
0093 //
0094 // But if you want to do further checking or processing, you can do this:
0095 //
0096 //   if VG_STR_CLO(arg, "--foo", clo_foo) { <checking or processing> }
0097 //
0098 // The recognisers above are only modifying their argument in the relevant
0099 // parsing mode (by default, only during cloP mode).
0100 // If an option is handled during other modes than cloP, use the *M
0101 // variants of the recognisers to specify the mode.
0102 //
0103 // They use GNU statement expressions to do the qq_var assignment within a
0104 // conditional expression.
0105 
0106 // Used to produce the list of dynamically changeable options.
0107 extern void VG_(list_clo)(const HChar *qq_option);
0108 
0109 // True if current option parsing mode matches qq_mode
0110 // and the first qq_len characters of qq_arg match qq_option.
0111 #define VG_STREQN_CLOM(qq_mode, qq_len, qq_arg, qq_option) \
0112    (VG_(check_clom)                                        \
0113     (qq_mode, qq_arg, qq_option,                           \
0114      VG_STREQN(qq_len, qq_arg, qq_option)))
0115 
0116 // True if current option parsing mode matches qq_mode
0117 // and qq_arg match qq_option.
0118 #define VG_STREQ_CLOM(qq_mode, qq_arg, qq_option)       \
0119    (VG_(check_clom)                                     \
0120     (qq_mode, qq_arg, qq_option,                        \
0121      VG_STREQ(qq_arg, qq_option)))
0122 
0123 static inline
0124 Bool VG_(bool_clom)(Clo_Mode qq_mode, const HChar* qq_arg, const HChar* qq_option, Bool* qq_var, Bool qq_vareq_arg)
0125 {
0126    Bool res = False;
0127    if (VG_(check_clom)(qq_mode, qq_arg, qq_option, qq_vareq_arg))
0128    {
0129       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];
0130       if (VG_(strcmp)(val, "yes") == 0)
0131       {
0132          *qq_var = True;
0133          res = True;
0134       }
0135       else if (VG_(strcmp)(val, "no") == 0)
0136       {
0137          *qq_var = False;
0138          res = True;
0139       }
0140       else
0141       {
0142          VG_(fmsg_bad_option)(qq_arg, "Invalid boolean value '%s'"
0143                                       " (should be 'yes' or 'no')\n",
0144           /* gcc 10 (20200119) complains that |val| could be null here. */
0145           /* I think it is wrong, but anyway, to placate it .. */
0146                                               (val ? val : "(null)"));
0147       }
0148    } else if (VG_STREQN(VG_(strlen)(qq_option), qq_arg, qq_option) &&
0149               VG_(strlen)(qq_option) == VG_(strlen)(qq_arg))
0150    {
0151       VG_(fmsg_bad_option)(qq_arg,
0152                            "Missing boolean value, did you mean '%s=yes'?\n",
0153                            qq_arg);
0154    }
0155 
0156    return res;
0157 }
0158 
0159 // String argument, eg. --foo=yes or --foo=no
0160 #define VG_BOOL_CLOM(qq_mode, qq_arg, qq_option, qq_var)        \
0161    (VG_(bool_clom)((qq_mode), (qq_arg), (qq_option), &(qq_var), \
0162    VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"="))   \
0163    )
0164 
0165 #define VG_BOOL_CLO(qq_arg, qq_option, qq_var) \
0166    VG_BOOL_CLOM(cloP, qq_arg, qq_option, qq_var)
0167 
0168 // String argument, eg. --foo=bar
0169 #define VG_STR_CLOM(qq_mode, qq_arg, qq_option, qq_var)                 \
0170    (VG_(check_clom)                                                     \
0171     (qq_mode, qq_arg, qq_option,                                        \
0172      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0173     ({const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0174       (qq_var) = val;                                                   \
0175       True; }))
0176 
0177 #define VG_STR_CLO(qq_arg, qq_option, qq_var) \
0178    VG_STR_CLOM(cloP, qq_arg, qq_option, qq_var)
0179 
0180 // UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none
0181 // or --foo=all  (if qq_all is True)
0182 #define VG_USETGEN_CLOM(qq_mode, qq_arg, qq_option, qq_vals, qq_var, qq_all) \
0183    (VG_(check_clom)                                                     \
0184     (qq_mode, qq_arg, qq_option,                                        \
0185      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0186     ({Bool res = True;                                                  \
0187        const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];        \
0188       if (!VG_(parse_enum_set)(qq_vals,                                 \
0189                                qq_all,/*allow_all*/                     \
0190                                val,                                     \
0191                                &(qq_var))) {                            \
0192          VG_(fmsg_bad_option)(qq_arg, "%s is an invalid %s set\n",      \
0193                               val, &qq_option[2]);                        \
0194          res = False; }                                                 \
0195       res; }))
0196 
0197 // UInt enum set arg, eg. --foo=fubar,bar,baz or --foo=none or --foo=all
0198 #define VG_USET_CLO(qq_arg, qq_option, qq_vals, qq_var) \
0199    VG_USETGEN_CLOM(cloP, (qq_arg), qq_option, (qq_vals), (qq_var), True)
0200 #define VG_USET_CLOM(qq_mode, qq_arg, qq_option, qq_vals, qq_var) \
0201    VG_USETGEN_CLOM(qq_mode, (qq_arg), qq_option, (qq_vals), (qq_var), True)
0202 
0203 /* Same as VG_USET_CLO but not allowing --foo=all.
0204    To be used when some or all of the enum set are mutually eXclusive. */
0205 #define VG_USETX_CLO(qq_arg, qq_option, qq_vals, qq_var) \
0206    VG_USETGEN_CLOM(cloP, (qq_arg), qq_option, (qq_vals), (qq_var), False)
0207 #define VG_USETX_CLOM(qq_mode, qq_arg, qq_option, qq_vals, qq_var) \
0208    VG_USETGEN_CLOM(qq_mode, (qq_arg), qq_option, (qq_vals), (qq_var), False)
0209 
0210 // Unbounded integer arg, eg. --foo=10
0211 #define VG_INT_CLOM(qq_mode, qq_arg, qq_option, qq_var)                 \
0212    (VG_(check_clom)                                                     \
0213     (qq_mode, qq_arg, qq_option,                                        \
0214      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0215     ({Bool res = True;                                                  \
0216       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0217       HChar* s;                                                         \
0218       Long n = VG_(strtoll10)( val, &s );                               \
0219       (qq_var) = n;                                                     \
0220       /* Check for non-numeralness, or overflow. */                     \
0221       if ('\0' != s[0] || (qq_var) != n) {                              \
0222          VG_(fmsg_bad_option)(qq_arg,                                   \
0223                               "Invalid integer value '%s'\n", val);     \
0224          res = False; }                                                 \
0225       res; }))
0226 
0227 #define VG_INT_CLO(qq_arg, qq_option, qq_var) \
0228    VG_INT_CLOM(cloP, qq_arg, qq_option, qq_var)
0229 
0230 // Bounded integer arg, eg. --foo=10 ;  if the value exceeds the bounds it
0231 // causes an abort.  'qq_base' can be 10 or 16.
0232 #define VG_BINTN_CLOM(qq_mode, qq_base, qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
0233    (VG_(check_clom)                                                     \
0234     (qq_mode, qq_arg, qq_option,                                        \
0235      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0236     ({Bool res = True;                                                  \
0237       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0238       HChar* s;                                                         \
0239       Long n = VG_(strtoll##qq_base)( val, &s );                        \
0240       (qq_var) = n;                                                     \
0241       /* MMM: separate the two cases, and explain the problem;  likewise */ \
0242       /* for all the other macros in this file. */                      \
0243       /* Check for non-numeralness, or overflow. */                     \
0244       /* Nb: it will overflow if qq_var is unsigned and qq_val is negative! */ \
0245       if ('\0' != s[0] || (qq_var) != n) {                              \
0246          VG_(fmsg_bad_option)(qq_arg,                                   \
0247                               "Invalid integer value '%s'\n", val);     \
0248          res = False; }                                                 \
0249       /* Check bounds. */                                               \
0250       if ((qq_var) < (qq_lo) || (qq_var) > (qq_hi)) {                   \
0251          VG_(fmsg_bad_option)(qq_arg,                                   \
0252             "'%s' argument must be between %lld and %lld\n",            \
0253                               (qq_option), (Long)(qq_lo), (Long)(qq_hi)); \
0254          res = False;                                                  \
0255       }                                                                \
0256       res;}))
0257 
0258 // As above, but for unsigned int arguments with a lower bound of 0
0259 #define VG_BUINTN_CLOM(qq_mode, qq_base, qq_arg, qq_option, qq_var, qq_hi) \
0260 (VG_(check_clom)                                                     \
0261  (qq_mode, qq_arg, qq_option,                                        \
0262   VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0263  ({Bool res = True;                                                  \
0264       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0265       HChar* s;                                                         \
0266       Long n = VG_(strtoll##qq_base)( val, &s );                        \
0267       (qq_var) = n;                                                     \
0268       if ('\0' != s[0] || (qq_var) != n) {                              \
0269          VG_(fmsg_bad_option)(qq_arg,                                   \
0270                               "Invalid integer value '%s'\n", val);     \
0271          res = False; }                                                 \
0272       /* Check bounds. */                                               \
0273       if ((qq_var) > (qq_hi)) {                                         \
0274          VG_(fmsg_bad_option)(qq_arg,                                   \
0275             "'%s' argument must be <= %lld\n",            \
0276                               (qq_option), (Long)(qq_hi));              \
0277          res = False;                                                  \
0278       }                                                                \
0279       res;}))
0280 
0281 // Bounded decimal integer arg, eg. --foo=100
0282 #define VG_BINT_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
0283    VG_BINTN_CLOM(cloP, 10, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi))
0284 #define VG_BINT_CLOM(qq_mode, qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
0285    VG_BINTN_CLOM(qq_mode, 10, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi))
0286 #define VG_BUINT_CLOM(qq_mode, qq_arg, qq_option, qq_var, qq_hi) \
0287    VG_BUINTN_CLOM(qq_mode, 10, (qq_arg), qq_option, (qq_var), (qq_hi))
0288 
0289 // Bounded hexadecimal integer arg, eg. --foo=0x1fa8
0290 #define VG_BHEX_CLO(qq_arg, qq_option, qq_var, qq_lo, qq_hi) \
0291    VG_BINTN_CLOM(cloP, 16, (qq_arg), qq_option, (qq_var), (qq_lo), (qq_hi))
0292 
0293 // Double (decimal) arg, eg. --foo=4.6
0294 // XXX: there's not VG_BDBL_CLO because we don't have a good way of printing
0295 // floats at the moment!
0296 #define VG_DBL_CLOM(qq_mode, qq_arg, qq_option, qq_var) \
0297    (VG_(check_clom)                                                     \
0298     (qq_mode, qq_arg, qq_option,                                        \
0299      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0300     ({Bool res = True;                                                  \
0301       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0302       HChar* s;                                                         \
0303       double n = VG_(strtod)( val, &s );                                \
0304       (qq_var) = n;                                                     \
0305       /* Check for non-numeralness */                                   \
0306       if ('\0' != s[0]) {                                               \
0307          VG_(fmsg_bad_option)(qq_arg,                                   \
0308                               "Invalid floating point value '%s'\n",val); \
0309          res = False; }                                                 \
0310       res;}))
0311 
0312 #define VG_DBL_CLO( qq_arg, qq_option, qq_var) \
0313    VG_DBL_CLOM(cloP, qq_arg, qq_option, qq_var)
0314 
0315 // Arg whose value is denoted by the exact presence of the given string;
0316 // if it matches, qq_var is assigned the value in qq_val.
0317 #define VG_XACT_CLOM(qq_mode, qq_arg, qq_option, qq_var, qq_val) \
0318    (VG_(check_clom) \
0319     (qq_mode, qq_arg, qq_option,                                \
0320      VG_STREQ((qq_arg), (qq_option))) &&                        \
0321     ({(qq_var) = (qq_val);                                      \
0322        True; }))
0323 
0324 #define VG_XACT_CLO(qq_arg, qq_option, qq_var, qq_val) \
0325    VG_XACT_CLOM(cloP, qq_arg, qq_option, qq_var, qq_val)
0326 
0327 // Arg that can be one of a set of strings, as specified in an NULL
0328 // terminated array.  Returns the index of the string in |qq_ix|, or
0329 // aborts if not found.
0330 #define VG_STRINDEX_CLOM(qq_mode, qq_arg, qq_option, qq_strings, qq_ix) \
0331    (VG_(check_clom)                                                     \
0332     (qq_mode, qq_arg, qq_option,                                        \
0333      VG_STREQN(VG_(strlen)(qq_option)+1, qq_arg, qq_option"=")) &&      \
0334     ({Bool res = True;                                                  \
0335       const HChar* val = &(qq_arg)[ VG_(strlen)(qq_option)+1 ];         \
0336       for (qq_ix = 0; (qq_strings)[qq_ix]; qq_ix++) {                   \
0337          if (VG_STREQ(val, (qq_strings)[qq_ix]))                        \
0338             break;                                                      \
0339       }                                                                 \
0340       if ((qq_strings)[qq_ix] == NULL) {                                \
0341          VG_(fmsg_bad_option)(qq_arg,                                   \
0342                               "Invalid string '%s' in '%s'\n", val, qq_arg); \
0343          res = False;                                                   \
0344       } \
0345       res; }))
0346 
0347 #define VG_STRINDEX_CLO(qq_arg, qq_option, qq_strings, qq_ix) \
0348    VG_STRINDEX_CLOM(cloP, qq_arg, qq_option, qq_strings, qq_ix)
0349 
0350 /* Verbosity level: 0 = silent, 1 (default), > 1 = more verbose. */
0351 extern Int  VG_(clo_verbosity);
0352 
0353 /* Show tool and core statistics */
0354 extern Bool VG_(clo_stats);
0355 
0356 /* wait for vgdb/gdb after reporting that amount of error.
0357    Note that this value can be changed dynamically. */
0358 extern Int VG_(clo_vgdb_error);
0359 
0360 /* Set by vgdb in --multi mode when launching valgrind. This suppresses
0361    the "TO DEBUG" banner because vgdb will take care of attaching in that
0362    case.  */
0363 extern Bool VG_(clo_launched_with_multi);
0364 
0365 /* If user has provided the --vgdb-prefix command line option,
0366    VG_(arg_vgdb_prefix) points at the provided argument (including the
0367    '--vgdb-prefix=' string).
0368    Otherwise, it is NULL.
0369    Typically, this is used by tools to produce user message with the
0370    expected vgdb prefix argument, if the user has changed the default. */
0371 extern const HChar *VG_(arg_vgdb_prefix);
0372 
0373 /* Emit all messages as XML? default: NO */
0374 /* If clo_xml is set, various other options are set in a non-default
0375    way.  See vg_main.c and mc_main.c. */
0376 extern Bool VG_(clo_xml);
0377 
0378 /* An arbitrary user-supplied string which is copied into the
0379    XML output, in between <usercomment> tags. */
0380 extern const HChar* VG_(clo_xml_user_comment);
0381 
0382 /* Vex iropt control.  Tool-visible so tools can make Vex optimise
0383    less aggressively if that is needed (callgrind needs this). */
0384 extern VexControl VG_(clo_vex_control);
0385 extern VexRegisterUpdates VG_(clo_px_file_backed);
0386 
0387 extern Int VG_(clo_redzone_size);
0388 
0389 typedef
0390    enum {
0391       Vg_XTMemory_None,   // Do not do any xtree memory profiling.
0392       Vg_XTMemory_Allocs, // Currently allocated size xtree memory profiling
0393       Vg_XTMemory_Full,   // Full profiling : Current allocated size, total
0394       // allocated size, nr of blocks, total freed size, ...
0395    }
0396    VgXTMemory;
0397 // Tools that replace malloc can optionally implement memory profiling
0398 // following the value of VG_(clo_xtree_profile_memory) to produce a report
0399 // at the end of execution.
0400 extern VgXTMemory VG_(clo_xtree_memory);
0401 /* Holds the filename to use for xtree memory profiling output, before expansion
0402    of %p and %q templates. */
0403 extern const HChar* VG_(clo_xtree_memory_file);
0404 /* Compress strings in xtree dumps. */
0405 extern Bool VG_(clo_xtree_compress_strings);
0406 
0407 /* Number of parents of a backtrace.  Default: 12  */
0408 extern Int   VG_(clo_backtrace_size);
0409 
0410 /* Continue stack traces below main()?  Default: NO */
0411 extern Bool VG_(clo_show_below_main);
0412 
0413 /* Keep symbols (and all other debuginfo) for code that is unloaded (dlclose
0414    or similar) so that stack traces can still give line/file info for
0415    previously captured stack traces.  e.g. ... showing where a block was
0416    allocated e.g. leaks of or accesses just outside a block. */
0417 extern Bool VG_(clo_keep_debuginfo);
0418 
0419 /* Track open file descriptors? 0 = No, 1 = Yes, 2 = All (including std)  */
0420 extern UInt  VG_(clo_track_fds);
0421 
0422 
0423 /* Used to expand file names.  "option_name" is the option name, eg.
0424    "--log-file".  'format' is what follows, eg. "cachegrind.out.%p".  In
0425    'format':
0426    - "%p" is replaced with PID.
0427    - "%q{QUAL}" is replaced with the environment variable $QUAL.  If $QUAL
0428      isn't set, we abort.  If the "{QUAL}" part is malformed, we abort.
0429    - "%%" is replaced with "%".
0430    Anything else after '%' causes an abort.
0431    If the format specifies a relative file name, it's put in the program's
0432    initial working directory.  If it specifies an absolute file name (ie.
0433    starts with '/') then it is put there.
0434 
0435    Note that "option_name" has no effect on the returned string: the
0436    returned string depends only on "format" and the PIDs and
0437    environment variables that it references (if any). "option_name" is
0438    merely used in printing error messages, if an error message needs
0439    to be printed due to malformedness of the "format" argument.
0440 */
0441 extern HChar* VG_(expand_file_name)(const HChar* option_name,
0442                                     const HChar* format);
0443 
0444 #endif   // __PUB_TOOL_OPTIONS_H
0445 
0446 /*--------------------------------------------------------------------*/
0447 /*--- end                                                          ---*/
0448 /*--------------------------------------------------------------------*/