]> sourceware.org Git - systemtap.git/blob - session.cxx
PR18848: Only compile monitor mode if json-c and ncurses developer
[systemtap.git] / session.cxx
1 // session functions
2 // Copyright (C) 2010-2015 Red Hat Inc.
3 //
4 // This file is part of systemtap, and is free software. You can
5 // redistribute it and/or modify it under the terms of the GNU General
6 // Public License (GPL); either version 2, or (at your option) any
7 // later version.
8
9 #include "config.h"
10 #include "session.h"
11 #include "cache.h"
12 #include "stapregex.h"
13 #include "elaborate.h"
14 #include "translate.h"
15 #include "buildrun.h"
16 #include "coveragedb.h"
17 #include "hash.h"
18 #include "task_finder.h"
19 #include "csclient.h"
20 #include "rpm_finder.h"
21 #include "util.h"
22 #include "cmdline.h"
23 #include "git_version.h"
24 #include "version.h"
25 #include "stringtable.h"
26
27 #include <cerrno>
28 #include <cstdlib>
29
30 extern "C" {
31 #include <getopt.h>
32 #include <limits.h>
33 #include <grp.h>
34 #include <sys/stat.h>
35 #include <sys/utsname.h>
36 #include <sys/resource.h>
37 #include <elfutils/libdwfl.h>
38 #include <elfutils/version.h>
39 #include <unistd.h>
40 #include <sys/wait.h>
41 #include <wordexp.h>
42 }
43
44 #if HAVE_NSS
45 extern "C" {
46 #include <nspr.h>
47 }
48 #endif
49
50 #include <string>
51
52 using namespace std;
53
54 /* getopt variables */
55 extern int optind;
56
57 #define PATH_TBD string("__TBD__")
58
59 #if HAVE_NSS
60 bool systemtap_session::NSPR_Initialized = false;
61 #endif
62
63 systemtap_session::systemtap_session ():
64 // NB: pointer members must be manually initialized!
65 // NB: don't forget the copy constructor too!
66 runtime_mode(kernel_runtime),
67 base_hash(0),
68 pattern_root(new match_node),
69 dfa_counter (0),
70 dfa_maxstate (0),
71 dfa_maxtag (0),
72 need_tagged_dfa (false),
73 be_derived_probes(0),
74 dwarf_derived_probes(0),
75 kprobe_derived_probes(0),
76 hwbkpt_derived_probes(0),
77 perf_derived_probes(0),
78 uprobe_derived_probes(0),
79 utrace_derived_probes(0),
80 itrace_derived_probes(0),
81 task_finder_derived_probes(0),
82 timer_derived_probes(0),
83 netfilter_derived_probes(0),
84 profile_derived_probes(0),
85 mark_derived_probes(0),
86 tracepoint_derived_probes(0),
87 hrtimer_derived_probes(0),
88 procfs_derived_probes(0),
89 dynprobe_derived_probes(0),
90 op (0), up (0),
91 sym_kprobes_text_start (0),
92 sym_kprobes_text_end (0),
93 sym_stext (0),
94 module_cache (0),
95 benchmark_sdt_loops(0),
96 benchmark_sdt_threads(0),
97 suppressed_warnings(0),
98 suppressed_errors(0),
99 warningerr_count(0),
100 target_namespaces_pid(0),
101 last_token (0)
102 {
103 struct utsname buf;
104 (void) uname (& buf);
105 kernel_release = string (buf.release);
106 release = kernel_release;
107 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
108 architecture = machine = normalize_machine(buf.machine);
109
110 for (unsigned i=0; i<5; i++) perpass_verbose[i]=0;
111 verbose = 0;
112
113 have_script = false;
114 runtime_specified = false;
115 include_arg_start = -1;
116 timing = false;
117 guru_mode = false;
118 bulk_mode = false;
119 unoptimized = false;
120 suppress_warnings = false;
121 panic_warnings = false;
122 dump_mode = systemtap_session::dump_none;
123 dump_matched_pattern = "";
124
125 #ifdef ENABLE_PROLOGUES
126 prologue_searching_mode = prologue_searching_always;
127 #else
128 prologue_searching_mode = prologue_searching_auto;
129 #endif
130
131 buffer_size = 0;
132 last_pass = 5;
133 module_name = "stap_" + lex_cast(getpid());
134 stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
135 output_file = ""; // -o FILE
136 tmpdir_opt_set = false;
137 monitor = false;
138 monitor_interval = 1;
139 save_module = false;
140 save_uprobes = false;
141 modname_given = false;
142 keep_tmpdir = false;
143 cmd = "";
144 target_pid = 0;
145 use_cache = true;
146 use_script_cache = true;
147 poison_cache = false;
148 tapset_compile_coverage = false;
149 need_uprobes = false;
150 need_unwind = false;
151 need_symbols = false;
152 need_lines = false;
153 uprobes_path = "";
154 load_only = false;
155 skip_badvars = false;
156 privilege = pr_stapdev;
157 privilege_set = false;
158 compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
159 unwindsym_ldd = false;
160 client_options = false;
161 server_cache = NULL;
162 auto_privilege_level_msg = "";
163 auto_server_msgs.clear ();
164 use_server_on_error = false;
165 try_server_status = try_server_unset;
166 use_remote_prefix = false;
167 systemtap_v_check = false;
168 download_dbinfo = 0;
169 suppress_handler_errors = false;
170 native_build = true; // presumed
171 sysroot = "";
172 update_release_sysroot = false;
173 suppress_time_limits = false;
174 target_namespaces_pid = 0;
175 color_mode = color_auto;
176 color_errors = isatty(STDERR_FILENO) // conditions for coloring when
177 && strcmp(getenv("TERM") ?: "notdumb", "dumb"); // on auto
178
179 // PR12443: put compiled-in / -I paths in front, to be preferred during
180 // tapset duplicate-file elimination
181 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
182 if (s_p != NULL)
183 {
184 include_path.push_back (s_p);
185 }
186 else
187 {
188 include_path.push_back (string(PKGDATADIR) + "/tapset");
189 }
190
191 /* adding in the XDG_DATA_DIRS variable path,
192 * this searches in conjunction with SYSTEMTAP_TAPSET
193 * to locate stap scripts, either can be disabled if
194 * needed using env $PATH=/dev/null where $PATH is the
195 * path you want disabled
196 */
197 const char* s_p1 = getenv ("XDG_DATA_DIRS");
198 if ( s_p1 != NULL )
199 {
200 vector<string> dirs;
201 tokenize(s_p1, dirs, ":");
202 for(vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i)
203 {
204 include_path.push_back(*i + "/systemtap/tapset");
205 }
206 }
207
208 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
209 if (s_r != NULL)
210 runtime_path = s_r;
211 else
212 runtime_path = string(PKGDATADIR) + "/runtime";
213
214 const char* s_d = getenv ("SYSTEMTAP_DIR");
215 if (s_d != NULL)
216 data_path = s_d;
217 else
218 data_path = get_home_directory() + string("/.systemtap");
219 if (create_dir(data_path.c_str()) == 1)
220 {
221 const char* e = strerror (errno);
222 print_warning("failed to create systemtap data directory \"" + data_path + "\" " + e + ", disabling cache support.");
223 use_cache = use_script_cache = false;
224 }
225
226 if (use_cache)
227 {
228 cache_path = data_path + "/cache";
229 if (create_dir(cache_path.c_str()) == 1)
230 {
231 const char* e = strerror (errno);
232 print_warning("failed to create cache directory (\" " + cache_path + " \") " + e + ", disabling cache support.");
233 use_cache = use_script_cache = false;
234 }
235 }
236
237 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
238 if (s_tc != NULL)
239 tapset_compile_coverage = true;
240
241 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
242 if (s_kr != NULL) {
243 setup_kernel_release(s_kr);
244 }
245 create_tmp_dir();
246 }
247
248 systemtap_session::systemtap_session (const systemtap_session& other,
249 const string& arch,
250 const string& kern):
251 // NB: pointer members must be manually initialized!
252 // NB: this needs to consider everything that the base ctor does,
253 // plus copying any wanted implicit fields (strings, vectors, etc.)
254 runtime_mode(other.runtime_mode),
255 base_hash(0),
256 pattern_root(new match_node),
257 user_files (other.user_files),
258 dfa_counter(0),
259 dfa_maxstate (0),
260 dfa_maxtag (0),
261 need_tagged_dfa(other.need_tagged_dfa),
262 be_derived_probes(0),
263 dwarf_derived_probes(0),
264 kprobe_derived_probes(0),
265 hwbkpt_derived_probes(0),
266 perf_derived_probes(0),
267 uprobe_derived_probes(0),
268 utrace_derived_probes(0),
269 itrace_derived_probes(0),
270 task_finder_derived_probes(0),
271 timer_derived_probes(0),
272 netfilter_derived_probes(0),
273 profile_derived_probes(0),
274 mark_derived_probes(0),
275 tracepoint_derived_probes(0),
276 hrtimer_derived_probes(0),
277 procfs_derived_probes(0),
278 dynprobe_derived_probes(0),
279 op (0), up (0),
280 sym_kprobes_text_start (0),
281 sym_kprobes_text_end (0),
282 sym_stext (0),
283 module_cache (0),
284 benchmark_sdt_loops(other.benchmark_sdt_loops),
285 benchmark_sdt_threads(other.benchmark_sdt_threads),
286 suppressed_warnings(0),
287 suppressed_errors(0),
288 warningerr_count(0),
289 target_namespaces_pid(0),
290 last_token (0)
291 {
292 release = kernel_release = kern;
293 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
294 architecture = machine = normalize_machine(arch);
295 setup_kernel_release(kern.c_str());
296 native_build = false; // assumed; XXX: could be computed as in check_options()
297
298 // These are all copied in the same order as the default ctor did above.
299
300 copy(other.perpass_verbose, other.perpass_verbose + 5, perpass_verbose);
301 verbose = other.verbose;
302
303 have_script = other.have_script;
304 runtime_specified = other.runtime_specified;
305 include_arg_start = other.include_arg_start;
306 timing = other.timing;
307 guru_mode = other.guru_mode;
308 bulk_mode = other.bulk_mode;
309 unoptimized = other.unoptimized;
310 suppress_warnings = other.suppress_warnings;
311 panic_warnings = other.panic_warnings;
312 dump_mode = other.dump_mode;
313 dump_matched_pattern = other.dump_matched_pattern;
314
315 prologue_searching_mode = other.prologue_searching_mode;
316
317 buffer_size = other.buffer_size;
318 last_pass = other.last_pass;
319 module_name = other.module_name;
320 stapconf_name = other.stapconf_name;
321 output_file = other.output_file; // XXX how should multiple remotes work?
322 tmpdir_opt_set = false;
323 monitor = other.monitor;
324 monitor_interval = other.monitor_interval;
325 save_module = other.save_module;
326 save_uprobes = other.save_uprobes;
327 modname_given = other.modname_given;
328 keep_tmpdir = other.keep_tmpdir;
329 cmd = other.cmd;
330 target_pid = other.target_pid; // XXX almost surely nonsense for multiremote
331 use_cache = other.use_cache;
332 use_script_cache = other.use_script_cache;
333 poison_cache = other.poison_cache;
334 tapset_compile_coverage = other.tapset_compile_coverage;
335 need_uprobes = false;
336 need_unwind = false;
337 need_symbols = false;
338 need_lines = false;
339 uprobes_path = "";
340 load_only = other.load_only;
341 skip_badvars = other.skip_badvars;
342 privilege = other.privilege;
343 privilege_set = other.privilege_set;
344 compatible = other.compatible;
345 unwindsym_ldd = other.unwindsym_ldd;
346 client_options = other.client_options;
347 server_cache = NULL;
348 use_server_on_error = other.use_server_on_error;
349 try_server_status = other.try_server_status;
350 use_remote_prefix = other.use_remote_prefix;
351 systemtap_v_check = other.systemtap_v_check;
352 download_dbinfo = other.download_dbinfo;
353 suppress_handler_errors = other.suppress_handler_errors;
354 sysroot = other.sysroot;
355 update_release_sysroot = other.update_release_sysroot;
356 sysenv = other.sysenv;
357 suppress_time_limits = other.suppress_time_limits;
358 color_errors = other.color_errors;
359 color_mode = other.color_mode;
360
361 include_path = other.include_path;
362 runtime_path = other.runtime_path;
363
364 // NB: assuming that "other" created these already
365 data_path = other.data_path;
366 cache_path = other.cache_path;
367
368 tapset_compile_coverage = other.tapset_compile_coverage;
369
370
371 // These are fields that were left to their default ctor, but now we want to
372 // copy them from "other". In the same order as declared...
373 script_file = other.script_file;
374 cmdline_script = other.cmdline_script;
375 additional_scripts = other.additional_scripts;
376 c_macros = other.c_macros;
377 args = other.args;
378 kbuildflags = other.kbuildflags;
379
380 globalopts = other.globalopts;
381 modinfos = other.modinfos;
382
383 client_options_disallowed_for_unprivileged = other.client_options_disallowed_for_unprivileged;
384 server_status_strings = other.server_status_strings;
385 specified_servers = other.specified_servers;
386 server_trust_spec = other.server_trust_spec;
387 server_args = other.server_args;
388 mok_fingerprints = other.mok_fingerprints;
389
390 unwindsym_modules = other.unwindsym_modules;
391 auto_privilege_level_msg = other.auto_privilege_level_msg;
392 auto_server_msgs = other.auto_server_msgs;
393
394 create_tmp_dir();
395 }
396
397 systemtap_session::~systemtap_session ()
398 {
399 remove_tmp_dir();
400 delete_map(subsessions);
401 delete pattern_root;
402 }
403
404 const string
405 systemtap_session::module_filename() const
406 {
407 if (runtime_usermode_p())
408 return module_name + ".so";
409 return module_name + ".ko";
410 }
411
412 #if HAVE_NSS
413 void
414 systemtap_session::NSPR_init ()
415 {
416 if (! NSPR_Initialized)
417 {
418 PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
419 NSPR_Initialized = true;
420 }
421 }
422 #endif // HAVE_NSS
423
424 systemtap_session*
425 systemtap_session::clone(const string& arch, const string& release)
426 {
427 const string norm_arch = normalize_machine(arch);
428 if (this->architecture == norm_arch && this->kernel_release == release)
429 return this;
430
431 systemtap_session*& s = subsessions[make_pair(norm_arch, release)];
432 if (!s)
433 s = new systemtap_session(*this, norm_arch, release);
434 return s;
435 }
436
437
438 string
439 systemtap_session::version_string ()
440 {
441 string elfutils_version1;
442 #ifdef _ELFUTILS_VERSION
443 elfutils_version1 = "0." + lex_cast(_ELFUTILS_VERSION);
444 #endif
445 string elfutils_version2 = dwfl_version(NULL);
446
447 if (elfutils_version1 != elfutils_version2)
448 elfutils_version2 += string("/") + elfutils_version1;
449
450 return string (VERSION) + "/" + elfutils_version2 + ", " + STAP_EXTENDED_VERSION;
451 }
452
453 void
454 systemtap_session::version ()
455 {
456 cout << _F("Systemtap translator/driver (version %s)\n"
457 "Copyright (C) 2005-2015 Red Hat, Inc. and others\n"
458 "This is free software; see the source for copying conditions.\n",
459 version_string().c_str());
460
461 cout << _("enabled features:")
462 #ifdef HAVE_AVAHI
463 << " AVAHI"
464 #endif
465 #ifdef HAVE_BOOST_SHARED_PTR_HPP
466 << " BOOST_SHARED_PTR"
467 #endif
468 #ifdef HAVE_BOOST_UTILITY_STRING_REF_HPP
469 << " BOOST_STRING_REF"
470 #endif
471 #ifdef HAVE_DYNINST
472 << " DYNINST"
473 #endif
474 #ifdef HAVE_JAVA
475 << " JAVA"
476 #endif
477 #ifdef HAVE_LIBRPM
478 << " LIBRPM"
479 #endif
480 #ifdef HAVE_LIBSQLITE3
481 << " LIBSQLITE3"
482 #endif
483 #ifdef HAVE_LIBVIRT
484 << " LIBVIRT"
485 #endif
486 #ifdef HAVE_LIBXML2
487 << " LIBXML2"
488 #endif
489 #ifdef ENABLE_NLS
490 << " NLS"
491 #endif
492 #ifdef HAVE_NSS
493 << " NSS"
494 #endif
495 #ifdef ENABLE_PROLOGUES
496 << " PROLOGUES"
497 #endif
498 #ifdef HAVE_TR1_UNORDERED_MAP
499 << " TR1_UNORDERED_MAP"
500 #endif
501 << endl;
502 }
503
504 void
505 systemtap_session::usage (int exitcode)
506 {
507 // For error cases, just suggest --help, so we don't obscure
508 // the actual error message with all the help text.
509 if (exitcode != EXIT_SUCCESS)
510 {
511 clog << _("Try '--help' for more information.") << endl;
512 throw exit_exception(exitcode);
513 }
514
515 version ();
516 cout
517 << endl
518 << _F(
519 "Usage: stap [options] FILE Run script in file.\n"
520 " or: stap [options] - Run script on stdin.\n"
521 " or: stap [options] -e SCRIPT Run given script.\n"
522 " or: stap [options] -l PROBE List matching probes.\n"
523 " or: stap [options] -L PROBE List matching probes and local variables.\n"
524 " or: stap [options] --dump-probe-types List available probe types.\n"
525 " or: stap [options] --dump-probe-aliases List available probe aliases.\n"
526 " or: stap [options] --dump-functions List available functions.\n\n"
527 "Options (in %s/rc and on command line):\n"
528 " -- end of translator options, script options follow\n"
529 " -h --help show help\n"
530 " -V --version show version\n"
531 " -p NUM stop after pass NUM 1-5, instead of %d\n"
532 " (parse, elaborate, translate, compile, run)\n"
533 " -v add verbosity to all passes\n"
534 " --vp {N}+ add per-pass verbosity [", data_path.c_str(), last_pass);
535 for (unsigned i=0; i<5; i++)
536 cout << (perpass_verbose[i] <= 9 ? perpass_verbose[i] : 9);
537 cout
538 << "]" << endl;
539 cout << _F(" -k keep temporary directory\n"
540 " -u unoptimized translation %s\n"
541 " -w suppress warnings %s\n"
542 " -W turn warnings into errors %s\n"
543 " -g guru mode %s\n"
544 " -P prologue-searching for function probes %s\n"
545 " -b bulk (percpu file) mode %s\n"
546 " -s NUM buffer size in megabytes, instead of %d\n"
547 " -I DIR look in DIR for additional .stp script files", (unoptimized ? _(" [set]") : ""),
548 (suppress_warnings ? _(" [set]") : ""), (panic_warnings ? _(" [set]") : ""),
549 (guru_mode ? _(" [set]") : ""), (prologue_searching_mode == prologue_searching_always ? _(" [set]") : ""),
550 (bulk_mode ? _(" [set]") : ""), buffer_size);
551 if (include_path.size() == 0)
552 cout << endl;
553 else
554 cout << _(", in addition to") << endl;
555 for (unsigned i=0; i<include_path.size(); i++)
556 cout << " " << include_path[i].c_str() << endl;
557 cout
558 << _F(" -D NM=VAL emit macro definition into generated C code\n"
559 " -B NM=VAL pass option to kbuild make\n"
560 " --modinfo NM=VAL\n"
561 " include a MODULE_INFO(NM,VAL) in the generated C code\n"
562 " -G VAR=VAL set global variable to value\n"
563 //TRANSLATORS: translating 'runtime' is not advised
564 " -R DIR look in DIR for runtime, instead of\n"
565 " %s\n"
566 " -r DIR cross-compile to kernel with given build tree; or else\n"
567 " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of\n"
568 " %s\n"
569 " -a ARCH cross-compile to given architecture, instead of %s\n"
570 " -m MODULE set probe module name, instead of \n"
571 " %s\n"
572 " -o FILE send script output to file, instead of stdout. This supports\n"
573 " strftime(3) formats for FILE\n"
574 " -E SCRIPT run the SCRIPT in addition to the main script specified\n"
575 " through -e or a script file\n"
576 " -c CMD start the probes, run CMD, and exit when it finishes\n"
577 " -x PID sets target() to PID\n"
578 " -F run as on-file flight recorder with -o.\n"
579 " run as on-memory flight recorder without -o.\n"
580 " -S size[,n] set maximum of the size and the number of files.\n"
581 " -d OBJECT add unwind/symbol data for OBJECT file", runtime_path.c_str(), kernel_build_tree.c_str(), architecture.c_str(), module_name.c_str());
582 if (unwindsym_modules.size() == 0)
583 cout << endl;
584 else
585 cout << _(", in addition to") << endl;
586 {
587 vector<string> syms (unwindsym_modules.begin(), unwindsym_modules.end());
588 for (unsigned i=0; i<syms.size(); i++)
589 cout << " " << syms[i].c_str() << endl;
590 }
591 cout
592 << _F(" --ldd add unwind/symbol data for all referenced object files.\n"
593 " --all-modules\n"
594 " add unwind/symbol data for all loaded kernel objects.\n"
595 " -t collect probe timing information\n"
596 #ifdef HAVE_LIBSQLITE3
597 " -q generate information on tapset coverage\n"
598 #endif /* HAVE_LIBSQLITE3 */
599 " --runtime=MODE\n"
600 " set the pass-5 runtime mode, instead of kernel\n"
601 #ifdef HAVE_DYNINST
602 " --dyninst\n"
603 " shorthand for --runtime=dyninst\n"
604 #endif /* HAVE_DYNINST */
605 " --prologue-searching[=WHEN]\n"
606 " prologue-searching for function probes\n"
607 " --privilege=PRIVILEGE_LEVEL\n"
608 " check the script for constructs not allowed at the given privilege level\n"
609 " --unprivileged\n"
610 " equivalent to --privilege=stapusr\n"
611 " --compatible=VERSION\n"
612 " suppress incompatible language/tapset changes beyond VERSION,\n"
613 " instead of %s\n"
614 " --check-version\n"
615 " displays warnings where a syntax element may be \n"
616 " version dependent\n"
617 " --skip-badvars\n"
618 " substitute zero for bad context $variables\n"
619 " --suppress-handler-errors\n"
620 " catch all runtime errors, quietly skip probe handlers\n"
621 " --use-server[=SERVER-SPEC]\n"
622 " specify systemtap compile-servers\n"
623 " --list-servers[=PROPERTIES]\n"
624 " report on the status of the specified compile-servers:\n"
625 " all,specified,online,trusted,signer,compatible\n"
626 #if HAVE_NSS
627 " --trust-servers[=TRUST-SPEC]\n"
628 " add/revoke trust of specified compile-servers:\n"
629 " ssl,signer,all-users,revoke,no-prompt\n"
630 " --use-server-on-error[=yes/no]\n"
631 " retry compilation using a compile server upon compilation error\n"
632 #endif
633 " --remote=HOSTNAME\n"
634 " run pass 5 on the specified ssh host.\n"
635 " may be repeated for targeting multiple hosts.\n"
636 " --remote-prefix\n"
637 " prefix each line of remote output with a host index.\n"
638 " --tmpdir=NAME\n"
639 " specify name of temporary directory to be used.\n"
640 " --download-debuginfo[=OPTION]\n"
641 " automatically download debuginfo using ABRT.\n"
642 " yes,no,ask,<timeout value>\n"
643 " --dump-probe-types\n"
644 " show a list of available probe types.\n"
645 " --sysroot=DIR\n"
646 " specify sysroot directory where target files (executables,\n" " libraries, etc.) are located.\n"
647 " --sysenv=VAR=VALUE\n"
648 " provide an alternate value for an environment variable\n"
649 " where the value on a remote system differs. Path\n"
650 " variables (e.g. PATH, LD_LIBRARY_PATH) are assumed to be\n"
651 " relative to the sysroot.\n"
652 " --suppress-time-limits\n"
653 " disable -DSTP_OVERLOAD, -DMAXACTION, and -DMAXTRYACTION limits\n"
654 " --save-uprobes\n"
655 " save uprobes.ko to current directory if it is built from source\n"
656 " --target-namesapce=PID\n"
657 " sets the target namespaces pid to PID\n"
658 #if HAVE_MONITOR_LIBS
659 " --monitor=INTERVAL\n"
660 " enables monitor interfaces\n"
661 #endif
662 , compatible.c_str()) << endl
663 ;
664
665 time_t now;
666 time (& now);
667 struct tm* t = localtime (& now);
668 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
669 cout << morehelp << endl;
670
671 throw exit_exception (exitcode);
672 }
673
674 int
675 systemtap_session::parse_cmdline (int argc, char * const argv [])
676 {
677 client_options_disallowed_for_unprivileged = "";
678 struct rlimit our_rlimit;
679 while (true)
680 {
681 char * num_endptr;
682 int grc = getopt_long (argc, argv, STAP_SHORT_OPTIONS, stap_long_options, NULL);
683
684 // NB: when adding new options, consider very carefully whether they
685 // should be restricted from stap clients (after --client-options)!
686
687 if (grc < 0)
688 break;
689 switch (grc)
690 {
691 case 'V':
692 version ();
693 throw exit_exception (EXIT_SUCCESS);
694
695 case 'v':
696 server_args.push_back (string ("-") + (char)grc);
697 for (unsigned i=0; i<5; i++)
698 perpass_verbose[i] ++;
699 verbose ++;
700 break;
701
702 case 'G':
703 // Make sure the global option is only composed of the
704 // following chars: [_=a-zA-Z0-9]
705 assert(optarg);
706 assert_regexp_match("-G parameter", optarg, "^[a-z_][a-z0-9_]*=[a-z0-9_-]+$");
707 globalopts.push_back (string(optarg));
708 break;
709
710 case 't':
711 server_args.push_back (string ("-") + (char)grc);
712 timing = true;
713 break;
714
715 case 'w':
716 server_args.push_back (string ("-") + (char)grc);
717 suppress_warnings = true;
718 break;
719
720 case 'W':
721 server_args.push_back (string ("-") + (char)grc);
722 panic_warnings = true;
723 break;
724
725 case 'p':
726 assert(optarg);
727 last_pass = (int)strtoul(optarg, &num_endptr, 10);
728 if (*num_endptr != '\0' || last_pass < 1 || last_pass > 5)
729 {
730 cerr << _("Invalid pass number (should be 1-5).") << endl;
731 return 1;
732 }
733 server_args.push_back (string ("-") + (char)grc + optarg);
734 break;
735
736 case 'I':
737 assert(optarg);
738 if (client_options)
739 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-I" : ", -I";
740 if (include_arg_start == -1)
741 include_arg_start = include_path.size ();
742 include_path.push_back (string (optarg));
743 break;
744
745 case 'd':
746 assert(optarg);
747 server_args.push_back (string ("-") + (char)grc + optarg);
748 {
749 // Make sure an empty data object wasn't specified (-d "")
750 if (strlen (optarg) == 0)
751 {
752 cerr << _("Data object (-d) cannot be empty.") << endl;
753 return 1;
754 }
755 // At runtime user module names are resolved through their
756 // canonical (absolute) path, or else it's a kernel module name.
757 unwindsym_modules.insert (resolve_path (optarg));
758 // NB: we used to enable_vma_tracker() here for PR10228, but now
759 // we'll leave that to pragma:vma functions which actually use it.
760 break;
761 }
762
763 case 'e':
764 assert(optarg);
765 if (have_script)
766 {
767 cerr << _("Only one script can be given on the command line.")
768 << endl;
769 return 1;
770 }
771 server_args.push_back (string ("-") + (char)grc + optarg);
772 cmdline_script = string (optarg);
773 have_script = true;
774 break;
775
776 case 'E':
777 assert(optarg);
778 server_args.push_back (string("-") + (char)grc + optarg);
779 additional_scripts.push_back(string (optarg));
780 // don't set have_script to true, since this script is meant to be
781 // given in addition to a script/script_file.
782 break;
783
784 case 'o':
785 assert(optarg);
786 // NB: client_options not a problem, since pass 1-4 does not use output_file.
787 server_args.push_back (string ("-") + (char)grc + optarg);
788 output_file = string (optarg);
789 break;
790
791 case 'R':
792 assert(optarg);
793 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-R", "--client-options") << endl; return 1; }
794 runtime_specified = true;
795 runtime_path = string (optarg);
796 break;
797
798 case 'm':
799 assert(optarg);
800 if (client_options)
801 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-m" : ", -m";
802 module_name = string (optarg);
803 save_module = true;
804 modname_given = true;
805 {
806 // If the module name ends with '.ko', chop it off since
807 // modutils doesn't like modules named 'foo.ko.ko'.
808 if (endswith(module_name, ".ko") || endswith(module_name, ".so"))
809 {
810 module_name.erase(module_name.size() - 3);
811 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
812 }
813
814 // Make sure an empty module name wasn't specified (-m "")
815 if (module_name.empty())
816 {
817 cerr << _("Module name cannot be empty.") << endl;
818 return 1;
819 }
820
821 // Make sure the module name is only composed of the
822 // following chars: [a-z0-9_]
823 assert_regexp_match("-m parameter", module_name, "^[a-z0-9_]+$");
824
825 // Make sure module name isn't too long.
826 if (module_name.size() >= (MODULE_NAME_LEN - 1))
827 {
828 module_name.resize(MODULE_NAME_LEN - 1);
829 cerr << _F("Truncating module name to '%s'", module_name.c_str()) << endl;
830 }
831 }
832
833 server_args.push_back (string ("-") + (char)grc + optarg);
834 use_script_cache = false;
835 break;
836
837 case 'r':
838 assert(optarg);
839 if (client_options) // NB: no paths!
840 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
841 server_args.push_back (string ("-") + (char)grc + optarg);
842 setup_kernel_release(optarg);
843 break;
844
845 case 'a':
846 assert(optarg);
847 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
848 server_args.push_back (string ("-") + (char)grc + optarg);
849 architecture = string(optarg);
850 break;
851
852 case 'k':
853 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-k", "--client-options") << endl; return 1; }
854 keep_tmpdir = true;
855 use_script_cache = false; /* User wants to keep a usable build tree. */
856 break;
857
858 case 'g':
859 server_args.push_back (string ("-") + (char)grc);
860 guru_mode = true;
861 break;
862
863 case 'P':
864 server_args.push_back (string ("-") + (char)grc);
865 prologue_searching_mode = prologue_searching_always;
866 break;
867
868 case 'b':
869 server_args.push_back (string ("-") + (char)grc);
870 bulk_mode = true;
871 break;
872
873 case 'u':
874 server_args.push_back (string ("-") + (char)grc);
875 unoptimized = true;
876 break;
877
878 case 's':
879 assert(optarg);
880 buffer_size = (int) strtoul (optarg, &num_endptr, 10);
881 if (*num_endptr != '\0' || buffer_size < 1 || buffer_size > 4095)
882 {
883 cerr << _("Invalid buffer size (should be 1-4095).") << endl;
884 return 1;
885 }
886 server_args.push_back (string ("-") + (char)grc + optarg);
887 break;
888
889 case 'c':
890 assert(optarg);
891 cmd = string (optarg);
892 if (cmd == "")
893 {
894 // This would mess with later code deciding to pass -c
895 // through to staprun
896 cerr << _("Empty CMD string invalid.") << endl;
897 return 1;
898 }
899 server_args.push_back (string ("-") + (char)grc + optarg);
900 break;
901
902 case 'x':
903 assert(optarg);
904 target_pid = (int) strtoul(optarg, &num_endptr, 10);
905 if (*num_endptr != '\0')
906 {
907 cerr << _("Invalid target process ID number.") << endl;
908 return 1;
909 }
910 server_args.push_back (string ("-") + (char)grc + optarg);
911 break;
912
913 case 'D':
914 assert(optarg);
915 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
916 if (client_options)
917 client_options_disallowed_for_unprivileged += client_options_disallowed_for_unprivileged.empty () ? "-D" : ", -D";
918 server_args.push_back (string ("-") + (char)grc + optarg);
919 c_macros.push_back (string (optarg));
920 break;
921
922 case 'S':
923 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
924 assert(optarg);
925 server_args.push_back (string ("-") + (char)grc + optarg);
926 size_option = string (optarg);
927 break;
928
929 case 'q':
930 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-q", "--client-options") << endl; return 1; }
931 server_args.push_back (string ("-") + (char)grc);
932 tapset_compile_coverage = true;
933 break;
934
935 case 'h':
936 usage (0);
937 break;
938
939 case 'L':
940 if (dump_mode)
941 {
942 cerr << _("ERROR: only one of the -l/-L/--dump-* "
943 "switches may be specified") << endl;
944 return 1;
945 }
946 assert(optarg);
947 server_args.push_back (string ("-") + (char)grc + optarg);
948 dump_mode = systemtap_session::dump_matched_probes_vars;
949 dump_matched_pattern = optarg;
950 unoptimized = true; // This causes retention of vars for listing
951 suppress_warnings = true;
952 break;
953
954 case 'l':
955 if (dump_mode)
956 {
957 cerr << _("ERROR: only one of the -l/-L/--dump-* "
958 "switches may be specified") << endl;
959 return 1;
960 }
961 assert(optarg);
962 server_args.push_back (string ("-") + (char)grc + optarg);
963 dump_mode = systemtap_session::dump_matched_probes;
964 dump_matched_pattern = optarg;
965 suppress_warnings = true;
966 break;
967
968 case 'F':
969 server_args.push_back (string ("-") + (char)grc);
970 load_only = true;
971 break;
972
973 case 'B':
974 if (client_options) { cerr << _F("ERROR: %s invalid with %s", "-B", "--client-options") << endl; return 1; }
975 assert(optarg);
976 server_args.push_back (string ("-") + (char)grc + optarg);
977 kbuildflags.push_back (string (optarg));
978 break;
979
980 case LONG_OPT_VERSION:
981 version ();
982 throw exit_exception (EXIT_SUCCESS);
983
984 case LONG_OPT_VERBOSE_PASS:
985 {
986 assert(optarg);
987 bool ok = true;
988 if (strlen(optarg) < 1 || strlen(optarg) > 5)
989 ok = false;
990 if (ok)
991 {
992 for (unsigned i=0; i<strlen(optarg); i++)
993 if (isdigit (optarg[i]))
994 perpass_verbose[i] += optarg[i]-'0';
995 else
996 ok = false;
997 }
998 if (! ok)
999 {
1000 cerr << _("Invalid --vp argument: it takes 1 to 5 digits.") << endl;
1001 return 1;
1002 }
1003 // NB: we don't do this: last_pass = strlen(optarg);
1004 server_args.push_back ("--vp=" + string(optarg));
1005 break;
1006 }
1007
1008 case LONG_OPT_SKIP_BADVARS:
1009 server_args.push_back ("--skip-badvars");
1010 skip_badvars = true;
1011 break;
1012
1013 case LONG_OPT_PRIVILEGE:
1014 {
1015 // We allow only multiple privilege-setting options if they all specify the same
1016 // privilege level. The server also expects and depends on this behaviour when
1017 // examining the client-side options passed to it.
1018 privilege_t newPrivilege;
1019 if (strcmp (optarg, "stapdev") == 0)
1020 newPrivilege = pr_stapdev;
1021 else if (strcmp (optarg, "stapsys") == 0)
1022 newPrivilege = pr_stapsys;
1023 else if (strcmp (optarg, "stapusr") == 0)
1024 newPrivilege = pr_stapusr;
1025 else
1026 {
1027 cerr << _F("Invalid argument '%s' for --privilege.", optarg) << endl;
1028 return 1;
1029 }
1030 if (privilege_set && newPrivilege != privilege)
1031 {
1032 cerr << _("Privilege level may be set only once.") << endl;
1033 return 1;
1034 }
1035 privilege = newPrivilege;
1036 privilege_set = true;
1037 server_args.push_back ("--privilege=" + string(optarg));
1038 }
1039 /* NB: for server security, it is essential that once this flag is
1040 set, no future flag be able to unset it. */
1041 break;
1042
1043 case LONG_OPT_UNPRIVILEGED:
1044 // We allow only multiple privilege-setting options if they all specify the same
1045 // privilege level. The server also expects and depends on this behaviour when
1046 // examining the client-side options passed to it.
1047 if (privilege_set && pr_unprivileged != privilege)
1048 {
1049 cerr << _("Privilege level may be set only once.") << endl;
1050 return 1;
1051 }
1052 privilege = pr_unprivileged;
1053 privilege_set = true;
1054 server_args.push_back ("--unprivileged");
1055 /* NB: for server security, it is essential that once this flag is
1056 set, no future flag be able to unset it. */
1057 break;
1058
1059 case LONG_OPT_CLIENT_OPTIONS:
1060 client_options = true;
1061 break;
1062
1063 case LONG_OPT_TMPDIR:
1064 if (client_options) {
1065 cerr << _F("ERROR: %s is invalid with %s", "--tmpdir", "--client-options") << endl;
1066 return 1;
1067 }
1068 tmpdir_opt_set = true;
1069 tmpdir = optarg;
1070 break;
1071
1072 case LONG_OPT_DOWNLOAD_DEBUGINFO:
1073 if(optarg)
1074 {
1075 if(strcmp(optarg, "no") == 0)
1076 download_dbinfo = 0; //Disable feature
1077 else if (strcmp(optarg, "yes") == 0)
1078 download_dbinfo = INT_MAX; //Enable, No Timeout
1079 /* NOTE: Timeout and Asking for Confirmation features below are not supported yet by abrt
1080 * in version abrt-2.0.3-1.fc15.x86_64, Bugzilla: BZ730107 (timeout), BZ726192 ('-y') */
1081 else if(atoi(optarg) > 0)
1082 download_dbinfo = atoi(optarg); //Enable, Set timeout to optarg
1083 else if (strcmp(optarg, "ask") == 0)
1084 download_dbinfo = -1; //Enable, Ask for confirmation
1085 else
1086 {
1087 cerr << _F("ERROR: %s is not a valid value. Use 'yes', 'no', 'ask' or a timeout value.", optarg) << endl;
1088 return 1;
1089 }
1090 }
1091 else
1092 download_dbinfo = INT_MAX; //Enable, No Timeout
1093 break;
1094
1095 case LONG_OPT_USE_SERVER:
1096 if (client_options) {
1097 cerr << _F("ERROR: %s is invalid with %s", "--use-server", "--client-options") << endl;
1098 return 1;
1099 }
1100 if (optarg)
1101 specified_servers.push_back (optarg);
1102 else
1103 specified_servers.push_back ("");
1104 break;
1105
1106 case LONG_OPT_USE_SERVER_ON_ERROR:
1107 if (client_options) {
1108 cerr << _F("ERROR: %s is invalid with %s", "--use-server-on-error", "--client-options") << endl;
1109 return 1;
1110 }
1111 if (optarg)
1112 {
1113 string arg = optarg;
1114 for (unsigned i = 0; i < arg.size (); ++i)
1115 arg[i] = tolower (arg[i]);
1116 if (arg == "yes" || arg == "ye" || arg == "y")
1117 use_server_on_error = true;
1118 else if (arg == "no" || arg == "n")
1119 use_server_on_error = false;
1120 else
1121 cerr << _F("Invalid argument '%s' for --use-server-on-error.", optarg) << endl;
1122 }
1123 else
1124 use_server_on_error = true;
1125 break;
1126
1127 case LONG_OPT_LIST_SERVERS:
1128 if (client_options) {
1129 cerr << _F("ERROR: %s is invalid with %s", "--list-servers", "--client-options") << endl;
1130 return 1;
1131 }
1132 if (optarg)
1133 server_status_strings.push_back (optarg);
1134 else
1135 server_status_strings.push_back ("");
1136 break;
1137
1138 case LONG_OPT_TRUST_SERVERS:
1139 if (client_options) {
1140 cerr << _F("ERROR: %s is invalid with %s", "--trust-servers", "--client-options") << endl;
1141 return 1;
1142 }
1143 if (optarg)
1144 server_trust_spec = optarg;
1145 else
1146 server_trust_spec = "ssl";
1147 break;
1148
1149 case LONG_OPT_HELP:
1150 usage (0);
1151 break;
1152
1153 // The caching options should not be available to server clients
1154 case LONG_OPT_DISABLE_CACHE:
1155 if (client_options) {
1156 cerr << _F("ERROR: %s is invalid with %s", "--disable-cache", "--client-options") << endl;
1157 return 1;
1158 }
1159 use_cache = use_script_cache = false;
1160 break;
1161
1162 case LONG_OPT_POISON_CACHE:
1163 if (client_options) {
1164 cerr << _F("ERROR: %s is invalid with %s", "--poison-cache", "--client-options") << endl;
1165 return 1;
1166 }
1167 poison_cache = true;
1168 break;
1169
1170 case LONG_OPT_CLEAN_CACHE:
1171 if (client_options) {
1172 cerr << _F("ERROR: %s is invalid with %s", "--clean-cache", "--client-options") << endl;
1173 return 1;
1174 }
1175 clean_cache(*this);
1176 throw exit_exception(EXIT_SUCCESS);
1177
1178 case LONG_OPT_COMPATIBLE:
1179 server_args.push_back ("--compatible=" + string(optarg));
1180 if (strverscmp(optarg, VERSION) > 0) {
1181 cerr << _F("ERROR: systemtap version %s cannot be compatible with future version %s", VERSION, optarg)
1182 << endl;
1183 return 1;
1184 }
1185 compatible = optarg;
1186 break;
1187
1188 case LONG_OPT_LDD:
1189 if (client_options) {
1190 cerr << _F("ERROR: %s is invalid with %s", "--ldd", "--client-options") << endl;
1191 return 1;
1192 }
1193 unwindsym_ldd = true;
1194 break;
1195
1196 case LONG_OPT_ALL_MODULES:
1197 if (client_options) {
1198 cerr << _F("ERROR: %s is invalid with %s", "--all-modules", "--client-options") << endl;
1199 return 1;
1200 }
1201 insert_loaded_modules();
1202 break;
1203
1204 case LONG_OPT_REMOTE:
1205 if (client_options) {
1206 cerr << _F("ERROR: %s is invalid with %s", "--remote", "--client-options") << endl;
1207 return 1;
1208 }
1209
1210 remote_uris.push_back(optarg);
1211 break;
1212
1213 case LONG_OPT_REMOTE_PREFIX:
1214 if (client_options) {
1215 cerr << _F("ERROR: %s is invalid with %s", "--remote-prefix", "--client-options") << endl;
1216 return 1;
1217 }
1218
1219 use_remote_prefix = true;
1220 break;
1221
1222 case LONG_OPT_CHECK_VERSION:
1223 server_args.push_back ("--check-version");
1224 systemtap_v_check = true;
1225 break;
1226
1227 case LONG_OPT_DUMP_PROBE_TYPES:
1228 if (dump_mode)
1229 {
1230 cerr << _("ERROR: only one of the -l/-L/--dump-* "
1231 "switches may be specified") << endl;
1232 return 1;
1233 }
1234 server_args.push_back ("--dump-probe-types");
1235 dump_mode = systemtap_session::dump_probe_types;
1236 break;
1237
1238 case LONG_OPT_DUMP_PROBE_ALIASES:
1239 if (dump_mode)
1240 {
1241 cerr << _("ERROR: only one of the -l/-L/--dump-* "
1242 "switches may be specified") << endl;
1243 return 1;
1244 }
1245 server_args.push_back ("--dump-probe-aliases");
1246 suppress_warnings = true;
1247 dump_mode = systemtap_session::dump_probe_aliases;
1248 break;
1249
1250 case LONG_OPT_DUMP_FUNCTIONS:
1251 if (dump_mode)
1252 {
1253 cerr << _("ERROR: only one of the -l/-L/--dump-* "
1254 "switches may be specified") << endl;
1255 return 1;
1256 }
1257 server_args.push_back ("--dump-functions");
1258 suppress_warnings = true;
1259 dump_mode = systemtap_session::dump_functions;
1260 unoptimized = true; // Keep unused functions (which is all of them)
1261 break;
1262
1263 case LONG_OPT_SUPPRESS_HANDLER_ERRORS:
1264 suppress_handler_errors = true;
1265 c_macros.push_back (string ("STAP_SUPPRESS_HANDLER_ERRORS"));
1266 break;
1267
1268 case LONG_OPT_MODINFO:
1269 // Make sure the global option is only composed of the
1270 // following chars: [_=a-zA-Z0-9]
1271 if (client_options) {
1272 cerr << _F("ERROR: %s is invalid with %s", "--modinfo", "--client-options") << endl;
1273 return 1;
1274 }
1275 assert_regexp_match("--modinfo parameter", optarg, "^[a-z_][a-z0-9_]*=.+$");
1276 modinfos.push_back (string(optarg));
1277 break;
1278
1279 case LONG_OPT_RLIMIT_AS:
1280 if(getrlimit(RLIMIT_AS, & our_rlimit))
1281 cerr << _F("Unable to obtain resource limits for rlimit_as : %s", strerror (errno)) << endl;
1282 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
1283 if(*num_endptr || setrlimit (RLIMIT_AS, & our_rlimit))
1284 cerr << _F("Unable to set resource limits for rlimit_as : %s", strerror (errno)) << endl;
1285 /* Disable core dumps, since exhaustion results in uncaught bad_alloc etc. exceptions */
1286 our_rlimit.rlim_max = our_rlimit.rlim_cur = 0;
1287 (void) setrlimit (RLIMIT_CORE, & our_rlimit);
1288 break;
1289
1290 case LONG_OPT_RLIMIT_CPU:
1291 if(getrlimit(RLIMIT_CPU, & our_rlimit))
1292 cerr << _F("Unable to obtain resource limits for rlimit_cpu : %s", strerror (errno)) << endl;
1293 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
1294 if(*num_endptr || setrlimit (RLIMIT_CPU, & our_rlimit))
1295 cerr << _F("Unable to set resource limits for rlimit_cpu : %s", strerror (errno)) << endl;
1296 break;
1297
1298 case LONG_OPT_RLIMIT_NPROC:
1299 if(getrlimit(RLIMIT_NPROC, & our_rlimit))
1300 cerr << _F("Unable to obtain resource limits for rlimit_nproc : %s", strerror (errno)) << endl;
1301 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
1302 if(*num_endptr || setrlimit (RLIMIT_NPROC, & our_rlimit))
1303 cerr << _F("Unable to set resource limits for rlimit_nproc : %s", strerror (errno)) << endl;
1304 break;
1305
1306 case LONG_OPT_RLIMIT_STACK:
1307 if(getrlimit(RLIMIT_STACK, & our_rlimit))
1308 cerr << _F("Unable to obtain resource limits for rlimit_stack : %s", strerror (errno)) << endl;
1309 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
1310 if(*num_endptr || setrlimit (RLIMIT_STACK, & our_rlimit))
1311 cerr << _F("Unable to set resource limits for rlimit_stack : %s", strerror (errno)) << endl;
1312 /* Disable core dumps, since exhaustion results in SIGSEGV */
1313 our_rlimit.rlim_max = our_rlimit.rlim_cur = 0;
1314 (void) setrlimit (RLIMIT_CORE, & our_rlimit);
1315 break;
1316
1317 case LONG_OPT_RLIMIT_FSIZE:
1318 if(getrlimit(RLIMIT_FSIZE, & our_rlimit))
1319 cerr << _F("Unable to obtain resource limits for rlimit_fsize : %s", strerror (errno)) << endl;
1320 our_rlimit.rlim_max = our_rlimit.rlim_cur = strtoul (optarg, &num_endptr, 0);
1321 if(*num_endptr || setrlimit (RLIMIT_FSIZE, & our_rlimit))
1322 cerr << _F("Unable to set resource limits for rlimit_fsize : %s", strerror (errno)) << endl;
1323 break;
1324
1325 case LONG_OPT_SYSROOT:
1326 if (client_options) {
1327 cerr << _F("ERROR: %s invalid with %s", "--sysroot", "--client-options") << endl;
1328 return 1;
1329 } else if (!sysroot.empty()) {
1330 cerr << "ERROR: multiple --sysroot options not supported" << endl;
1331 return 1;
1332 } else {
1333 char *spath = canonicalize_file_name (optarg);
1334 if (spath == NULL) {
1335 cerr << _F("ERROR: %s is an invalid directory for --sysroot", optarg) << endl;
1336 return 1;
1337 }
1338
1339 sysroot = string(spath);
1340 free (spath);
1341 if (sysroot[sysroot.size() - 1] != '/')
1342 sysroot.append("/");
1343
1344 break;
1345 }
1346
1347 case LONG_OPT_SYSENV:
1348 if (client_options) {
1349 cerr << _F("ERROR: %s invalid with %s", "--sysenv", "--client-options") << endl;
1350 return 1;
1351 } else {
1352 string sysenv_str = optarg;
1353 string value;
1354 size_t pos;
1355 if (sysroot.empty()) {
1356 cerr << "ERROR: --sysenv must follow --sysroot" << endl;
1357 return 1;
1358 }
1359
1360 pos = sysenv_str.find("=");
1361 if (pos == string::npos) {
1362 cerr << _F("ERROR: %s is an invalid argument for --sysenv", optarg) << endl;
1363 return 1;
1364 }
1365
1366 value = sysenv_str.substr(pos + 1);
1367 sysenv[sysenv_str.substr(0, pos)] = value;
1368
1369 break;
1370 }
1371
1372 case LONG_OPT_SUPPRESS_TIME_LIMITS: //require guru_mode to use
1373 if (guru_mode == false)
1374 {
1375 cerr << _F("ERROR %s requires guru mode (-g)", "--suppress-time-limits") << endl;
1376 return 1;
1377 }
1378 else
1379 {
1380 suppress_time_limits = true;
1381 server_args.push_back (string ("--suppress-time-limits"));
1382 c_macros.push_back (string ("STAP_SUPPRESS_TIME_LIMITS_ENABLE"));
1383 break;
1384 }
1385
1386 case LONG_OPT_RUNTIME:
1387 if (!parse_cmdline_runtime (optarg))
1388 return 1;
1389 break;
1390
1391 case LONG_OPT_RUNTIME_DYNINST:
1392 if (!parse_cmdline_runtime ("dyninst"))
1393 return 1;
1394 break;
1395
1396 case LONG_OPT_BENCHMARK_SDT:
1397 // XXX This option is secret, not supported, subject to change at our whim
1398 benchmark_sdt_threads = sysconf(_SC_NPROCESSORS_ONLN);
1399 break;
1400
1401 case LONG_OPT_BENCHMARK_SDT_LOOPS:
1402 assert(optarg != 0); // optarg can't be NULL (or getopt would choke)
1403 // XXX This option is secret, not supported, subject to change at our whim
1404 benchmark_sdt_loops = strtoul(optarg, NULL, 10);
1405 break;
1406
1407 case LONG_OPT_BENCHMARK_SDT_THREADS:
1408 assert(optarg != 0); // optarg can't be NULL (or getopt would choke)
1409 // XXX This option is secret, not supported, subject to change at our whim
1410 benchmark_sdt_threads = strtoul(optarg, NULL, 10);
1411 break;
1412
1413 case LONG_OPT_COLOR_ERRS:
1414 // --color without arg is equivalent to always
1415 if (!optarg || !strcmp(optarg, "always"))
1416 color_mode = color_always;
1417 else if (!strcmp(optarg, "auto"))
1418 color_mode = color_auto;
1419 else if (!strcmp(optarg, "never"))
1420 color_mode = color_never;
1421 else {
1422 cerr << _F("Invalid argument '%s' for --color.", optarg) << endl;
1423 return 1;
1424 }
1425 color_errors = color_mode == color_always
1426 || (color_mode == color_auto && isatty(STDERR_FILENO) &&
1427 strcmp(getenv("TERM") ?: "notdumb", "dumb"));
1428 break;
1429
1430 case LONG_OPT_PROLOGUE_SEARCHING:
1431 // --prologue-searching without arg is equivalent to always
1432 if (!optarg || !strcmp(optarg, "always"))
1433 prologue_searching_mode = prologue_searching_always;
1434 else if (!strcmp(optarg, "auto"))
1435 prologue_searching_mode = prologue_searching_auto;
1436 else if (!strcmp(optarg, "never"))
1437 prologue_searching_mode = prologue_searching_never;
1438 else {
1439 cerr << _F("Invalid argument '%s' for --prologue-searching.", optarg) << endl;
1440 return 1;
1441 }
1442 break;
1443
1444 case LONG_OPT_SAVE_UPROBES:
1445 save_uprobes = true;
1446 break;
1447
1448 case LONG_OPT_TARGET_NAMESPACES:
1449 assert(optarg);
1450 target_namespaces_pid = (int) strtoul(optarg, &num_endptr, 10);
1451 if (*num_endptr != '\0' || target_namespaces_pid < 1)
1452 {
1453 cerr << _("Invalid process ID number for target namespaces.") << endl;
1454 return 1;
1455 }
1456 break;
1457
1458 case LONG_OPT_MONITOR:
1459 monitor = true;
1460 if (optarg)
1461 {
1462 monitor_interval = (int) strtoul(optarg, &num_endptr, 10);
1463 if (*num_endptr != '\0' || monitor_interval < 1)
1464 {
1465 cerr << _("Invalid monitor interval.") << endl;
1466 return 1;
1467 }
1468 }
1469 break;
1470
1471 case '?':
1472 // Invalid/unrecognized option given or argument required, but
1473 // not given. In both cases getopt_long() will have printed the
1474 // appropriate error message to stderr already.
1475 usage(1);
1476 break;
1477
1478 default:
1479 // NOTREACHED unless one added a getopt option but not a corresponding case:
1480 cerr << _F("Unhandled argument code %d", (char)grc) << endl;
1481 return 1;
1482 break;
1483 }
1484 }
1485
1486 return 0;
1487 }
1488
1489 bool
1490 systemtap_session::parse_cmdline_runtime (const string& opt_runtime)
1491 {
1492 if (opt_runtime == string("kernel"))
1493 runtime_mode = kernel_runtime;
1494 else if (opt_runtime == string("dyninst"))
1495 {
1496 #ifndef HAVE_DYNINST
1497 cerr << _("ERROR: --runtime=dyninst unavailable; this build lacks DYNINST feature") << endl;
1498 version();
1499 return false;
1500 #else
1501 if (privilege_set && pr_unprivileged != privilege)
1502 {
1503 cerr << _("ERROR: --runtime=dyninst implies unprivileged mode only") << endl;
1504 return false;
1505 }
1506 privilege = pr_unprivileged;
1507 privilege_set = true;
1508 runtime_mode = dyninst_runtime;
1509 #endif
1510 }
1511 else
1512 {
1513 cerr << _F("ERROR: %s is an invalid argument for --runtime", opt_runtime.c_str()) << endl;
1514 return false;
1515 }
1516
1517 return true;
1518 }
1519
1520 void
1521 systemtap_session::check_options (int argc, char * const argv [])
1522 {
1523 for (int i = optind; i < argc; i++)
1524 {
1525 if (! have_script && ! dump_mode)
1526 {
1527 script_file = string (argv[i]);
1528 have_script = true;
1529 }
1530 else
1531 args.push_back (string (argv[i]));
1532 }
1533
1534 // We don't need a script with --list-servers, --trust-servers, or any dump mode
1535 bool need_script = server_status_strings.empty () &&
1536 server_trust_spec.empty () &&
1537 !dump_mode;
1538
1539 if (benchmark_sdt_loops > 0 || benchmark_sdt_threads > 0)
1540 {
1541 // Secret benchmarking options are for local use only, not servers or --remote
1542 if (client_options || !remote_uris.empty())
1543 {
1544 cerr << _("Benchmark options are only for local use.") << endl;
1545 usage(1);
1546 }
1547
1548 // Fill defaults if either is unset.
1549 if (benchmark_sdt_loops == 0)
1550 benchmark_sdt_loops = 10000000;
1551 if (benchmark_sdt_threads == 0)
1552 benchmark_sdt_threads = 1;
1553
1554 need_script = false;
1555 }
1556
1557 // need a user file
1558 // NB: this is also triggered if stap is invoked with no arguments at all
1559 if (need_script && ! have_script)
1560 {
1561 cerr << _("A script must be specified.") << endl;
1562 usage(1);
1563 }
1564 if (dump_mode && have_script)
1565 {
1566 cerr << _("Cannot specify a script with -l/-L/--dump-* switches.") << endl;
1567 usage(1);
1568 }
1569 if (dump_mode && last_pass != 5)
1570 {
1571 cerr << _("Cannot specify -p with -l/-L/--dump-* switches.") << endl;
1572 usage(1);
1573 }
1574
1575 #if ! HAVE_NSS
1576 if (client_options)
1577 print_warning("--client-options is not supported by this version of systemtap");
1578
1579 if (! server_status_strings.empty ())
1580 {
1581 print_warning("--list-servers is not supported by this version of systemtap");
1582 server_status_strings.clear ();
1583 }
1584
1585 if (! server_trust_spec.empty ())
1586 {
1587 print_warning("--trust-servers is not supported by this version of systemtap");
1588 server_trust_spec.clear ();
1589 }
1590 #endif
1591
1592 #if ! HAVE_MONITOR_LIBS
1593 if (monitor)
1594 {
1595 print_warning("Monitor mode is not supported by this version of systemtap");
1596 exit(1);
1597 }
1598 #endif
1599
1600 if (runtime_specified && ! specified_servers.empty ())
1601 {
1602 print_warning("Ignoring --use-server due to the use of -R");
1603 specified_servers.clear ();
1604 }
1605
1606 if (client_options && last_pass > 4)
1607 {
1608 last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
1609 }
1610
1611 // If phase 5 has been requested, automatically adjust the --privilege setting to match the
1612 // user's actual privilege level and add --use-server, if necessary.
1613 // Do this only if we have a script and we are not the server.
1614 // Also do this only if we're running in the kernel (e.g. not --runtime=dyninst)
1615 // XXX Eventually we could check remote hosts, but disable that case for now.
1616 if (last_pass > 4 && have_script && ! client_options &&
1617 runtime_mode == kernel_runtime && remote_uris.empty())
1618 {
1619 // What is the user's privilege level?
1620 privilege_t credentials = get_privilege_credentials ();
1621 // Don't alter specifically-requested privilege levels
1622 if (! privilege_set && ! pr_contains (credentials, privilege))
1623 {
1624 // We do not have the default privilege credentials (stapdev). Lower
1625 // the privilege level to match our credentials.
1626 if (pr_contains (credentials, pr_stapsys))
1627 {
1628 privilege = pr_stapsys;
1629 server_args.push_back ("--privilege=stapsys");
1630 auto_privilege_level_msg =
1631 _("--privilege=stapsys was automatically selected because you are a member "
1632 "of the groups stapusr and stapsys. [man stap]");
1633 }
1634 else if (pr_contains (credentials, pr_stapusr))
1635 {
1636 privilege = pr_stapusr;
1637 server_args.push_back ("--privilege=stapusr");
1638 auto_privilege_level_msg =
1639 _("--privilege=stapusr was automatically selected because you are a member "
1640 "of the group stapusr. [man stap]");
1641 }
1642 else
1643 {
1644 // Completely unprivileged user.
1645 cerr << _("You are trying to run systemtap as a normal user.\n"
1646 "You should either be root, or be part of "
1647 "the group \"stapusr\" and possibly one of the groups "
1648 "\"stapsys\" or \"stapdev\". [man stap]\n");
1649 #if HAVE_DYNINST
1650 cerr << _("Alternatively, you may specify --runtime=dyninst for userspace probing.\n");
1651 #endif
1652 usage (1); // does not return.
1653 }
1654 }
1655 // Add --use-server if not already specified and the user's (lack of) credentials require
1656 // it for pass 5.
1657 if (! pr_contains (credentials, pr_stapdev))
1658 {
1659 enable_auto_server (
1660 _F("For users with the privilege level %s, the module created by compiling your "
1661 "script must be signed by a trusted systemtap compile-server. [man stap-server]",
1662 pr_name (credentials)));
1663 }
1664 }
1665
1666 if (client_options && ! pr_contains (privilege, pr_stapdev) && ! client_options_disallowed_for_unprivileged.empty ())
1667 {
1668 cerr << _F("You can't specify %s when --privilege=%s is specified.",
1669 client_options_disallowed_for_unprivileged.c_str(),
1670 pr_name (privilege))
1671 << endl;
1672 usage (1);
1673 }
1674 if ((cmd != "") && (target_pid))
1675 {
1676 cerr << _F("You can't specify %s and %s together.", "-c", "-x") << endl;
1677 usage (1);
1678 }
1679
1680 // NB: In user-mode runtimes (dyninst), we can allow guru mode any time, but we
1681 // need to restrict guru by privilege level in the kernel runtime.
1682 if (! runtime_usermode_p () && ! pr_contains (privilege, pr_stapdev) && guru_mode)
1683 {
1684 cerr << _F("You can't specify %s and --privilege=%s together.", "-g", pr_name (privilege))
1685 << endl;
1686 usage (1);
1687 }
1688
1689 // Can't use --remote and --tmpdir together because with --remote,
1690 // there may be more than one tmpdir needed.
1691 if (!remote_uris.empty() && tmpdir_opt_set)
1692 {
1693 cerr << _F("You can't specify %s and %s together.", "--remote", "--tmpdir") << endl;
1694 usage(1);
1695 }
1696 // Warn in case the target kernel release doesn't match the running one.
1697 native_build = (release == kernel_release &&
1698 machine == architecture); // NB: squashed ARCH by PR4186 logic
1699
1700 // Non-native builds can't be loaded locally, but may still work on remotes
1701 if (last_pass > 4 && !native_build && remote_uris.empty())
1702 {
1703 print_warning("kernel release/architecture mismatch with host forces last-pass 4.");
1704 last_pass = 4;
1705 }
1706 if(download_dbinfo != 0 && access ("/usr/bin/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0
1707 && access ("/usr/libexec/abrt-action-install-debuginfo-to-abrt-cache", X_OK) < 0)
1708 {
1709 print_warning("abrt-action-install-debuginfo-to-abrt-cache is not installed. Continuing without downloading debuginfo.");
1710 download_dbinfo = 0;
1711 }
1712
1713 // translate path of runtime to absolute path
1714 if (runtime_path[0] != '/')
1715 {
1716 char cwd[PATH_MAX];
1717 if (getcwd(cwd, sizeof(cwd)))
1718 {
1719 runtime_path = string(cwd) + "/" + runtime_path;
1720 }
1721 }
1722
1723 // Abnormal characters in our temp path can break us, including parts out
1724 // of our control like Kbuild. Let's enforce nice, safe characters only.
1725 const char *tmpdir = getenv("TMPDIR");
1726 if (tmpdir != NULL)
1727 assert_regexp_match("TMPDIR", tmpdir, "^[-/._0-9a-z]+$");
1728
1729 // If the kernel is using signed modules, we need to enforce server
1730 // use.
1731 if (!client_options && modules_must_be_signed())
1732 {
1733 // Force server use to be on, if not on already.
1734 enable_auto_server (
1735 _("The kernel on your system requires modules to be signed for loading.\n"
1736 "The module created by compiling your script must be signed by a systemtap "
1737 "compile-server. [man stap-server]"));
1738
1739 // Cache the current system's machine owner key (MOK)
1740 // information, to pass over to the server.
1741 get_mok_info();
1742 }
1743 }
1744
1745 int
1746 systemtap_session::parse_kernel_config ()
1747 {
1748 // PR10702: pull config options
1749 string kernel_config_file = kernel_build_tree + "/.config";
1750 struct stat st;
1751 int rc = stat(kernel_config_file.c_str(), &st);
1752 if (rc != 0)
1753 {
1754 clog << _F("Checking \"%s\" failed with error: %s",
1755 kernel_config_file.c_str(), strerror(errno)) << endl;
1756 find_devel_rpms(*this, kernel_build_tree.c_str());
1757 missing_rpm_list_print(*this, "-devel");
1758 return rc;
1759 }
1760
1761 ifstream kcf (kernel_config_file.c_str());
1762 string line;
1763 while (getline (kcf, line))
1764 {
1765 if (!startswith(line, "CONFIG_")) continue;
1766 size_t off = line.find('=');
1767 if (off == string::npos) continue;
1768 string key = line.substr(0, off);
1769 string value = line.substr(off+1, string::npos);
1770 kernel_config[key] = value;
1771 }
1772 if (verbose > 2)
1773 clog << _F("Parsed kernel \"%s\", ", kernel_config_file.c_str())
1774 << _NF("containing %zu tuple", "containing %zu tuples",
1775 kernel_config.size(), kernel_config.size()) << endl;
1776
1777
1778 kcf.close();
1779 return 0;
1780 }
1781
1782
1783 int
1784 systemtap_session::parse_kernel_exports ()
1785 {
1786 string kernel_exports_file = kernel_build_tree + "/Module.symvers";
1787 struct stat st;
1788 int rc = stat(kernel_exports_file.c_str(), &st);
1789 if (rc != 0)
1790 {
1791 clog << _F("Checking \"%s\" failed with error: %s\nEnsure kernel development headers & makefiles are installed",
1792 kernel_exports_file.c_str(), strerror(errno)) << endl;
1793 return rc;
1794 }
1795
1796 ifstream kef (kernel_exports_file.c_str());
1797 string line;
1798 while (getline (kef, line))
1799 {
1800 vector<string> tokens;
1801 tokenize (line, tokens, "\t");
1802 if (tokens.size() == 4 &&
1803 tokens[2] == "vmlinux" &&
1804 tokens[3].substr(0,13) == string("EXPORT_SYMBOL"))
1805 kernel_exports.insert (tokens[1]);
1806 // RHEL4 Module.symvers file only has 3 tokens. No
1807 // 'EXPORT_SYMBOL' token at the end of the line.
1808 else if (tokens.size() == 3 && tokens[2] == "vmlinux")
1809 kernel_exports.insert (tokens[1]);
1810 }
1811 if (verbose > 2)
1812 clog << _NF("Parsed kernel \"%s\", containing one vmlinux export",
1813 "Parsed kernel \"%s\", containing %zu vmlinux exports",
1814 kernel_exports.size(), kernel_exports_file.c_str(),
1815 kernel_exports.size()) << endl;
1816
1817 kef.close();
1818 return 0;
1819 }
1820
1821
1822 int
1823 systemtap_session::parse_kernel_functions ()
1824 {
1825 string system_map_path = kernel_build_tree + "/System.map";
1826 ifstream system_map;
1827
1828 system_map.open(system_map_path.c_str(), ifstream::in);
1829 if (! system_map.is_open())
1830 {
1831 if (verbose > 1)
1832 clog << _F("Kernel symbol table %s unavailable, (%s)",
1833 system_map_path.c_str(), strerror(errno)) << endl;
1834
1835 system_map_path = "/boot/System.map-" + kernel_release;
1836 system_map.clear();
1837 system_map.open(system_map_path.c_str(), ifstream::in);
1838 if (! system_map.is_open())
1839 {
1840 if (verbose > 1)
1841 clog << _F("Kernel symbol table %s unavailable, (%s)",
1842 system_map_path.c_str(), strerror(errno)) << endl;
1843 }
1844 }
1845
1846 while (system_map.good())
1847 {
1848 assert_no_interrupts();
1849
1850 string address, type, name;
1851 system_map >> address >> type >> name;
1852
1853 if (verbose > 3)
1854 clog << "'" << address << "' '" << type << "' '" << name
1855 << "'" << endl;
1856
1857 // 'T'/'t' are text code symbols
1858 if (type != "t" && type != "T")
1859 continue;
1860
1861 #ifdef __powerpc__ // XXX cross-compiling hazard
1862 // Map ".sys_foo" to "sys_foo".
1863 if (name[0] == '.')
1864 name.erase(0, 1);
1865 #endif
1866
1867 // FIXME: better things to do here - look for _stext before
1868 // remembering symbols. Also:
1869 // - stop remembering names at ???
1870 // - what about __kprobes_text_start/__kprobes_text_end?
1871 kernel_functions.insert(name);
1872 }
1873 system_map.close();
1874
1875 if (kernel_functions.size() == 0)
1876 print_warning ("Kernel function symbol table missing [man warning::symbols]", 0);
1877
1878 if (verbose > 2)
1879 clog << _F("Parsed kernel \"%s\", ", system_map_path.c_str())
1880 << _NF("containing %zu symbol", "containing %zu symbols",
1881 kernel_functions.size(), kernel_functions.size()) << endl;
1882
1883 return 0;
1884 }
1885
1886
1887 string
1888 systemtap_session::cmd_file ()
1889 {
1890 wordexp_t words;
1891 string file;
1892
1893 if (target_pid && cmd == "")
1894 {
1895 // check that the target_pid corresponds to a running process
1896 string err_msg;
1897 if(!is_valid_pid (target_pid, err_msg))
1898 throw SEMANTIC_ERROR(err_msg);
1899
1900 file = string("/proc/") + lex_cast(target_pid) + "/exe";
1901 }
1902 else // default is to assume -c flag was given
1903 {
1904 int rc = wordexp (cmd.c_str (), &words, WRDE_NOCMD|WRDE_UNDEF);
1905 if(rc == 0)
1906 {
1907 if (words.we_wordc > 0)
1908 file = words.we_wordv[0];
1909 wordfree (& words);
1910 }
1911 else
1912 {
1913 switch (rc)
1914 {
1915 case WRDE_BADCHAR:
1916 throw SEMANTIC_ERROR(_("command contains illegal characters"));
1917 case WRDE_BADVAL:
1918 throw SEMANTIC_ERROR(_("command contains undefined shell variables"));
1919 case WRDE_CMDSUB:
1920 throw SEMANTIC_ERROR(_("command contains command substitutions"));
1921 case WRDE_NOSPACE:
1922 throw SEMANTIC_ERROR(_("out of memory"));
1923 case WRDE_SYNTAX:
1924 throw SEMANTIC_ERROR(_("command contains shell syntax errors"));
1925 default:
1926 throw SEMANTIC_ERROR(_("unspecified wordexp failure"));
1927 }
1928 }
1929 }
1930 return file;
1931 }
1932
1933
1934 void
1935 systemtap_session::init_try_server ()
1936 {
1937 #if HAVE_NSS
1938 // If the option is disabled or we are a server or we are already using a
1939 // server, then never retry compilation using a server.
1940 if (! use_server_on_error || client_options || ! specified_servers.empty ())
1941 try_server_status = dont_try_server;
1942 else
1943 try_server_status = try_server_unset;
1944 #else
1945 // No client, so don't bother.
1946 try_server_status = dont_try_server;
1947 #endif
1948 }
1949
1950 void
1951 systemtap_session::set_try_server (int t)
1952 {
1953 if (try_server_status != dont_try_server)
1954 try_server_status = t;
1955 }
1956
1957
1958 void systemtap_session::insert_loaded_modules()
1959 {
1960 char line[1024];
1961 ifstream procmods ("/proc/modules");
1962 while (procmods.good()) {
1963 procmods.getline (line, sizeof(line));
1964 strtok(line, " \t");
1965 if (line[0] == '\0')
1966 break; // maybe print a warning?
1967 unwindsym_modules.insert (string (line));
1968 }
1969 procmods.close();
1970 unwindsym_modules.insert ("kernel");
1971 }
1972
1973 void
1974 systemtap_session::setup_kernel_release (const char* kstr)
1975 {
1976 // Sometimes we may get dupes here... e.g. a server may have a full
1977 // -r /path/to/kernel followed by a client's -r kernel.
1978 if (kernel_release == kstr)
1979 return; // nothing new here...
1980
1981 kernel_release = kernel_build_tree = kernel_source_tree = "";
1982 if (kstr[0] == '/') // fully specified path
1983 {
1984 kernel_build_tree = kstr;
1985 kernel_release = kernel_release_from_build_tree (kernel_build_tree, verbose);
1986
1987 // PR10745
1988 // Maybe it's a full kernel source tree, for purposes of PR10745.
1989 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
1990 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
1991 // need heuristics such as this one:
1992
1993 string some_random_source_only_file = kernel_build_tree + "/COPYING";
1994 ifstream epic (some_random_source_only_file.c_str());
1995 if (! epic.fail())
1996 {
1997 kernel_source_tree = kernel_build_tree;
1998 if (verbose > 2)
1999 clog << _F("Located kernel source tree (COPYING) at '%s'", kernel_source_tree.c_str()) << endl;
2000 }
2001 }
2002 else
2003 {
2004 update_release_sysroot = true;
2005 kernel_release = string (kstr);
2006 if (!kernel_release.empty())
2007 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
2008
2009 // PR10745
2010 // Let's not look for the kernel_source_tree; it's definitely
2011 // not THERE. tapsets.cxx might try to find it later if tracepoints
2012 // need it.
2013 }
2014 }
2015
2016
2017 // Register all the aliases we've seen in library files, and the user
2018 // file, as patterns.
2019 void
2020 systemtap_session::register_library_aliases()
2021 {
2022 vector<stapfile*> files(library_files);
2023 files.insert(files.end(), user_files.begin(), user_files.end());
2024
2025 for (unsigned f = 0; f < files.size(); ++f)
2026 {
2027 stapfile * file = files[f];
2028 for (unsigned a = 0; a < file->aliases.size(); ++a)
2029 {
2030 probe_alias * alias = file->aliases[a];
2031 try
2032 {
2033 for (unsigned n = 0; n < alias->alias_names.size(); ++n)
2034 {
2035 probe_point * name = alias->alias_names[n];
2036 match_node * mn = pattern_root;
2037 for (unsigned c = 0; c < name->components.size(); ++c)
2038 {
2039 probe_point::component * comp = name->components[c];
2040 // XXX: alias parameters
2041 if (comp->arg)
2042 throw SEMANTIC_ERROR(_F("alias component %s contains illegal parameter",
2043 comp->functor.to_string().c_str()));
2044 mn = mn->bind(comp->functor);
2045 }
2046 // PR 12916: All probe aliases are OK for all users. The actual
2047 // referenced probe points will be checked when the alias is resolved.
2048 mn->bind_privilege (pr_all);
2049 mn->bind(new alias_expansion_builder(alias));
2050 }
2051 }
2052 catch (const semantic_error& e)
2053 {
2054 semantic_error er(ERR_SRC, _("while registering probe alias"),
2055 alias->tok, NULL, &e);
2056 print_error (er);
2057 }
2058 }
2059 }
2060 }
2061
2062
2063 // Print this given token, but abbreviate it if the last one had the
2064 // same file name.
2065 void
2066 systemtap_session::print_token (ostream& o, const token* tok)
2067 {
2068 assert (tok);
2069
2070 if (last_token && last_token->location.file == tok->location.file)
2071 {
2072 stringstream tmpo;
2073 tmpo << *tok;
2074 string ts = tmpo.str();
2075 // search & replace the file name with nothing
2076 size_t idx = ts.find (tok->location.file->name);
2077 if (idx != string::npos) {
2078 ts.erase(idx, tok->location.file->name.size()); // remove path
2079 if (color_errors) {
2080 string src = ts.substr(idx); // keep line & col
2081 ts.erase(idx); // remove from output string
2082 ts += colorize(src, "source"); // re-add it colorized
2083 }
2084 }
2085
2086 o << ts;
2087 }
2088 else
2089 o << colorize(tok);
2090
2091 last_token = tok;
2092 }
2093
2094
2095 void
2096 systemtap_session::print_error (const semantic_error& se)
2097 {
2098 // skip error message printing for listing mode with low verbosity
2099 if (this->dump_mode && this->verbose <= 1)
2100 {
2101 seen_errors[se.errsrc_chain()]++; // increment num_errors()
2102 return;
2103 }
2104
2105 // duplicate elimination
2106 if (verbose > 0 || seen_errors[se.errsrc_chain()] < 1)
2107 {
2108 seen_errors[se.errsrc_chain()]++;
2109 for (const semantic_error *e = &se; e != NULL; e = e->get_chain())
2110 cerr << build_error_msg(*e);
2111 }
2112 else suppressed_errors++;
2113 }
2114
2115 string
2116 systemtap_session::build_error_msg (const semantic_error& e)
2117 {
2118 stringstream message;
2119 string align_semantic_error (" ");
2120
2121 message << colorize(_("semantic error:"), "error") << ' ' << e.what ();
2122 if (e.tok1 || e.tok2)
2123 message << ": ";
2124 else
2125 {
2126 print_error_details (message, align_semantic_error, e);
2127 message << endl;
2128 if (verbose > 1) // no tokens to print, so print any errsrc right there
2129 message << _(" thrown from: ") << e.errsrc;
2130 }
2131
2132 if (e.tok1)
2133 {
2134 print_token (message, e.tok1);
2135 print_error_details (message, align_semantic_error, e);
2136 message << endl;
2137 if (verbose > 1)
2138 message << _(" thrown from: ") << e.errsrc << endl;
2139 print_error_source (message, align_semantic_error, e.tok1);
2140 }
2141 if (e.tok2)
2142 {
2143 print_token (message, e.tok2);
2144 message << endl;
2145 print_error_source (message, align_semantic_error, e.tok2);
2146 }
2147 message << endl;
2148 return message.str();
2149 }
2150
2151 void
2152 systemtap_session::print_error_source (std::ostream& message,
2153 std::string& align, const token* tok)
2154 {
2155 unsigned i = 0;
2156
2157 assert (tok);
2158 if (!tok->location.file)
2159 //No source to print, silently exit
2160 return;
2161
2162 unsigned line = tok->location.line;
2163 unsigned col = tok->location.column;
2164 interned_string file_contents = tok->location.file->file_contents;
2165
2166 size_t start_pos = 0, end_pos = 0;
2167 //Navigate to the appropriate line
2168 while (i != line && end_pos != std::string::npos)
2169 {
2170 start_pos = end_pos;
2171 end_pos = file_contents.find ('\n', start_pos) + 1;
2172 i++;
2173 }
2174 //TRANSLATORS: Here we are printing the source string of the error
2175 message << align << _("source: ");
2176 interned_string srcline = file_contents.substr(start_pos, end_pos-start_pos-1);
2177 if (color_errors) {
2178 // before token:
2179 message << srcline.substr(0, col-1);
2180 // token:
2181 // after token:
2182 // ... hold it - the token might have been synthetic,
2183 // or expanded from a $@ command line argument, or ...
2184 // so tok->content may have nothing in common with the
2185 // contents of srcline at the same point.
2186 interned_string srcline_rest = srcline.substr(col-1);
2187 interned_string srcline_tokenish = srcline_rest.substr(0, tok->content.size());
2188 if (srcline_tokenish == tok->content) { // oh good
2189 message << colorize(tok->content, "token");
2190 message << srcline_rest.substr(tok->content.size());
2191 message << endl;
2192 }
2193 else { // oh bad
2194 message << " ... ";
2195 col += 5; // line up with the caret
2196 message << colorize(tok->content, "token");
2197 message << " ... " << srcline_rest;
2198 message << endl;
2199 }
2200 } else
2201 message << srcline << endl;
2202 message << align << " ";
2203 //Navigate to the appropriate column
2204 for (i=start_pos; i<start_pos+col-1; i++)
2205 {
2206 if(isspace(file_contents[i]))
2207 message << file_contents[i];
2208 else
2209 message << ' ';
2210 }
2211 message << colorize("^", "caret") << endl;
2212
2213 // print chained macro invocations and synthesized code
2214 if (tok->chain)
2215 {
2216 if (tok->location.file->synthetic)
2217 message << _("\tin synthesized code from: ");
2218 else
2219 message << _("\tin expansion of macro: ");
2220 message << colorize(tok->chain) << endl;
2221 print_error_source (message, align, tok->chain);
2222 }
2223 }
2224
2225 void
2226 systemtap_session::print_error_details (std::ostream& message,
2227 std::string& align,
2228 const semantic_error& e)
2229 {
2230 for (size_t i = 0; i < e.details.size(); ++i)
2231 message << endl << align << e.details[i];
2232 }
2233
2234 void
2235 systemtap_session::print_warning (const string& message_str, const token* tok)
2236 {
2237 // Only output in dump mode if -vv is supplied:
2238 if (suppress_warnings && (!dump_mode || verbose <= 1))
2239 return; // NB: don't count towards suppressed_warnings count
2240
2241 // Duplicate elimination
2242 string align_warning (" ");
2243 if (verbose > 0 || seen_warnings.find (message_str) == seen_warnings.end())
2244 {
2245 seen_warnings.insert (message_str);
2246 clog << colorize(_("WARNING:"), "warning") << ' ' << message_str;
2247 if (tok) { clog << ": "; print_token (clog, tok); }
2248 clog << endl;
2249 if (tok) { print_error_source (clog, align_warning, tok); }
2250 }
2251 else suppressed_warnings++;
2252 }
2253
2254
2255 void
2256 systemtap_session::print_error (const parse_error &pe,
2257 const token* tok,
2258 const std::string &input_name,
2259 bool is_warningerr)
2260 {
2261 // duplicate elimination
2262 if (verbose > 0 || seen_errors[pe.errsrc_chain()] < 1)
2263 {
2264 // Sometimes, we need to print parse errors that should not be considered
2265 // critical. For example, when we parse tapsets and macros. In those
2266 // cases, is_warningerr is true, and we cancel out the increase in
2267 // seen_errors.size() by also increasing warningerr_count, so that the
2268 // net num_errors() value is unchanged.
2269 seen_errors[pe.errsrc_chain()]++; // can be simplified if we
2270 if (seen_errors[pe.errsrc_chain()] == 1 && is_warningerr) // change map to a set (and
2271 warningerr_count++; // settle on threshold of 1)
2272 cerr << build_error_msg(pe, tok, input_name);
2273 for (const parse_error *e = pe.chain; e != NULL; e = e->chain)
2274 cerr << build_error_msg(*e, e->tok, input_name);
2275 }
2276 else suppressed_errors++;
2277 }
2278
2279 string
2280 systemtap_session::build_error_msg (const parse_error& pe,
2281 const token* tok,
2282 const std::string &input_name)
2283 {
2284 stringstream message;
2285 string align_parse_error (" ");
2286
2287 // print either pe.what() or a deferred error from the lexer
2288 bool found_junk = false;
2289 if (tok && tok->type == tok_junk && tok->msg != "")
2290 {
2291 found_junk = true;
2292 message << colorize(_("parse error:"), "error") << ' ' << tok->msg << endl;
2293 }
2294 else
2295 {
2296 message << colorize(_("parse error:"), "error") << ' ' << pe.what() << endl;
2297 }
2298
2299 // NB: It makes sense for lexer errors to always override parser
2300 // errors, since the original obvious scheme was for the lexer to
2301 // throw an exception before the token reached the parser.
2302
2303 if (pe.tok || found_junk)
2304 {
2305 message << align_parse_error << _(" at: ") << colorize(tok) << endl;
2306 print_error_source (message, align_parse_error, tok);
2307 }
2308 else if (tok) // "expected" type error
2309 {
2310 message << align_parse_error << _(" saw: ") << colorize(tok) << endl;
2311 print_error_source (message, align_parse_error, tok);
2312 }
2313 else
2314 {
2315 message << align_parse_error << _(" saw: ") << input_name << " EOF" << endl;
2316 }
2317 message << endl;
2318
2319 return message.str();
2320 }
2321
2322 void
2323 systemtap_session::report_suppression()
2324 {
2325 if (this->suppressed_errors > 0)
2326 cerr << colorize(_F("Number of similar error messages suppressed: %d.",
2327 this->suppressed_errors),
2328 "error") << endl;
2329 if (this->suppressed_warnings > 0)
2330 cerr << colorize(_F("Number of similar warning messages suppressed: %d.",
2331 this->suppressed_warnings),
2332 "warning") << endl;
2333 if (this->suppressed_errors > 0 || this->suppressed_warnings > 0)
2334 cerr << "Rerun with -v to see them." << endl;
2335 }
2336
2337 void
2338 systemtap_session::create_tmp_dir()
2339 {
2340 if (!tmpdir.empty())
2341 return;
2342
2343 // Create the temp directory
2344 const char * tmpdir_env = getenv("TMPDIR");
2345 if (!tmpdir_env)
2346 tmpdir_env = "/tmp";
2347
2348 string stapdir = "/stapXXXXXX";
2349 string tmpdirt = tmpdir_env + stapdir;
2350 const char *tmpdir_name = mkdtemp((char *)tmpdirt.c_str());
2351 if (! tmpdir_name)
2352 {
2353 const char* e = strerror(errno);
2354 //TRANSLATORS: we can't make the directory due to the error
2355 throw runtime_error(_F("cannot create temporary directory (\" %s \"): %s", tmpdirt.c_str(), e));
2356 }
2357 else
2358 tmpdir = tmpdir_name;
2359 }
2360
2361 void
2362 systemtap_session::remove_tmp_dir()
2363 {
2364 if(tmpdir.empty())
2365 return;
2366
2367 // Remove temporary directory
2368 if (keep_tmpdir && !tmpdir_opt_set)
2369 clog << _F("Keeping temporary directory \"%s\"", tmpdir.c_str()) << endl;
2370 else if (!tmpdir_opt_set)
2371 {
2372 // Mask signals while we're deleting the temporary directory.
2373 stap_sigmasker masked;
2374
2375 // Remove the temporary directory.
2376 vector<string> cleanupcmd;
2377 cleanupcmd.push_back("rm");
2378 cleanupcmd.push_back("-rf");
2379 cleanupcmd.push_back(tmpdir);
2380
2381 (void) stap_system(verbose, cleanupcmd);
2382 if (verbose>1)
2383 clog << _F("Removed temporary directory \"%s\"", tmpdir.c_str()) << endl;
2384 tmpdir.clear();
2385
2386 }
2387 }
2388
2389 void
2390 systemtap_session::reset_tmp_dir()
2391 {
2392 remove_tmp_dir();
2393 create_tmp_dir();
2394 }
2395
2396 translator_output* systemtap_session::op_create_auxiliary(bool trailer_p)
2397 {
2398 static int counter = 0;
2399 string tmpname = this->tmpdir + "/" + this->module_name + "_aux_" + lex_cast(counter++) + ".c";
2400 translator_output* n = new translator_output (tmpname);
2401 n->trailer_p = trailer_p;
2402 auxiliary_outputs.push_back (n);
2403 return n;
2404 }
2405
2406 // Wrapper for checking if there are pending interrupts
2407 void
2408 assert_no_interrupts()
2409 {
2410 if (pending_interrupts)
2411 throw interrupt_exception();
2412 }
2413
2414 std::string
2415 systemtap_session::colorize(const std::string& str, const std::string& type)
2416 {
2417 if (str.empty() || !color_errors)
2418 return str;
2419 else {
2420 // Check if this type is defined in SYSTEMTAP_COLORS
2421 std::string color = parse_stap_color(type);
2422 if (!color.empty()) // no need to pollute terminal if not necessary
2423 return "\033[" + color + "m\033[K" + str + "\033[m\033[K";
2424 else
2425 return str;
2426 }
2427 }
2428
2429 // Colorizes the path:row:col part of the token
2430 std::string
2431 systemtap_session::colorize(const token* tok)
2432 {
2433 if (tok == NULL)
2434 return "";
2435
2436 stringstream tmp;
2437 tmp << *tok;
2438
2439 if (!color_errors)
2440 return tmp.str(); // Might as well stop now to save time
2441 else {
2442 string ts = tmp.str();
2443
2444 // Print token location, which is also the tail of ts
2445 stringstream loc;
2446 loc << tok->location;
2447
2448 // Remove token location and re-add it colorized
2449 ts.erase(ts.size()-loc.str().size());
2450 return ts + colorize(loc.str(), "source");
2451 }
2452 }
2453
2454 /* Parse SYSTEMTAP_COLORS and returns the SGR parameter(s) for the given
2455 type. The env var SYSTEMTAP_COLORS must be in the following format:
2456 'key1=val1:key2=val2:' etc... where valid keys are 'error', 'warning',
2457 'source', 'caret', 'token' and valid values constitute SGR parameter(s).
2458 For example, the default setting would be:
2459 'error=01;31:warning=00;33:source=00;34:caret=01:token=01'
2460 */
2461 std::string
2462 systemtap_session::parse_stap_color(const std::string& type)
2463 {
2464 const char *key, *col, *eq;
2465 int n = type.size();
2466 int done = 0;
2467
2468 key = getenv("SYSTEMTAP_COLORS");
2469 if (key == NULL)
2470 key = "error=01;31:warning=00;33:source=00;34:caret=01:token=01";
2471 else if (*key == '\0')
2472 return ""; // disable colors if set but empty
2473
2474 while (!done) {
2475 if (!(col = strchr(key, ':'))) {
2476 col = strchr(key, '\0');
2477 done = 1;
2478 }
2479 if (!((eq = strchr(key, '=')) && eq < col))
2480 return ""; /* invalid syntax: no = in range */
2481 if (!(key < eq && eq < col-1))
2482 return ""; /* invalid syntax: key or val empty */
2483 if (strspn(eq+1, "0123456789;") < (size_t)(col-eq-1))
2484 return ""; /* invalid syntax: invalid char in val */
2485 if (eq-key == n && type.compare(0, n, key, n) == 0)
2486 return string(eq+1, col-eq-1);
2487 if (!done) key = col+1; /* advance to next key */
2488 }
2489
2490 // Could not find the key
2491 return "";
2492 }
2493
2494 /*
2495 * Returns true if this system requires modules to have signatures
2496 * (typically on a secure boot system), false otherwise.
2497 *
2498 * This routine parses /sys/module/module/parameters/sig_enforce to
2499 * figure out if signatures are enforced on modules. Note that if the
2500 * file doesn't exist, we don't really care and return false.
2501 *
2502 * On certain kernels (RHEL7), we also have to check
2503 * /sys/kernel/security/securelevel.
2504 */
2505 bool
2506 systemtap_session::modules_must_be_signed()
2507 {
2508 ifstream statm("/sys/module/module/parameters/sig_enforce");
2509 ifstream securelevel("/sys/kernel/security/securelevel");
2510 char status = 'N';
2511
2512 statm >> status;
2513 if (status == 'Y')
2514 return true;
2515
2516 securelevel >> status;
2517 if (status == '1')
2518 return true;
2519 return false;
2520 }
2521
2522 /*
2523 * Get information on the list of enrolled machine owner keys (MOKs) on
2524 * this system.
2525 */
2526 void
2527 systemtap_session::get_mok_info()
2528 {
2529 vector<string> cmd;
2530 int rc;
2531 stringstream out;
2532
2533 // FIXME: In theory, we should be able to read /sys files and use
2534 // some of the guts of read_cert_info_from_file() to get the
2535 // fingerprints. This would rid us of our mokutil
2536 // dependency. However, we'd need to copy/duplicate efilib.c from
2537 // mokutil source to be able to decipher the efi data.
2538
2539 cmd.push_back("mokutil");
2540 cmd.push_back("--list-enrolled");
2541 rc = stap_system_read(verbose, cmd, out);
2542 if (rc != 0)
2543 // If we're here, we know the client requires module signing, but
2544 // we can't get the list of MOKs. Quit.
2545 throw runtime_error(_F("failed to get list of machine owner keys (MOK) fingerprints: rc %d", rc));
2546
2547 string line, fingerprint;
2548 while (! out.eof())
2549 {
2550 vector<string> matches;
2551
2552 // Get a line of the output, then try to find the fingerprint in
2553 // the line.
2554 getline(out, line);
2555 if (! regexp_match(line, "^SHA1 Fingerprint: ([0-9a-f:]+)$", matches))
2556 {
2557 // matches[0] is the entire line, matches[1] is the first
2558 // submatch, in this case the actual fingerprint
2559 if (verbose > 2)
2560 clog << "MOK fingerprint found: " << matches[1] << endl;
2561 if (! matches[1].empty())
2562 mok_fingerprints.push_back(matches[1]);
2563 }
2564 }
2565 }
2566
2567 void
2568 systemtap_session::enable_auto_server (const string &message)
2569 {
2570 // There may be more than one reason to enable auto server mode, so we may be called
2571 // more than once. Accumulate the messages.
2572 auto_server_msgs.push_back (message);
2573
2574 #if HAVE_NSS
2575 // Enable auto server mode, if not enabled already.
2576 if (specified_servers.empty())
2577 specified_servers.push_back ("");
2578 #else
2579 // Compilation using a server is not supported. exit() after
2580 // the first explanation.
2581 explain_auto_options ();
2582 clog << _("Unable to request compilation by a compile-server\n."
2583 "Without NSS, --use-server is not supported by this version systemtap.") << endl;
2584 exit(1);
2585 #endif
2586 }
2587
2588 void
2589 systemtap_session::explain_auto_options()
2590 {
2591 // Was there an automatic privilege setting?
2592 if (! auto_privilege_level_msg.empty())
2593 clog << auto_privilege_level_msg << endl;
2594
2595 // Was a server was automatically requested? Handle this one after other auto_settings
2596 // which may result in an auto_server setting.
2597 if (! auto_server_msgs.empty())
2598 {
2599 for (vector<string>::iterator i = auto_server_msgs.begin(); i != auto_server_msgs.end(); ++i)
2600 {
2601 clog << *i << endl;
2602 clog << _("--use-server was automatically selected in order to request compilation by "
2603 "a compile-server.") << endl;
2604 }
2605 }
2606 }
2607
2608 bool
2609 systemtap_session::is_user_file (const string &name)
2610 {
2611 // base the check on the name of the user_file
2612 for (vector<stapfile*>::iterator it = user_files.begin(); it != user_files.end(); it++)
2613 if (name == (*it)->name)
2614 return true;
2615 return false; // no match
2616 }
2617
2618 bool
2619 systemtap_session::is_primary_probe (derived_probe *dp)
2620 {
2621 // We check if this probe is from the primary user file by going back to its
2622 // original probe and checking if that probe was found in the primary user
2623 // file.
2624
2625 if (user_files.empty())
2626 return false;
2627
2628 vector<probe*> chain;
2629 dp->collect_derivation_chain (chain);
2630 const source_loc& origin = chain.back()->tok->location;
2631 return origin.file == user_files[0];
2632 }
2633
2634 // --------------------------------------------------------------------------
2635
2636 /*
2637 Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
2638 gurapr catgbcnz | cazfpnyr -jvqgu 160 |
2639 cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
2640 phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
2641 */
2642 const char*
2643 systemtap_session::morehelp =
2644 "\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2645 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2646 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2647 "\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2648 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
2649 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2650 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2651 "\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
2652 "\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2653 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2654 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2655 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
2656 "\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
2657 "\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
2658 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2659 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2660 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
2661 "\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
2662 "\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
2663 "\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2664 "\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2665 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2666 "\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
2667 "\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
2668 "\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
2669 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
2670 "\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2671 "\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
2672 "\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
2673 "\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
2674 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
2675 "\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2676 "\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
2677 "\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
2678 "\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
2679 "\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
2680 "\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
2681 "\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
2682 "\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
2683 "\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
2684 "\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
2685 "\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
2686 "\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
2687 "\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
2688 "\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
2689 "\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
2690 "\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
2691 "\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
2692 "\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
2693 "\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
2694 "\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
2695 "\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
2696 "\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
2697 "\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
2698 "\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2699 "\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
2700 "\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
2701 "\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
2702 "\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
2703 "\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
2704 "\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
2705 "\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
2706 "\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
2707 "\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2708 "\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
2709 "\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
2710 "\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
2711 "\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
2712 "\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
2713 "\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
2714 "\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
2715 "\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
2716 "\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
2717 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
2718 "\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
2719 "\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
2720 "\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
2721 "\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
2722 "\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
2723 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
2724 "\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
2725 "\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
2726 "\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
2727 "\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
2728 "\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
2729 "\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
2730 "\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
2731 "\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
2732 "\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
2733 "\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2734 "\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2735 "\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
2736 "\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
2737 "\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
2738 "\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
2739 "\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
2740 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
2741 "\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
2742 "\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
2743 "\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
2744 "\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
2745 "\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
2746 "\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
2747 "\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
2748 "\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
2749 "\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
2750 "\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
2751 "\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
2752 "\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
2753 "\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
2754 "\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
2755 "\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
2756 "\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
2757 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
2758 "\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
2759 "\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
2760 "\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
2761 "\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
2762 "\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
2763 "\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
2764 "\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
2765 "\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
2766 "\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
2767 "\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
2768 "\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
2769 "\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
2770 "\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
2771 "\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
2772 "\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
2773 "\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
2774 "\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2775 "\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
2776 "\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
2777 "\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
2778 "\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
2779 "\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
2780 "\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
2781 "\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
2782 "\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
2783 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
2784 "\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
2785 "\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
2786 "\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
2787 "\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2788 "\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
2789 "\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
2790 "\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
2791 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
2792 "\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
2793 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
2794 "\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
2795 "\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
2796 "\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
2797 "\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
2798 "\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
2799 "\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
2800 "\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
2801 "\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
2802 "\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
2803 "\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
2804 "\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
2805 "\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
2806 "\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
2807 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
2808 "\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
2809 "\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
2810 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
2811 "\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
2812 "\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
2813 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
2814 "\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
2815 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
2816 "\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
2817 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
2818 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2819 "\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
2820 "\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
2821 "\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
2822 "\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
2823 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
2824 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
2825 "\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
2826 "\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
2827 "\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2828 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
2829 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2830 "\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
2831 "\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
2832 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
2833 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
2834 "\x5b\x30\x6d";
2835
2836 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.184246 seconds and 6 git commands to generate.