Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:13:31

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