]> sourceware.org Git - systemtap.git/blob - session.cxx
PR12115: New support for multiple remote targets
[systemtap.git] / session.cxx
1 // session functions
2 // Copyright (C) 2010 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 "elaborate.h"
13 #include "translate.h"
14 #include "buildrun.h"
15 #include "coveragedb.h"
16 #include "hash.h"
17 #include "task_finder.h"
18 #include "csclient.h"
19 #include "rpm_finder.h"
20 #include "util.h"
21 #include "git_version.h"
22
23 #include <cerrno>
24 #include <cstdlib>
25
26 extern "C" {
27 #include <getopt.h>
28 #include <limits.h>
29 #include <sys/stat.h>
30 #include <sys/utsname.h>
31 #include <elfutils/libdwfl.h>
32 }
33
34 #if HAVE_NSS
35 extern "C" {
36 #include <nspr.h>
37 }
38 #endif
39
40 #include <string>
41
42 using namespace std;
43
44 /* getopt variables */
45 extern int optind;
46
47 #define PATH_TBD string("__TBD__")
48
49 systemtap_session::systemtap_session ():
50 // NB: pointer members must be manually initialized!
51 base_hash(0),
52 pattern_root(new match_node),
53 user_file (0),
54 be_derived_probes(0),
55 dwarf_derived_probes(0),
56 kprobe_derived_probes(0),
57 hwbkpt_derived_probes(0),
58 perf_derived_probes(0),
59 uprobe_derived_probes(0),
60 utrace_derived_probes(0),
61 itrace_derived_probes(0),
62 task_finder_derived_probes(0),
63 timer_derived_probes(0),
64 profile_derived_probes(0),
65 mark_derived_probes(0),
66 tracepoint_derived_probes(0),
67 hrtimer_derived_probes(0),
68 procfs_derived_probes(0),
69 op (0), up (0),
70 sym_kprobes_text_start (0),
71 sym_kprobes_text_end (0),
72 sym_stext (0),
73 module_cache (0),
74 last_token (0)
75 {
76 struct utsname buf;
77 (void) uname (& buf);
78 kernel_release = string (buf.release);
79 release = kernel_release;
80 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
81 architecture = machine = normalize_machine(buf.machine);
82
83 for (unsigned i=0; i<5; i++) perpass_verbose[i]=0;
84 verbose = 0;
85
86 have_script = false;
87 runtime_specified = false;
88 include_arg_start = -1;
89 timing = false;
90 guru_mode = false;
91 bulk_mode = false;
92 unoptimized = false;
93 suppress_warnings = false;
94 panic_warnings = false;
95 listing_mode = false;
96 listing_mode_vars = false;
97
98 #ifdef ENABLE_PROLOGUES
99 prologue_searching = true;
100 #else
101 prologue_searching = false;
102 #endif
103
104 buffer_size = 0;
105 last_pass = 5;
106 module_name = "stap_" + lex_cast(getpid());
107 stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
108 output_file = ""; // -o FILE
109 save_module = false;
110 keep_tmpdir = false;
111 cmd = "";
112 target_pid = 0;
113 use_cache = true;
114 use_script_cache = true;
115 poison_cache = false;
116 tapset_compile_coverage = false;
117 need_uprobes = false;
118 uprobes_path = "";
119 consult_symtab = false;
120 ignore_vmlinux = false;
121 ignore_dwarf = false;
122 load_only = false;
123 skip_badvars = false;
124 unprivileged = false;
125 omit_werror = false;
126 compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
127 unwindsym_ldd = false;
128 client_options = false;
129 NSPR_Initialized = false;
130
131 /* adding in the XDG_DATA_DIRS variable path,
132 * this searches in conjunction with SYSTEMTAP_TAPSET
133 * to locate stap scripts, either can be disabled if
134 * needed using env $PATH=/dev/null where $PATH is the
135 * path you want disabled
136 */
137 const char* s_p1 = getenv ("XDG_DATA_DIRS");
138 if ( s_p1 != NULL )
139 {
140 vector<string> dirs;
141 tokenize(s_p1, dirs, ":");
142 for(vector<string>::iterator i = dirs.begin(); i != dirs.end(); ++i)
143 {
144 include_path.push_back(*i + "/systemtap/tapset");
145 }
146 }
147
148 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
149 if (s_p != NULL)
150 {
151 include_path.push_back (s_p);
152 }
153 else
154 {
155 include_path.push_back (string(PKGDATADIR) + "/tapset");
156 }
157
158 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
159 if (s_r != NULL)
160 runtime_path = s_r;
161 else
162 runtime_path = string(PKGDATADIR) + "/runtime";
163
164 const char* s_d = getenv ("SYSTEMTAP_DIR");
165 if (s_d != NULL)
166 data_path = s_d;
167 else
168 data_path = get_home_directory() + string("/.systemtap");
169 if (create_dir(data_path.c_str()) == 1)
170 {
171 const char* e = strerror (errno);
172 if (! suppress_warnings)
173 cerr << "Warning: failed to create systemtap data directory (\""
174 << data_path << "\"): " << e
175 << ", disabling cache support." << endl;
176 use_cache = use_script_cache = false;
177 }
178
179 if (use_cache)
180 {
181 cache_path = data_path + "/cache";
182 if (create_dir(cache_path.c_str()) == 1)
183 {
184 const char* e = strerror (errno);
185 if (! suppress_warnings)
186 cerr << "Warning: failed to create cache directory (\""
187 << cache_path << "\"): " << e
188 << ", disabling cache support." << endl;
189 use_cache = use_script_cache = false;
190 }
191 }
192
193 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
194 if (s_tc != NULL)
195 tapset_compile_coverage = true;
196
197 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
198 if (s_kr != NULL) {
199 setup_kernel_release(s_kr);
200 }
201 }
202
203 systemtap_session::~systemtap_session ()
204 {
205 #if HAVE_NSS
206 if (NSPR_Initialized)
207 PR_Cleanup ();
208 #endif // HAVE_NSS
209
210 delete_map(subsessions);
211 }
212
213 void
214 systemtap_session::NSPR_init ()
215 {
216 #if HAVE_NSS
217 if (! NSPR_Initialized)
218 {
219 PR_Init (PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
220 NSPR_Initialized = true;
221 }
222 #endif // HAVE_NSS
223 }
224
225 systemtap_session*
226 systemtap_session::clone(const string& arch, const string& release)
227 {
228 if (this->architecture == arch && this->kernel_release == release)
229 return this;
230
231 systemtap_session*& s = subsessions[make_pair(arch, release)];
232 if (!s)
233 {
234 s = new systemtap_session(*this);
235 s->machine = s->architecture = arch;
236 s->setup_kernel_release(release.c_str());
237 }
238 return s;
239 }
240
241 void
242 systemtap_session::version ()
243 {
244 clog
245 << "SystemTap translator/driver "
246 << "(version " << VERSION << "/" << dwfl_version (NULL)
247 << " " << GIT_MESSAGE << ")" << endl
248 << "Copyright (C) 2005-2010 Red Hat, Inc. and others" << endl
249 << "This is free software; see the source for copying conditions." << endl;
250 clog << "enabled features:"
251 #ifdef HAVE_AVAHI
252 << " AVAHI"
253 #endif
254 #ifdef HAVE_LIBRPM
255 << " LIBRPM"
256 #endif
257 #ifdef HAVE_LIBSQLITE3
258 << " LIBSQLITE3"
259 #endif
260 #ifdef HAVE_NSS
261 << " NSS"
262 #endif
263 #ifdef HAVE_BOOST_SHARED_PTR_HPP
264 << " BOOST_SHARED_PTR"
265 #endif
266 #ifdef HAVE_TR1_UNORDERED_MAP
267 << " TR1_UNORDERED_MAP"
268 #endif
269 #ifdef ENABLE_PROLOGUES
270 << " PROLOGUES"
271 #endif
272 << endl;
273 }
274
275 void
276 systemtap_session::usage (int exitcode)
277 {
278 version ();
279 clog
280 << endl
281 << "Usage: stap [options] FILE Run script in file."
282 << endl
283 << " or: stap [options] - Run script on stdin."
284 << endl
285 << " or: stap [options] -e SCRIPT Run given script."
286 << endl
287 << " or: stap [options] -l PROBE List matching probes."
288 << endl
289 << " or: stap [options] -L PROBE List matching probes and local variables."
290 << endl
291 << endl
292 << "Options:" << endl
293 << " -- end of translator options, script options follow" << endl
294 << " -h --help show help" << endl
295 << " -V show version" << endl
296 << " -p NUM stop after pass NUM 1-5, instead of " << last_pass << endl
297 << " (parse, elaborate, translate, compile, run)" << endl
298 << " -v add verbosity to all passes" << endl
299 << " --vp {N}+ add per-pass verbosity [";
300 for (unsigned i=0; i<5; i++)
301 clog << (perpass_verbose[i] <= 9 ? perpass_verbose[i] : 9);
302 clog
303 << "]" << endl
304 << " -k keep temporary directory" << endl
305 << " -u unoptimized translation" << (unoptimized ? " [set]" : "") << endl
306 << " -w suppress warnings" << (suppress_warnings ? " [set]" : "") << endl
307 << " -W turn warnings into errors" << (panic_warnings ? " [set]" : "") << endl
308 << " -g guru mode" << (guru_mode ? " [set]" : "") << endl
309 << " -P prologue-searching for function probes"
310 << (prologue_searching ? " [set]" : "") << endl
311 << " -b bulk (percpu file) mode" << (bulk_mode ? " [set]" : "") << endl
312 << " -s NUM buffer size in megabytes, instead of " << buffer_size << endl
313 << " -I DIR look in DIR for additional .stp script files";
314 if (include_path.size() == 0)
315 clog << endl;
316 else
317 clog << ", in addition to" << endl;
318 for (unsigned i=0; i<include_path.size(); i++)
319 clog << " " << include_path[i] << endl;
320 clog
321 << " -D NM=VAL emit macro definition into generated C code" << endl
322 << " -B NM=VAL pass option to kbuild make" << endl
323 << " -G VAR=VAL set global variable to value" << endl
324 << " -R DIR look in DIR for runtime, instead of" << endl
325 << " " << runtime_path << endl
326 << " -r DIR cross-compile to kernel with given build tree; or else" << endl
327 << " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of" << endl
328 << " " << kernel_build_tree << endl
329 << " -a ARCH cross-compile to given architecture, instead of " << architecture << endl
330 << " -m MODULE set probe module name, instead of " << endl
331 << " " << module_name << endl
332 << " -o FILE send script output to file, instead of stdout. This supports" << endl
333 << " strftime(3) formats for FILE" << endl
334 << " -c CMD start the probes, run CMD, and exit when it finishes" << endl
335 << " -x PID sets target() to PID" << endl
336 << " -F run as on-file flight recorder with -o." << endl
337 << " run as on-memory flight recorder without -o." << endl
338 << " -S size[,n] set maximum of the size and the number of files." << endl
339 << " -d OBJECT add unwind/symbol data for OBJECT file";
340 if (unwindsym_modules.size() == 0)
341 clog << endl;
342 else
343 clog << ", in addition to" << endl;
344 {
345 vector<string> syms (unwindsym_modules.begin(), unwindsym_modules.end());
346 for (unsigned i=0; i<syms.size(); i++)
347 clog << " " << syms[i] << endl;
348 }
349 clog
350 << " --ldd add unwind/symbol data for all referenced OBJECT files." << endl
351 << " --all-modules" << endl
352 << " add unwind/symbol data for all loaded kernel objects." << endl
353 << " -t collect probe timing information" << endl
354 #ifdef HAVE_LIBSQLITE3
355 << " -q generate information on tapset coverage" << endl
356 #endif /* HAVE_LIBSQLITE3 */
357 << " --unprivileged" << endl
358 << " restrict usage to features available to unprivileged users" << endl
359 #if 0 /* PR6864: disable temporarily; should merge with -d somehow */
360 << " --kelf make do with symbol table from vmlinux" << endl
361 << " --kmap[=FILE]" << endl
362 << " make do with symbol table from nm listing" << endl
363 #endif
364 // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use
365 // only, and don't belong in the eyesight of a plain user.
366 << " --compatible=VERSION" << endl
367 << " suppress incompatible language/tapset changes beyond VERSION," << endl
368 << " instead of " << compatible << endl
369 << " --skip-badvars" << endl
370 << " substitute zero for bad context $variables" << endl
371 << " --use-server[=SERVER-SPEC]" << endl
372 << " specify systemtap compile-servers" << endl
373 << " --list-servers[=PROPERTIES]" << endl
374 << " report on the status of the specified compile-servers" << endl
375 #if HAVE_NSS
376 << " --trust-servers[=TRUST-SPEC]" << endl
377 << " add/revoke trust of specified compile-servers" << endl
378 #endif
379 ;
380
381 time_t now;
382 time (& now);
383 struct tm* t = localtime (& now);
384 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
385 clog << morehelp << endl;
386
387 exit (exitcode);
388 }
389
390 int
391 systemtap_session::parse_cmdline (int argc, char * const argv [])
392 {
393 client_options_disallowed = "";
394 while (true)
395 {
396 int long_opt;
397 char * num_endptr;
398
399 // NB: when adding new options, consider very carefully whether they
400 // should be restricted from stap clients (after --client-options)!
401 #define LONG_OPT_KELF 1
402 #define LONG_OPT_KMAP 2
403 #define LONG_OPT_IGNORE_VMLINUX 3
404 #define LONG_OPT_IGNORE_DWARF 4
405 #define LONG_OPT_VERBOSE_PASS 5
406 #define LONG_OPT_SKIP_BADVARS 6
407 #define LONG_OPT_UNPRIVILEGED 7
408 #define LONG_OPT_OMIT_WERROR 8
409 #define LONG_OPT_CLIENT_OPTIONS 9
410 #define LONG_OPT_HELP 10
411 #define LONG_OPT_DISABLE_CACHE 11
412 #define LONG_OPT_POISON_CACHE 12
413 #define LONG_OPT_CLEAN_CACHE 13
414 #define LONG_OPT_COMPATIBLE 14
415 #define LONG_OPT_LDD 15
416 #define LONG_OPT_USE_SERVER 16
417 #define LONG_OPT_LIST_SERVERS 17
418 #define LONG_OPT_TRUST_SERVERS 18
419 #define LONG_OPT_ALL_MODULES 19
420 #define LONG_OPT_REMOTE 20
421 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
422 static struct option long_options[] = {
423 { "kelf", 0, &long_opt, LONG_OPT_KELF },
424 { "kmap", 2, &long_opt, LONG_OPT_KMAP },
425 { "ignore-vmlinux", 0, &long_opt, LONG_OPT_IGNORE_VMLINUX },
426 { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
427 { "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS },
428 { "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
429 { "unprivileged", 0, &long_opt, LONG_OPT_UNPRIVILEGED },
430 #define OWE5 "tter"
431 #define OWE1 "uild-"
432 #define OWE6 "fu-kb"
433 #define OWE2 "i-kno"
434 #define OWE4 "st"
435 #define OWE3 "w-be"
436 { OWE4 OWE6 OWE1 OWE2 OWE3 OWE5, 0, &long_opt, LONG_OPT_OMIT_WERROR },
437 { "client-options", 0, &long_opt, LONG_OPT_CLIENT_OPTIONS },
438 { "help", 0, &long_opt, LONG_OPT_HELP },
439 { "disable-cache", 0, &long_opt, LONG_OPT_DISABLE_CACHE },
440 { "poison-cache", 0, &long_opt, LONG_OPT_POISON_CACHE },
441 { "clean-cache", 0, &long_opt, LONG_OPT_CLEAN_CACHE },
442 { "compatible", 1, &long_opt, LONG_OPT_COMPATIBLE },
443 { "ldd", 0, &long_opt, LONG_OPT_LDD },
444 { "use-server", 2, &long_opt, LONG_OPT_USE_SERVER },
445 { "list-servers", 2, &long_opt, LONG_OPT_LIST_SERVERS },
446 { "trust-servers", 2, &long_opt, LONG_OPT_TRUST_SERVERS },
447 { "all-modules", 0, &long_opt, LONG_OPT_ALL_MODULES },
448 { "remote", 1, &long_opt, LONG_OPT_REMOTE },
449 { NULL, 0, NULL, 0 }
450 };
451 int grc = getopt_long (argc, argv, "hVvtp:I:e:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:WG:",
452 long_options, NULL);
453 // NB: when adding new options, consider very carefully whether they
454 // should be restricted from stap clients (after --client-options)!
455
456 if (grc < 0)
457 break;
458 bool push_server_opt = false;
459 switch (grc)
460 {
461 case 'V':
462 push_server_opt = true;
463 version ();
464 exit (0);
465
466 case 'v':
467 push_server_opt = true;
468 for (unsigned i=0; i<5; i++)
469 perpass_verbose[i] ++;
470 verbose ++;
471 break;
472
473 case 'G':
474 // Make sure the global option is only composed of the
475 // following chars: [_=a-zA-Z0-9]
476 assert_regexp_match("-G parameter", optarg, "^[a-z_][a-z0-9_]+=[a-z0-9_-]+$");
477
478 globalopts.push_back (string(optarg));
479 break;
480
481 case 't':
482 push_server_opt = true;
483 timing = true;
484 break;
485
486 case 'w':
487 push_server_opt = true;
488 suppress_warnings = true;
489 break;
490
491 case 'W':
492 push_server_opt = true;
493 panic_warnings = true;
494 break;
495
496 case 'p':
497 last_pass = (int)strtoul(optarg, &num_endptr, 10);
498 if (*num_endptr != '\0' || last_pass < 1 || last_pass > 5)
499 {
500 cerr << "Invalid pass number (should be 1-5)." << endl;
501 return 1;
502 }
503 if (listing_mode && last_pass != 2)
504 {
505 cerr << "Listing (-l) mode implies pass 2." << endl;
506 return 1;
507 }
508 push_server_opt = true;
509 break;
510
511 case 'I':
512 if (client_options)
513 client_options_disallowed += client_options_disallowed.empty () ? "-I" : ", -I";
514 if (include_arg_start == -1)
515 include_arg_start = include_path.size ();
516 include_path.push_back (string (optarg));
517 break;
518
519 case 'd':
520 push_server_opt = true;
521 {
522 // At runtime user module names are resolved through their
523 // canonical (absolute) path.
524 const char *mpath = canonicalize_file_name (optarg);
525 if (mpath == NULL) // Must be a kernel module name
526 mpath = optarg;
527 unwindsym_modules.insert (string (mpath));
528 // PR10228: trigger vma tracker logic early if -d /USER-MODULE/
529 // given. XXX This is actually too early. Having a user module
530 // is a good indicator that something will need vma tracking.
531 // But it is not 100%, this really should only trigger through
532 // a user mode tapset /* pragma:vma */ or a probe doing a
533 // variable lookup through a dynamic module.
534 if (mpath[0] == '/')
535 enable_vma_tracker (*this);
536 break;
537 }
538
539 case 'e':
540 if (have_script)
541 {
542 cerr << "Only one script can be given on the command line."
543 << endl;
544 return 1;
545 }
546 push_server_opt = true;
547 cmdline_script = string (optarg);
548 have_script = true;
549 break;
550
551 case 'o':
552 // NB: client_options not a problem, since pass 1-4 does not use output_file.
553 push_server_opt = true;
554 output_file = string (optarg);
555 break;
556
557 case 'R':
558 if (client_options) { cerr << "ERROR: -R invalid with --client-options" << endl; return 1; }
559 runtime_specified = true;
560 runtime_path = string (optarg);
561 break;
562
563 case 'm':
564 if (client_options)
565 client_options_disallowed += client_options_disallowed.empty () ? "-m" : ", -m";
566 module_name = string (optarg);
567 save_module = true;
568 {
569 // If the module name ends with '.ko', chop it off since
570 // modutils doesn't like modules named 'foo.ko.ko'.
571 if (endswith(module_name, ".ko"))
572 {
573 module_name.erase(module_name.size() - 3);
574 cerr << "Truncating module name to '" << module_name
575 << "'" << endl;
576 }
577
578 // Make sure an empty module name wasn't specified (-m "")
579 if (module_name.empty())
580 {
581 cerr << "Module name cannot be empty." << endl;
582 return 1;
583 }
584
585 // Make sure the module name is only composed of the
586 // following chars: [a-z0-9_]
587 assert_regexp_match("-m parameter", module_name, "^[a-z0-9_]+$");
588
589 // Make sure module name isn't too long.
590 if (module_name.size() >= (MODULE_NAME_LEN - 1))
591 {
592 module_name.resize(MODULE_NAME_LEN - 1);
593 cerr << "Truncating module name to '" << module_name
594 << "'" << endl;
595 }
596 }
597
598 push_server_opt = true;
599 use_script_cache = false;
600 break;
601
602 case 'r':
603 if (client_options) // NB: no paths!
604 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
605 push_server_opt = true;
606 setup_kernel_release(optarg);
607 break;
608
609 case 'a':
610 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
611 push_server_opt = true;
612 architecture = string(optarg);
613 break;
614
615 case 'k':
616 push_server_opt = true;
617 keep_tmpdir = true;
618 use_script_cache = false; /* User wants to keep a usable build tree. */
619 break;
620
621 case 'g':
622 push_server_opt = true;
623 guru_mode = true;
624 break;
625
626 case 'P':
627 push_server_opt = true;
628 prologue_searching = true;
629 break;
630
631 case 'b':
632 push_server_opt = true;
633 bulk_mode = true;
634 break;
635
636 case 'u':
637 push_server_opt = true;
638 unoptimized = true;
639 break;
640
641 case 's':
642 buffer_size = (int) strtoul (optarg, &num_endptr, 10);
643 if (*num_endptr != '\0' || buffer_size < 1 || buffer_size > 4095)
644 {
645 cerr << "Invalid buffer size (should be 1-4095)." << endl;
646 return 1;
647 }
648 push_server_opt = true;
649 break;
650
651 case 'c':
652 push_server_opt = true;
653 cmd = string (optarg);
654 if (cmd == "")
655 {
656 // This would mess with later code deciding to pass -c
657 // through to staprun
658 cerr << "Empty CMD string invalid." << endl;
659 return 1;
660 }
661 break;
662
663 case 'x':
664 target_pid = (int) strtoul(optarg, &num_endptr, 10);
665 if (*num_endptr != '\0')
666 {
667 cerr << "Invalid target process ID number." << endl;
668 return 1;
669 }
670 push_server_opt = true;
671 break;
672
673 case 'D':
674 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
675 if (client_options)
676 client_options_disallowed += client_options_disallowed.empty () ? "-D" : ", -D";
677 push_server_opt = true;
678 macros.push_back (string (optarg));
679 break;
680
681 case 'S':
682 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
683 push_server_opt = true;
684 size_option = string (optarg);
685 break;
686
687 case 'q':
688 if (client_options) { cerr << "ERROR: -q invalid with --client-options" << endl; return 1; }
689 push_server_opt = true;
690 tapset_compile_coverage = true;
691 break;
692
693 case 'h':
694 usage (0);
695 break;
696
697 case 'L':
698 listing_mode_vars = true;
699 unoptimized = true; // This causes retention of variables for listing_mode
700 // fallthrough
701 case 'l':
702 suppress_warnings = true;
703 listing_mode = true;
704 last_pass = 2;
705 if (have_script)
706 {
707 cerr << "Only one script can be given on the command line."
708 << endl;
709 return 1;
710 }
711 push_server_opt = true;
712 cmdline_script = string("probe ") + string(optarg) + " {}";
713 have_script = true;
714 break;
715
716 case 'F':
717 push_server_opt = true;
718 load_only = true;
719 break;
720
721 case 'B':
722 if (client_options) { cerr << "ERROR: -B invalid with --client-options" << endl; return 1; }
723 push_server_opt = true;
724 kbuildflags.push_back (string (optarg));
725 break;
726
727 case 0:
728 switch (long_opt)
729 {
730 case LONG_OPT_KELF:
731 push_server_opt = true;
732 consult_symtab = true;
733 break;
734 case LONG_OPT_KMAP:
735 // Leave consult_symtab unset for now, to ease error checking.
736 if (!kernel_symtab_path.empty())
737 {
738 cerr << "You can't specify multiple --kmap options." << endl;
739 return 1;
740 }
741 push_server_opt = true;
742 if (optarg)
743 kernel_symtab_path = optarg;
744 else
745 kernel_symtab_path = PATH_TBD;
746 break;
747 case LONG_OPT_IGNORE_VMLINUX:
748 push_server_opt = true;
749 ignore_vmlinux = true;
750 break;
751 case LONG_OPT_IGNORE_DWARF:
752 push_server_opt = true;
753 ignore_dwarf = true;
754 break;
755 case LONG_OPT_VERBOSE_PASS:
756 {
757 bool ok = true;
758 if (strlen(optarg) < 1 || strlen(optarg) > 5)
759 ok = false;
760 if (ok)
761 for (unsigned i=0; i<strlen(optarg); i++)
762 if (isdigit (optarg[i]))
763 perpass_verbose[i] += optarg[i]-'0';
764 else
765 ok = false;
766
767 if (! ok)
768 {
769 cerr << "Invalid --vp argument: it takes 1 to 5 digits." << endl;
770 return 1;
771 }
772 // NB: we don't do this: last_pass = strlen(optarg);
773 push_server_opt = true;
774 break;
775 }
776 case LONG_OPT_SKIP_BADVARS:
777 push_server_opt = true;
778 skip_badvars = true;
779 break;
780 case LONG_OPT_UNPRIVILEGED:
781 push_server_opt = true;
782 unprivileged = true;
783 /* NB: for server security, it is essential that once this flag is
784 set, no future flag be able to unset it. */
785 break;
786 case LONG_OPT_OMIT_WERROR:
787 push_server_opt = true;
788 omit_werror = true;
789 break;
790 case LONG_OPT_CLIENT_OPTIONS:
791 client_options = true;
792 break;
793 case LONG_OPT_USE_SERVER:
794 if (client_options)
795 client_options_disallowed += client_options_disallowed.empty () ? "--use-server" : ", --use-server";
796 if (optarg)
797 specified_servers.push_back (optarg);
798 else
799 specified_servers.push_back ("");
800 break;
801 case LONG_OPT_LIST_SERVERS:
802 if (client_options)
803 client_options_disallowed += client_options_disallowed.empty () ? "--list-servers" : ", --list-servers";
804 if (optarg)
805 server_status_strings.push_back (optarg);
806 else
807 server_status_strings.push_back ("");
808 break;
809 case LONG_OPT_TRUST_SERVERS:
810 if (client_options)
811 client_options_disallowed += client_options_disallowed.empty () ? "--trust-servers" : ", --trust-servers";
812 if (optarg)
813 server_trust_spec = optarg;
814 else
815 server_trust_spec = "ssl";
816 break;
817 case LONG_OPT_HELP:
818 usage (0);
819 break;
820
821 // The caching options should not be available to server clients
822 case LONG_OPT_DISABLE_CACHE:
823 if (client_options) {
824 cerr << "ERROR: --disable-cache is invalid with --client-options" << endl;
825 return 1;
826 }
827 use_cache = use_script_cache = false;
828 break;
829 case LONG_OPT_POISON_CACHE:
830 if (client_options) {
831 cerr << "ERROR: --poison-cache is invalid with --client-options" << endl;
832 return 1;
833 }
834 poison_cache = true;
835 break;
836 case LONG_OPT_CLEAN_CACHE:
837 if (client_options) {
838 cerr << "ERROR: --clean-cache is invalid with --client-options" << endl;
839 return 1;
840 }
841 clean_cache(*this);
842 exit(0);
843
844 case LONG_OPT_COMPATIBLE:
845 push_server_opt = true;
846 compatible = optarg;
847 break;
848
849 case LONG_OPT_LDD:
850 if (client_options) {
851 cerr << "ERROR: --ldd is invalid with --client-options" << endl;
852 return 1;
853 }
854 push_server_opt = true;
855 unwindsym_ldd = true;
856 break;
857
858 case LONG_OPT_ALL_MODULES:
859 if (client_options) {
860 cerr << "ERROR: --all-modules is invalid with --client-options" << endl;
861 return 1;
862 }
863 insert_loaded_modules();
864 break;
865
866 case LONG_OPT_REMOTE:
867 if (client_options) {
868 cerr << "ERROR: --remote is invalid with --client-options" << endl;
869 return 1;
870 }
871 remote_uris.push_back(optarg);
872 break;
873
874 default:
875 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
876 cerr << "Unhandled long argument id " << long_opt << endl;
877 return 1;
878 }
879 break;
880
881 case '?':
882 // Invalid/unrecognized option given or argument required, but
883 // not given. In both cases getopt_long() will have printed the
884 // appropriate error message to stderr already.
885 return 1;
886 break;
887
888 default:
889 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
890 cerr << "Unhandled argument code " << (char)grc << endl;
891 return 1;
892 break;
893 }
894
895 // Pass selected options on to the server, if any.
896 if (push_server_opt)
897 {
898 if (grc == 0)
899 server_args.push_back (string ("--") +
900 long_options[long_opt - 1].name);
901 else
902 server_args.push_back (string ("-") + (char)grc);
903 if (optarg)
904 server_args.push_back (optarg);
905 }
906 }
907
908 return 0;
909 }
910
911 void
912 systemtap_session::check_options (int argc, char * const argv [])
913 {
914 #if ! HAVE_NSS
915 if (client_options)
916 cerr << "WARNING: --client-options is not supported by this version of systemtap" << endl;
917 #endif
918
919 #if ! HAVE_NSS
920 if (! server_trust_spec.empty ())
921 {
922 cerr << "WARNING: --trust-servers is not supported by this version of systemtap" << endl;
923 server_trust_spec.clear ();
924 }
925 #endif
926
927 if (runtime_specified && ! specified_servers.empty ())
928 {
929 cerr << "Warning: Ignoring --use-server due to the use of -R" << endl;
930 specified_servers.clear ();
931 }
932
933 if (client_options && last_pass > 4)
934 {
935 last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
936 }
937 if (client_options && unprivileged && ! client_options_disallowed.empty ())
938 {
939 cerr << "You can't specify " << client_options_disallowed << " when --unprivileged is specified." << endl;
940 usage (1);
941 }
942 if ((cmd != "") && (target_pid))
943 {
944 cerr << "You can't specify -c and -x options together." << endl;
945 usage (1);
946 }
947 if (unprivileged && guru_mode)
948 {
949 cerr << "You can't specify -g and --unprivileged together." << endl;
950 usage (1);
951 }
952 if (!kernel_symtab_path.empty())
953 {
954 if (consult_symtab)
955 {
956 cerr << "You can't specify --kelf and --kmap together." << endl;
957 usage (1);
958 }
959 consult_symtab = true;
960 if (kernel_symtab_path == PATH_TBD)
961 kernel_symtab_path = string("/boot/System.map-") + kernel_release;
962 }
963 // Warn in case the target kernel release doesn't match the running one.
964 if (last_pass > 4 &&
965 (release != kernel_release ||
966 machine != architecture)) // NB: squashed ARCH by PR4186 logic
967 {
968 if(! suppress_warnings)
969 cerr << "WARNING: kernel release/architecture mismatch with host forces last-pass 4." << endl;
970 last_pass = 4;
971 }
972
973 for (int i = optind; i < argc; i++)
974 {
975 if (! have_script)
976 {
977 script_file = string (argv[i]);
978 have_script = true;
979 }
980 else
981 args.push_back (string (argv[i]));
982 }
983
984 // need a user file
985 // NB: this is also triggered if stap is invoked with no arguments at all
986 if (! have_script)
987 {
988 // We don't need a script if --list-servers or --trust-servers was specified
989 if (server_status_strings.empty () && server_trust_spec.empty ())
990 {
991 cerr << "A script must be specified." << endl;
992 usage(1);
993 }
994 }
995
996 // translate path of runtime to absolute path
997 if (runtime_path[0] != '/')
998 {
999 char cwd[PATH_MAX];
1000 if (getcwd(cwd, sizeof(cwd)))
1001 {
1002 runtime_path = string(cwd) + "/" + runtime_path;
1003 }
1004 }
1005 }
1006
1007 void systemtap_session::insert_loaded_modules()
1008 {
1009 char line[1024];
1010 ifstream procmods ("/proc/modules");
1011 while (procmods.good()) {
1012 procmods.getline (line, sizeof(line));
1013 strtok(line, " \t");
1014 if (line[0] == '\0')
1015 break; // maybe print a warning?
1016 unwindsym_modules.insert (string (line));
1017 }
1018 procmods.close();
1019 unwindsym_modules.insert ("kernel");
1020 }
1021
1022 void
1023 systemtap_session::setup_kernel_release (const char* kstr)
1024 {
1025 if (kstr[0] == '/') // fully specified path
1026 {
1027 kernel_build_tree = kstr;
1028 string version_file_name = kernel_build_tree + "/include/config/kernel.release";
1029 // The file include/config/kernel.release within the
1030 // build tree is used to pull out the version information
1031 ifstream version_file (version_file_name.c_str());
1032 if (version_file.fail ())
1033 {
1034 cerr << "Missing " << version_file_name << endl;
1035 exit(1);
1036 }
1037 else
1038 {
1039 char c;
1040 kernel_release = "";
1041 while (version_file.get(c) && c != '\n')
1042 kernel_release.push_back(c);
1043 }
1044
1045 // PR10745
1046 // Maybe it's a full kernel source tree, for purposes of PR10745.
1047 // In case CONFIG_DEBUG_INFO was set, we'd find it anyway with the
1048 // normal search in tapsets.cxx. Without CONFIG_DEBUG_INFO, we'd
1049 // need heuristics such as this one:
1050
1051 string some_random_source_only_file = kernel_build_tree + "/COPYING";
1052 ifstream epic (some_random_source_only_file.c_str());
1053 if (! epic.fail())
1054 {
1055 kernel_source_tree = kernel_build_tree;
1056 if (verbose > 2)
1057 clog << "Located kernel source tree (COPYING) at '"
1058 << kernel_source_tree << "'" << endl;
1059 }
1060 }
1061 else
1062 {
1063 kernel_release = string (kstr);
1064 kernel_build_tree = "/lib/modules/" + kernel_release + "/build";
1065
1066 // PR10745
1067 // Let's not look for the kernel_source_tree; it's definitely
1068 // not THERE. tapsets.cxx might try to find it later if tracepoints
1069 // need it.
1070 }
1071 }
1072
1073
1074 // Register all the aliases we've seen in library files, and the user
1075 // file, as patterns.
1076 void
1077 systemtap_session::register_library_aliases()
1078 {
1079 vector<stapfile*> files(library_files);
1080 files.push_back(user_file);
1081
1082 for (unsigned f = 0; f < files.size(); ++f)
1083 {
1084 stapfile * file = files[f];
1085 for (unsigned a = 0; a < file->aliases.size(); ++a)
1086 {
1087 probe_alias * alias = file->aliases[a];
1088 try
1089 {
1090 for (unsigned n = 0; n < alias->alias_names.size(); ++n)
1091 {
1092 probe_point * name = alias->alias_names[n];
1093 match_node * n = pattern_root;
1094 for (unsigned c = 0; c < name->components.size(); ++c)
1095 {
1096 probe_point::component * comp = name->components[c];
1097 // XXX: alias parameters
1098 if (comp->arg)
1099 throw semantic_error("alias component "
1100 + comp->functor
1101 + " contains illegal parameter");
1102 n = n->bind(comp->functor);
1103 }
1104 n->bind(new alias_expansion_builder(alias));
1105 }
1106 }
1107 catch (const semantic_error& e)
1108 {
1109 semantic_error* er = new semantic_error (e); // copy it
1110 stringstream msg;
1111 msg << e.msg2;
1112 msg << " while registering probe alias ";
1113 alias->printsig(msg);
1114 er->msg2 = msg.str();
1115 print_error (* er);
1116 delete er;
1117 }
1118 }
1119 }
1120 }
1121
1122
1123 // Print this given token, but abbreviate it if the last one had the
1124 // same file name.
1125 void
1126 systemtap_session::print_token (ostream& o, const token* tok)
1127 {
1128 assert (tok);
1129
1130 if (last_token && last_token->location.file == tok->location.file)
1131 {
1132 stringstream tmpo;
1133 tmpo << *tok;
1134 string ts = tmpo.str();
1135 // search & replace the file name with nothing
1136 size_t idx = ts.find (tok->location.file->name);
1137 if (idx != string::npos)
1138 ts.replace (idx, tok->location.file->name.size(), "");
1139
1140 o << ts;
1141 }
1142 else
1143 o << *tok;
1144
1145 last_token = tok;
1146 }
1147
1148
1149
1150 void
1151 systemtap_session::print_error (const semantic_error& e)
1152 {
1153 string message_str[2];
1154 string align_semantic_error (" ");
1155
1156 // We generate two messages. The second one ([1]) is printed
1157 // without token compression, for purposes of duplicate elimination.
1158 // This way, the same message that may be generated once with a
1159 // compressed and once with an uncompressed token still only gets
1160 // printed once.
1161 for (int i=0; i<2; i++)
1162 {
1163 stringstream message;
1164
1165 message << "semantic error: " << e.what ();
1166 if (e.tok1 || e.tok2)
1167 message << ": ";
1168 if (e.tok1)
1169 {
1170 if (i == 0) print_token (message, e.tok1);
1171 else message << *e.tok1;
1172 }
1173 message << e.msg2;
1174 if (e.tok2)
1175 {
1176 if (i == 0) print_token (message, e.tok2);
1177 else message << *e.tok2;
1178 }
1179 message << endl;
1180 message_str[i] = message.str();
1181 }
1182
1183 // Duplicate elimination
1184 if (seen_errors.find (message_str[1]) == seen_errors.end())
1185 {
1186 seen_errors.insert (message_str[1]);
1187 cerr << message_str[0];
1188
1189 if (e.tok1)
1190 print_error_source (cerr, align_semantic_error, e.tok1);
1191
1192 if (e.tok2)
1193 print_error_source (cerr, align_semantic_error, e.tok2);
1194 }
1195
1196 if (e.chain)
1197 print_error (* e.chain);
1198 }
1199
1200 void
1201 systemtap_session::print_error_source (std::ostream& message,
1202 std::string& align, const token* tok)
1203 {
1204 unsigned i = 0;
1205
1206 assert (tok);
1207 if (!tok->location.file)
1208 //No source to print, silently exit
1209 return;
1210
1211 unsigned line = tok->location.line;
1212 unsigned col = tok->location.column;
1213 const string &file_contents = tok->location.file->file_contents;
1214
1215 size_t start_pos = 0, end_pos = 0;
1216 //Navigate to the appropriate line
1217 while (i != line && end_pos != std::string::npos)
1218 {
1219 start_pos = end_pos;
1220 end_pos = file_contents.find ('\n', start_pos) + 1;
1221 i++;
1222 }
1223 message << align << "source: " << file_contents.substr (start_pos, end_pos-start_pos-1) << endl;
1224 message << align << " ";
1225 //Navigate to the appropriate column
1226 for (i=start_pos; i<start_pos+col-1; i++)
1227 {
1228 if(isspace(file_contents[i]))
1229 message << file_contents[i];
1230 else
1231 message << ' ';
1232 }
1233 message << "^" << endl;
1234 }
1235
1236 void
1237 systemtap_session::print_warning (const string& message_str, const token* tok)
1238 {
1239 // Duplicate elimination
1240 string align_warning (" ");
1241 if (seen_warnings.find (message_str) == seen_warnings.end())
1242 {
1243 seen_warnings.insert (message_str);
1244 clog << "WARNING: " << message_str;
1245 if (tok) { clog << ": "; print_token (clog, tok); }
1246 clog << endl;
1247 if (tok) { print_error_source (clog, align_warning, tok); }
1248 }
1249 }
1250
1251 // --------------------------------------------------------------------------
1252
1253 /*
1254 Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
1255 gurapr catgbcnz | cazfpnyr -jvqgu 160 |
1256 cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
1257 phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
1258 */
1259 const char*
1260 systemtap_session::morehelp =
1261 "\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1262 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1263 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1264 "\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1265 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
1266 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1267 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1268 "\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
1269 "\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1270 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1271 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1272 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
1273 "\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
1274 "\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
1275 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1276 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1277 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
1278 "\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
1279 "\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
1280 "\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1281 "\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1282 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1283 "\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
1284 "\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
1285 "\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
1286 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
1287 "\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1288 "\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
1289 "\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
1290 "\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
1291 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
1292 "\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1293 "\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
1294 "\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
1295 "\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
1296 "\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
1297 "\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
1298 "\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
1299 "\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
1300 "\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
1301 "\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1302 "\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
1303 "\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
1304 "\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
1305 "\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
1306 "\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
1307 "\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
1308 "\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
1309 "\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
1310 "\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
1311 "\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
1312 "\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
1313 "\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
1314 "\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
1315 "\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1316 "\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
1317 "\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
1318 "\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
1319 "\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
1320 "\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
1321 "\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
1322 "\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
1323 "\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
1324 "\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1325 "\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
1326 "\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
1327 "\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
1328 "\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1329 "\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
1330 "\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
1331 "\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
1332 "\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
1333 "\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1334 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
1335 "\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
1336 "\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
1337 "\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
1338 "\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
1339 "\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
1340 "\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
1341 "\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
1342 "\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
1343 "\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
1344 "\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
1345 "\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
1346 "\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
1347 "\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
1348 "\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
1349 "\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
1350 "\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1351 "\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1352 "\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
1353 "\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
1354 "\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1355 "\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
1356 "\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
1357 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
1358 "\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
1359 "\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
1360 "\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
1361 "\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
1362 "\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
1363 "\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
1364 "\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
1365 "\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
1366 "\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
1367 "\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
1368 "\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1369 "\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
1370 "\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
1371 "\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
1372 "\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
1373 "\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
1374 "\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
1375 "\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
1376 "\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
1377 "\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
1378 "\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
1379 "\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
1380 "\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
1381 "\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
1382 "\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
1383 "\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
1384 "\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
1385 "\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
1386 "\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
1387 "\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
1388 "\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
1389 "\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
1390 "\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
1391 "\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1392 "\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
1393 "\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
1394 "\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
1395 "\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
1396 "\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
1397 "\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
1398 "\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
1399 "\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
1400 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
1401 "\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
1402 "\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
1403 "\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
1404 "\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1405 "\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
1406 "\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
1407 "\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
1408 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
1409 "\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
1410 "\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
1411 "\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
1412 "\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
1413 "\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
1414 "\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
1415 "\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
1416 "\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
1417 "\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
1418 "\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1419 "\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
1420 "\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
1421 "\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
1422 "\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
1423 "\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
1424 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
1425 "\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
1426 "\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
1427 "\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
1428 "\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1429 "\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
1430 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
1431 "\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
1432 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
1433 "\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
1434 "\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
1435 "\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1436 "\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
1437 "\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
1438 "\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
1439 "\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
1440 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
1441 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
1442 "\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
1443 "\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
1444 "\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1445 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
1446 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1447 "\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
1448 "\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
1449 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1450 "\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
1451 "\x5b\x30\x6d";
1452
1453 /* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
This page took 0.122314 seconds and 6 git commands to generate.