]> sourceware.org Git - systemtap.git/blame - main.cxx
PR11508: stap --ldd option for automagic shared library scanning
[systemtap.git] / main.cxx
CommitLineData
f4b28491 1// systemtap translator/driver
cf4a6df8 2// Copyright (C) 2005-2010 Red Hat Inc.
f12b2552 3// Copyright (C) 2005 IBM Corp.
77a5c1f9 4// Copyright (C) 2006 Intel Corporation.
69c68955
FCE
5//
6// This file is part of systemtap, and is free software. You can
7// redistribute it and/or modify it under the terms of the GNU General
8// Public License (GPL); either version 2, or (at your option) any
9// later version.
2b066ec1
FCE
10
11#include "config.h"
12#include "staptree.h"
13#include "parse.h"
14#include "elaborate.h"
15#include "translate.h"
f4b28491 16#include "buildrun.h"
dc38c0ae 17#include "session.h"
1b78aef5
DS
18#include "hash.h"
19#include "cache.h"
20#include "util.h"
c3a3c0c9 21#include "coveragedb.h"
c0f9d4b0 22#include "git_version.h"
2ed04863 23#include "rpm_finder.h"
671ceda8
FCE
24#include "task_finder.h"
25
ce91eebd 26#include "sys/sdt.h"
2b066ec1
FCE
27
28#include <iostream>
29#include <fstream>
30#include <sstream>
f4b28491 31#include <cerrno>
24cb178f 32#include <cstdlib>
e00f99a7 33#include <limits.h>
2b066ec1
FCE
34
35extern "C" {
36#include <glob.h>
37#include <unistd.h>
49abf162 38#include <signal.h>
f4b28491 39#include <sys/utsname.h>
5ee1c56b 40#include <sys/times.h>
1d738eed 41#include <sys/time.h>
f59e98c4 42#include <sys/stat.h>
f4b28491 43#include <time.h>
f8949662 44#include <elfutils/libdwfl.h>
5f0a03a6 45#include <getopt.h>
28b768e1 46#include <unistd.h>
2b066ec1
FCE
47}
48
49using namespace std;
50
8f222481 51#define PATH_TBD string("__TBD__")
6e683641 52extern const char* morehelp;
2b066ec1 53
f4b28491 54void
c0de7a8d 55version ()
2b066ec1 56{
d54d4661 57 clog
d04cf5ff 58 << "SystemTap translator/driver "
c4a94c1a 59 << "(version " << VERSION << "/" << dwfl_version (NULL)
2881ab63 60 << " " << GIT_MESSAGE << ")" << endl
c0d1b5a0 61 << "Copyright (C) 2005-2010 Red Hat, Inc. and others" << endl
f8949662 62 << "This is free software; see the source for copying conditions." << endl;
c0de7a8d
FCE
63}
64
8abeee5d 65
8abeee5d
FCE
66
67
c0de7a8d 68void
277c1957 69usage (systemtap_session& s, int exitcode)
c0de7a8d
FCE
70{
71 version ();
72 clog
f4b28491 73 << endl
b2d5d95c 74 << "Usage: stap [options] FILE Run script in file."
f4b28491 75 << endl
b2d5d95c 76 << " or: stap [options] - Run script on stdin."
f4b28491 77 << endl
d54d4661 78 << " or: stap [options] -e SCRIPT Run given script."
f4b28491 79 << endl
16442b90
FCE
80 << " or: stap [options] -l PROBE List matching probes."
81 << endl
d4e35ac8
WH
82 << " or: stap [options] -L PROBE List matching probes and local variables."
83 << endl
f4b28491 84 << endl
c0de7a8d 85 << "Options:" << endl
16442b90 86 << " -- end of translator options, script options follow" << endl
83b38ce6 87 << " -h --help show help" << endl
c0de7a8d 88 << " -V show version" << endl
e0b4e89d
FCE
89 << " -p NUM stop after pass NUM 1-5, instead of " << s.last_pass << endl
90 << " (parse, elaborate, translate, compile, run)" << endl
91 << " -v add verbosity to all passes" << endl
92 << " --vp {N}+ add per-pass verbosity [";
93 for (unsigned i=0; i<5; i++)
94 clog << (s.perpass_verbose[i] <= 9 ? s.perpass_verbose[i] : 9);
95 clog
96 << "]" << endl
d5d7c2cc 97 << " -k keep temporary directory" << endl
cbfbbf69 98 << " -u unoptimized translation" << (s.unoptimized ? " [set]" : "") << endl
a9e8f7e0 99 << " -w suppress warnings" << (s.suppress_warnings ? " [set]" : "") << endl
57a56e00 100 << " -W turn warnings into errors" << (s.panic_warnings ? " [set]" : "") << endl
377b8831 101 << " -g guru mode" << (s.guru_mode ? " [set]" : "") << endl
dff50e09 102 << " -P prologue-searching for function probes"
44f75386 103 << (s.prologue_searching ? " [set]" : "") << endl
6dfd08d7 104 << " -b bulk (percpu file) mode" << (s.bulk_mode ? " [set]" : "") << endl
e0b4e89d 105 << " -s NUM buffer size in megabytes, instead of " << s.buffer_size << endl
f4b28491
FCE
106 << " -I DIR look in DIR for additional .stp script files";
107 if (s.include_path.size() == 0)
0d49d7bc 108 clog << endl;
f4b28491 109 else
24cb178f 110 clog << ", in addition to" << endl;
f4b28491 111 for (unsigned i=0; i<s.include_path.size(); i++)
0d49d7bc
FCE
112 clog << " " << s.include_path[i] << endl;
113 clog
ed10c639 114 << " -D NM=VAL emit macro definition into generated C code" << endl
1392896d 115 << " -B NM=VAL pass option to kbuild make" << endl
24cb178f 116 << " -R DIR look in DIR for runtime, instead of" << endl
b5e66ada
FCE
117 << " " << s.runtime_path << endl
118 << " -r DIR cross-compile to kernel with given build tree; or else" << endl
119 << " -r RELEASE cross-compile to kernel /lib/modules/RELEASE/build, instead of" << endl
120 << " " << s.kernel_build_tree << endl
1392896d 121 << " -a ARCH cross-compile to given architecture, instead of " << s.architecture << endl
b5e66ada
FCE
122 << " -m MODULE set probe module name, instead of " << endl
123 << " " << s.module_name << endl
04ae1b09 124 << " -o FILE send script output to file, instead of stdout. This supports" << endl
54f1da8f 125 << " strftime(3) formats for FILE" << endl
b5e66ada 126 << " -c CMD start the probes, run CMD, and exit when it finishes" << endl
4c5ff1bb 127 << " -x PID sets target() to PID" << endl
701c41be
MH
128 << " -F run as on-file flight recorder with -o." << endl
129 << " run as on-memory flight recorder without -o." << endl
130 << " -S size[,n] set maximum of the size and the number of files." << endl
a8368458
FCE
131 << " -d OBJECT add unwind/symbol data for OBJECT file";
132 if (s.unwindsym_modules.size() == 0)
133 clog << endl;
134 else
135 clog << ", in addition to" << endl;
1a0dbc5a
FCE
136 {
137 vector<string> syms (s.unwindsym_modules.begin(), s.unwindsym_modules.end());
138 for (unsigned i=0; i<syms.size(); i++)
139 clog << " " << syms[i] << endl;
140 }
a8368458 141 clog
ef06c938 142 << " --ldd add unwind/symbol data for all referenced OBJECT files." << endl
cbd6fc7b 143 << " -t collect probe timing information" << endl
1c0b94ef 144#ifdef HAVE_LIBSQLITE3
5f0a03a6 145 << " -q generate information on tapset coverage" << endl
1c0b94ef 146#endif /* HAVE_LIBSQLITE3 */
2f54c4fe
DB
147 << " --unprivileged" << endl
148 << " restrict usage to features available to unprivileged users" << endl
05ec91b4 149#if 0 /* PR6864: disable temporarily; should merge with -d somehow */
5f0a03a6
JK
150 << " --kelf make do with symbol table from vmlinux" << endl
151 << " --kmap[=FILE]" << endl
152 << " make do with symbol table from nm listing" << endl
05ec91b4
FCE
153#endif
154 // Formerly present --ignore-{vmlinux,dwarf} options are for testsuite use
155 // only, and don't belong in the eyesight of a plain user.
db135493
FCE
156 << " --compatible=VERSION" << endl
157 << " suppress incompatible language/tapset changes beyond VERSION," << endl
158 << " instead of " << s.compatible << endl
3bd0d4df 159 << " --skip-badvars" << endl
83b38ce6 160 << " substitute zero for bad context $variables" << endl
c3a3c0c9 161 << endl
d5d7c2cc 162 ;
2b066ec1 163
8abeee5d
FCE
164 time_t now;
165 time (& now);
166 struct tm* t = localtime (& now);
167 if (t && t->tm_mon*3 + t->tm_mday*173 == 0xb6)
168 clog << morehelp << endl;
169
277c1957 170 exit (exitcode);
2b066ec1
FCE
171}
172
173
d0bfd2ac
NT
174static void uniq_list(list<string>& l)
175{
176 list<string> r;
177 set<string> s;
178
179 for (list<string>::iterator i = l.begin(); i != l.end(); ++i) {
180 s.insert(*i);
181 }
182
183 for (list<string>::iterator i = l.begin(); i != l.end(); ++i) {
184 if (s.find(*i) != s.end()) {
185 s.erase(*i);
186 r.push_back(*i);
187 }
188 }
189
190 l.clear();
191 l.assign(r.begin(), r.end());
192}
193
1b78aef5
DS
194static void
195printscript(systemtap_session& s, ostream& o)
196{
16442b90 197 if (s.listing_mode)
83d7fcdc 198 {
16442b90 199 // We go through some heroic measures to produce clean output.
c39cdd55
WH
200 // Record the alias and probe pointer as <name, set<derived_probe *> >
201 map<string,set<derived_probe *> > probe_list;
83d7fcdc 202
c39cdd55 203 // Pre-process the probe alias
16442b90 204 for (unsigned i=0; i<s.probes.size(); i++)
9ba8c134 205 {
f76427a2
FCE
206 if (pending_interrupts) return;
207
16442b90
FCE
208 derived_probe* p = s.probes[i];
209 // NB: p->basest() is not so interesting;
210 // p->almost_basest() doesn't quite work, so ...
211 vector<probe*> chain;
212 p->collect_derivation_chain (chain);
213 probe* second = (chain.size()>1) ? chain[chain.size()-2] : chain[0];
214
c72aa911
JS
215 #if 0 // dump everything about the derivation chain
216 p->printsig(cerr); cerr << endl;
217 cerr << "chain[" << chain.size() << "]:" << endl;
218 for (unsigned j=0; j<chain.size(); j++)
219 {
220 cerr << " [" << j << "]: " << endl;
221 cerr << "\tlocations[" << chain[j]->locations.size() << "]:" << endl;
222 for (unsigned k=0; k<chain[j]->locations.size(); k++)
223 {
224 cerr << "\t [" << k << "]: ";
225 chain[j]->locations[k]->print(cerr);
226 cerr << endl;
227 }
228 const probe_alias *a = chain[j]->get_alias();
229 if (a)
230 {
231 cerr << "\taliases[" << a->alias_names.size() << "]:" << endl;
232 for (unsigned k=0; k<a->alias_names.size(); k++)
233 {
234 cerr << "\t [" << k << "]: ";
235 a->alias_names[k]->print(cerr);
236 cerr << endl;
237 }
238 }
239 }
16442b90
FCE
240 #endif
241
242 stringstream tmps;
7fb2f650
FCE
243 const probe_alias *a = second->get_alias();
244 if (a)
245 {
246 assert (a->alias_names.size() >= 1);
247 a->alias_names[0]->print(tmps); // XXX: [0] is arbitrary; perhaps print all
dff50e09 248 }
7fb2f650
FCE
249 else
250 {
251 assert (second->locations.size() >= 1);
252 second->locations[0]->print(tmps); // XXX: [0] is less arbitrary here, but still ...
253 }
254 string pp = tmps.str();
16442b90
FCE
255
256 // Now duplicate-eliminate. An alias may have expanded to
257 // several actual derived probe points, but we only want to
258 // print the alias head name once.
c39cdd55
WH
259 probe_list[pp].insert(p);
260 }
261
262 // print probe name and variables if there
263 for (map<string, set<derived_probe *> >::iterator it=probe_list.begin(); it!=probe_list.end(); ++it)
264 {
265 o << it->first; // probe name or alias
266
267 // Print the locals and arguments for -L mode only
268 if (s.listing_mode_vars)
16442b90 269 {
d0bfd2ac
NT
270 map<string,unsigned> var_count; // format <"name:type",count>
271 map<string,unsigned> arg_count;
272 list<string> var_list;
273 list<string> arg_list;
c39cdd55
WH
274 // traverse set<derived_probe *> to collect all locals and arguments
275 for (set<derived_probe *>::iterator ix=it->second.begin(); ix!=it->second.end(); ++ix)
8c39844b 276 {
c39cdd55
WH
277 derived_probe* p = *ix;
278 // collect available locals of the probe
8c39844b
JS
279 for (unsigned j=0; j<p->locals.size(); j++)
280 {
c39cdd55 281 stringstream tmps;
8c39844b 282 vardecl* v = p->locals[j];
c39cdd55 283 v->printsig (tmps);
d0bfd2ac
NT
284 var_count[tmps.str()]++;
285 var_list.push_back(tmps.str());
8c39844b 286 }
c39cdd55 287 // collect arguments of the probe if there
d0bfd2ac 288 list<string> arg_set;
c39cdd55 289 p->getargs(arg_set);
d0bfd2ac
NT
290 for (list<string>::iterator ia=arg_set.begin(); ia!=arg_set.end(); ++ia) {
291 arg_count[*ia]++;
292 arg_list.push_back(*ia);
293 }
8c39844b 294 }
d0bfd2ac
NT
295
296 uniq_list(arg_list);
297 uniq_list(var_list);
298
c39cdd55 299 // print the set-intersection only
d0bfd2ac
NT
300 for (list<string>::iterator ir=var_list.begin(); ir!=var_list.end(); ++ir)
301 if (var_count.find(*ir)->second == it->second.size()) // print locals
302 o << " " << *ir;
303 for (list<string>::iterator ir=arg_list.begin(); ir!=arg_list.end(); ++ir)
304 if (arg_count.find(*ir)->second == it->second.size()) // print arguments
305 o << " " << *ir;
16442b90 306 }
c39cdd55 307 o << endl;
9ba8c134 308 }
1b78aef5 309 }
16442b90 310 else
1b78aef5 311 {
16442b90
FCE
312 if (s.embeds.size() > 0)
313 o << "# global embedded code" << endl;
314 for (unsigned i=0; i<s.embeds.size(); i++)
1b78aef5 315 {
f76427a2 316 if (pending_interrupts) return;
16442b90
FCE
317 embeddedcode* ec = s.embeds[i];
318 ec->print (o);
319 o << endl;
320 }
dff50e09 321
16442b90
FCE
322 if (s.globals.size() > 0)
323 o << "# globals" << endl;
324 for (unsigned i=0; i<s.globals.size(); i++)
1b78aef5 325 {
f76427a2 326 if (pending_interrupts) return;
16442b90
FCE
327 vardecl* v = s.globals[i];
328 v->printsig (o);
329 if (s.verbose && v->init)
330 {
331 o << " = ";
332 v->init->print(o);
333 }
334 o << endl;
335 }
dff50e09 336
16442b90
FCE
337 if (s.functions.size() > 0)
338 o << "# functions" << endl;
f76427a2 339 for (map<string,functiondecl*>::iterator it = s.functions.begin(); it != s.functions.end(); it++)
1b78aef5 340 {
f76427a2
FCE
341 if (pending_interrupts) return;
342 functiondecl* f = it->second;
16442b90
FCE
343 f->printsig (o);
344 o << endl;
345 if (f->locals.size() > 0)
346 o << " # locals" << endl;
347 for (unsigned j=0; j<f->locals.size(); j++)
348 {
349 vardecl* v = f->locals[j];
350 o << " ";
351 v->printsig (o);
352 o << endl;
353 }
354 if (s.verbose)
355 {
356 f->body->print (o);
357 o << endl;
358 }
359 }
dff50e09 360
16442b90
FCE
361 if (s.probes.size() > 0)
362 o << "# probes" << endl;
363 for (unsigned i=0; i<s.probes.size(); i++)
1b78aef5 364 {
f76427a2 365 if (pending_interrupts) return;
16442b90
FCE
366 derived_probe* p = s.probes[i];
367 p->printsig (o);
368 o << endl;
369 if (p->locals.size() > 0)
370 o << " # locals" << endl;
371 for (unsigned j=0; j<p->locals.size(); j++)
372 {
373 vardecl* v = p->locals[j];
374 o << " ";
375 v->printsig (o);
376 o << endl;
377 }
378 if (s.verbose)
379 {
380 p->body->print (o);
381 o << endl;
382 }
383 }
384 }
277f2b79 385}
1b78aef5 386
49abf162
FCE
387
388int pending_interrupts;
389
390extern "C"
82737bef 391void handle_interrupt (int sig)
49abf162 392{
4cc40e82 393 kill_stap_spawn(sig);
49abf162 394 pending_interrupts ++;
4cc40e82 395 if (pending_interrupts > 1) // XXX: should be configurable? time-based?
49abf162
FCE
396 {
397 char msg[] = "Too many interrupts received, exiting.\n";
398 int rc = write (2, msg, sizeof(msg)-1);
9ceec314 399 if (rc) {/* Do nothing; we don't care if our last gasp went out. */ ;}
49abf162
FCE
400 _exit (1);
401 }
402}
403
404
3972b443
DS
405void
406setup_signals (sighandler_t handler)
407{
408 struct sigaction sa;
409
410 sa.sa_handler = handler;
411 sigemptyset (&sa.sa_mask);
412 if (handler != SIG_IGN)
413 {
414 sigaddset (&sa.sa_mask, SIGHUP);
415 sigaddset (&sa.sa_mask, SIGPIPE);
416 sigaddset (&sa.sa_mask, SIGINT);
417 sigaddset (&sa.sa_mask, SIGTERM);
418 }
4cc40e82 419 sa.sa_flags = SA_RESTART;
3972b443
DS
420
421 sigaction (SIGHUP, &sa, NULL);
422 sigaction (SIGPIPE, &sa, NULL);
423 sigaction (SIGINT, &sa, NULL);
424 sigaction (SIGTERM, &sa, NULL);
425}
426
561079c8
FCE
427void setup_kernel_release (systemtap_session &s, const char* kstr)
428{
4d0a3330
KS
429 if (kstr[0] == '/') // fully specified path
430 {
431 s.kernel_build_tree = kstr;
432 string version_file_name = s.kernel_build_tree + "/include/config/kernel.release";
433 // The file include/config/kernel.release within the
434 // build tree is used to pull out the version information
435 ifstream version_file (version_file_name.c_str());
436 if (version_file.fail ())
437 {
438 cerr << "Missing " << version_file_name << endl;
439 exit(1);
440 }
441 else
442 {
443 char c;
444 s.kernel_release = "";
445 while (version_file.get(c) && c != '\n')
446 s.kernel_release.push_back(c);
447 }
448 }
449 else
450 {
451 s.kernel_release = string (kstr);
452 s.kernel_build_tree = "/lib/modules/" + s.kernel_release + "/build";
453 }
454}
3972b443 455
561079c8 456
6861e056 457int parse_kernel_config (systemtap_session &s)
561079c8
FCE
458{
459 // PR10702: pull config options
460 string kernel_config_file = s.kernel_build_tree + "/.config";
6861e056
CW
461 struct stat st;
462 int rc = stat(kernel_config_file.c_str(), &st);
463 if (rc != 0)
464 {
465 clog << "Checking \"" << kernel_config_file << "\" failed: " << strerror(errno) << endl
466 << "Ensure kernel development headers & makefiles are installed." << endl;
467 return rc;
468 }
469
561079c8
FCE
470 ifstream kcf (kernel_config_file.c_str());
471 string line;
472 while (getline (kcf, line))
473 {
60d98537 474 if (!startswith(line, "CONFIG_")) continue;
561079c8
FCE
475 size_t off = line.find('=');
476 if (off == string::npos) continue;
477 string key = line.substr(0, off);
478 string value = line.substr(off+1, string::npos);
479 s.kernel_config[key] = value;
480 }
481 if (s.verbose > 2)
482 clog << "Parsed kernel \"" << kernel_config_file << "\", number of tuples: " << s.kernel_config.size() << endl;
483
484 kcf.close();
6861e056 485 return 0;
561079c8
FCE
486}
487
70e6d6c9
FCE
488
489int parse_kernel_exports (systemtap_session &s)
490{
491 string kernel_exports_file = s.kernel_build_tree + "/Module.symvers";
492 struct stat st;
493 int rc = stat(kernel_exports_file.c_str(), &st);
494 if (rc != 0)
495 {
496 clog << "Checking \"" << kernel_exports_file << "\" failed: " << strerror(errno) << endl
497 << "Ensure kernel development headers & makefiles are installed." << endl;
498 return rc;
499 }
500
501 ifstream kef (kernel_exports_file.c_str());
502 string line;
503 while (getline (kef, line))
504 {
505 vector<string> tokens;
506 tokenize (line, tokens, "\t");
507 if (tokens.size() == 4 &&
508 tokens[2] == "vmlinux" &&
509 tokens[3].substr(0,13) == string("EXPORT_SYMBOL"))
510 s.kernel_exports.insert (tokens[1]);
511 }
512 if (s.verbose > 2)
513 clog << "Parsed kernel \"" << kernel_exports_file << "\", number of vmlinux exports: " << s.kernel_exports.size() << endl;
514
515 kef.close();
516 return 0;
517}
518
519
28b768e1
MW
520/*
521 * Returns a string describing memory resource usage.
522 * Since it seems getrusage() doesn't maintain the mem related fields,
523 * this routine parses /proc/self/statm to get the statistics.
524 */
525static string
526getmemusage ()
527{
71b6e9b2 528 static long sz = sysconf(_SC_PAGESIZE);
28b768e1
MW
529
530 long pages, kb;
531 ostringstream oss;
532 ifstream statm("/proc/self/statm");
533 statm >> pages;
534 kb = pages * sz / 1024;
535 oss << "using " << kb << "virt/";
536 statm >> pages;
537 kb = pages * sz / 1024;
538 oss << kb << "res/";
539 statm >> pages;
540 kb = pages * sz / 1024;
541 oss << kb << "shr kb, ";
542 return oss.str();
543}
544
2b066ec1
FCE
545int
546main (int argc, char * const argv [])
547{
2b066ec1
FCE
548 string cmdline_script; // -e PROGRAM
549 string script_file; // FILE
550 bool have_script = false;
fc52ef5b 551 bool save_module = false;
f4b28491
FCE
552
553 // Initialize defaults
554 systemtap_session s;
555 struct utsname buf;
556 (void) uname (& buf);
557 s.kernel_release = string (buf.release);
b5e66ada
FCE
558 s.kernel_build_tree = "/lib/modules/" + s.kernel_release + "/build";
559
d27e6fd5
FCE
560 // PR4186: Copy logic from coreutils uname (uname -i) to squash
561 // i?86->i386. Actually, copy logic from linux top-level Makefile
562 // to squash uname -m -> $(SUBARCH).
563
564 string machine = buf.machine;
565 if (machine == "i486") machine = "i386";
566 else if (machine == "i586") machine = "i386";
567 else if (machine == "i686") machine = "i386";
568 else if (machine == "sun4u") machine = "sparc64";
569 else if (machine.substr(0,3) == "arm") machine = "arm";
570 else if (machine == "sa110") machine = "arm";
571 else if (machine == "s390x") machine = "s390";
572 else if (machine.substr(0,3) == "ppc") machine = "powerpc";
573 else if (machine.substr(0,4) == "mips") machine = "mips";
574 else if (machine.substr(0,3) == "sh2") machine = "sh";
575 else if (machine.substr(0,3) == "sh3") machine = "sh";
576 else if (machine.substr(0,3) == "sh4") machine = "sh";
577
578 s.architecture = machine;
e0b4e89d 579 for (unsigned i=0; i<5; i++) s.perpass_verbose[i]=0;
a9e8f7e0 580 s.timing = false;
377b8831 581 s.guru_mode = false;
16d8de1b 582 s.bulk_mode = false;
cbfbbf69 583 s.unoptimized = false;
a9e8f7e0 584 s.suppress_warnings = false;
57a56e00 585 s.panic_warnings = false;
16442b90 586 s.listing_mode = false;
8c39844b 587 s.listing_mode_vars = false;
44f75386
FCE
588
589#ifdef ENABLE_PROLOGUES
590 s.prologue_searching = true;
591#else
592 s.prologue_searching = false;
593#endif
594
16d8de1b 595 s.buffer_size = 0;
f4b28491 596 s.last_pass = 5;
aca66a36
JS
597 s.module_name = "stap_" + lex_cast(getpid());
598 s.stapconf_name = "stapconf_" + lex_cast(getpid()) + ".h";
08c68653 599 s.output_file = ""; // -o FILE
f4b28491 600 s.keep_tmpdir = false;
4c5ff1bb
MH
601 s.cmd = "";
602 s.target_pid = 0;
f1bad60c 603 s.symtab = false;
1b78aef5 604 s.use_cache = true;
63d530ab 605 s.use_script_cache = true;
d105f664 606 s.poison_cache = false;
c3a3c0c9 607 s.tapset_compile_coverage = false;
12dc24bc 608 s.need_uprobes = false;
5f0a03a6
JK
609 s.consult_symtab = false;
610 s.ignore_vmlinux = false;
611 s.ignore_dwarf = false;
2fa2a091 612 s.load_only = false;
28f569c2 613 s.skip_badvars = false;
2f54c4fe 614 s.unprivileged = false;
c72dd3c7 615 s.omit_werror = false;
db135493 616 s.compatible = VERSION; // XXX: perhaps also process GIT_SHAID if available?
ef06c938 617 s.unwindsym_ldd = false;
a0ace491
DB
618 bool client_options = false;
619 string client_options_disallowed;
2f54c4fe 620
4c797c5e 621 // Location of our signing certificate.
2f54c4fe
DB
622 // If we're root, use the database in SYSCONFDIR, otherwise
623 // use the one in our $HOME directory. */
624 if (getuid() == 0)
625 s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
626 else
627 s.cert_db_path = getenv("HOME") + string ("/.systemtap/ssl/server");
24cb178f
FCE
628
629 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
dff50e09 630 if (s_p != NULL)
ec819dc3 631 {
24cb178f 632 s.include_path.push_back (s_p);
ec819dc3 633 }
24cb178f 634 else
ec819dc3 635 {
24cb178f 636 s.include_path.push_back (string(PKGDATADIR) + "/tapset");
ec819dc3 637 }
24cb178f
FCE
638
639 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
640 if (s_r != NULL)
641 s.runtime_path = s_r;
642 else
643 s.runtime_path = string(PKGDATADIR) + "/runtime";
f4b28491 644
1b78aef5
DS
645 const char* s_d = getenv ("SYSTEMTAP_DIR");
646 if (s_d != NULL)
647 s.data_path = s_d;
648 else
649 s.data_path = get_home_directory() + string("/.systemtap");
650 if (create_dir(s.data_path.c_str()) == 1)
651 {
652 const char* e = strerror (errno);
f4d5049b
FCE
653 if (! s.suppress_warnings)
654 cerr << "Warning: failed to create systemtap data directory (\""
655 << s.data_path << "\"): " << e
656 << ", disabling cache support." << endl;
63d530ab 657 s.use_cache = s.use_script_cache = false;
1b78aef5
DS
658 }
659
660 if (s.use_cache)
661 {
662 s.cache_path = s.data_path + "/cache";
663 if (create_dir(s.cache_path.c_str()) == 1)
664 {
665 const char* e = strerror (errno);
f4d5049b
FCE
666 if (! s.suppress_warnings)
667 cerr << "Warning: failed to create cache directory (\""
668 << s.cache_path << "\"): " << e
669 << ", disabling cache support." << endl;
63d530ab 670 s.use_cache = s.use_script_cache = false;
1b78aef5
DS
671 }
672 }
673
36b66efa
DB
674 // Location of our signing certificate.
675 // If we're root, use the database in SYSCONFDIR, otherwise
676 // use the one in s.data_path. */
677 if (geteuid() == 0)
678 s.cert_db_path = SYSCONFDIR "/systemtap/ssl/server";
679 else
680 s.cert_db_path = s.data_path + "/ssl/server";
681
c3a3c0c9
WC
682 const char* s_tc = getenv ("SYSTEMTAP_COVERAGE");
683 if (s_tc != NULL)
684 s.tapset_compile_coverage = true;
685
755cdd9b
KS
686 const char* s_kr = getenv ("SYSTEMTAP_RELEASE");
687 if (s_kr != NULL) {
4d0a3330 688 setup_kernel_release(s, s_kr);
755cdd9b
KS
689 }
690
2b066ec1
FCE
691 while (true)
692 {
5f0a03a6 693 int long_opt;
877bbb20 694 char * num_endptr;
5f0a03a6
JK
695#define LONG_OPT_KELF 1
696#define LONG_OPT_KMAP 2
697#define LONG_OPT_IGNORE_VMLINUX 3
698#define LONG_OPT_IGNORE_DWARF 4
e0b4e89d 699#define LONG_OPT_VERBOSE_PASS 5
3bd0d4df 700#define LONG_OPT_SKIP_BADVARS 6
4c797c5e 701#define LONG_OPT_UNPRIVILEGED 7
c72dd3c7
PP
702#define LONG_OPT_OMIT_WERROR 8
703#define LONG_OPT_CLIENT_OPTIONS 9
83b38ce6 704#define LONG_OPT_HELP 10
d105f664
JS
705#define LONG_OPT_DISABLE_CACHE 11
706#define LONG_OPT_POISON_CACHE 12
707#define LONG_OPT_CLEAN_CACHE 13
db135493 708#define LONG_OPT_COMPATIBLE 14
ef06c938 709#define LONG_OPT_LDD 15
a9e8f7e0 710 // NB: also see find_hash(), usage(), switch stmt below, stap.1 man page
5f0a03a6
JK
711 static struct option long_options[] = {
712 { "kelf", 0, &long_opt, LONG_OPT_KELF },
713 { "kmap", 2, &long_opt, LONG_OPT_KMAP },
714 { "ignore-vmlinux", 0, &long_opt, LONG_OPT_IGNORE_VMLINUX },
715 { "ignore-dwarf", 0, &long_opt, LONG_OPT_IGNORE_DWARF },
3bd0d4df 716 { "skip-badvars", 0, &long_opt, LONG_OPT_SKIP_BADVARS },
e0b4e89d 717 { "vp", 1, &long_opt, LONG_OPT_VERBOSE_PASS },
2f54c4fe 718 { "unprivileged", 0, &long_opt, LONG_OPT_UNPRIVILEGED },
c72dd3c7
PP
719#define OWE5 "tter"
720#define OWE1 "uild-"
721#define OWE6 "fu-kb"
722#define OWE2 "i-kno"
723#define OWE4 "st"
724#define OWE3 "w-be"
725 { OWE4 OWE6 OWE1 OWE2 OWE3 OWE5, 0, &long_opt, LONG_OPT_OMIT_WERROR },
a0ace491 726 { "client-options", 0, &long_opt, LONG_OPT_CLIENT_OPTIONS },
83b38ce6 727 { "help", 0, &long_opt, LONG_OPT_HELP },
d105f664
JS
728 { "disable-cache", 0, &long_opt, LONG_OPT_DISABLE_CACHE },
729 { "poison-cache", 0, &long_opt, LONG_OPT_POISON_CACHE },
730 { "clean-cache", 0, &long_opt, LONG_OPT_CLEAN_CACHE },
db135493 731 { "compatible", 1, &long_opt, LONG_OPT_COMPATIBLE },
ef06c938 732 { "ldd", 0, &long_opt, LONG_OPT_LDD },
5f0a03a6
JK
733 { NULL, 0, NULL, 0 }
734 };
57a56e00 735 int grc = getopt_long (argc, argv, "hVvtp:I:e:o:R:r:a:m:kgPc:x:D:bs:uqwl:d:L:FS:B:W",
1392896d 736 long_options, NULL);
2b066ec1
FCE
737 if (grc < 0)
738 break;
739 switch (grc)
740 {
c0de7a8d
FCE
741 case 'V':
742 version ();
743 exit (0);
744
bd2b1e68 745 case 'v':
e0b4e89d
FCE
746 for (unsigned i=0; i<5; i++)
747 s.perpass_verbose[i] ++;
bd2b1e68
GH
748 break;
749
4b17d6af 750 case 't':
a9e8f7e0
FCE
751 s.timing = true;
752 break;
753
754 case 'w':
755 s.suppress_warnings = true;
4b17d6af
WC
756 break;
757
57a56e00
FCE
758 case 'W':
759 s.panic_warnings = true;
760 break;
761
2b066ec1 762 case 'p':
877bbb20
SW
763 s.last_pass = (int)strtoul(optarg, &num_endptr, 10);
764 if (*num_endptr != '\0' || s.last_pass < 1 || s.last_pass > 5)
2b066ec1 765 {
277c1957 766 cerr << "Invalid pass number (should be 1-5)." << endl;
83b38ce6 767 exit (1);
2b066ec1 768 }
8afee8bb
DB
769 if (s.listing_mode && s.last_pass != 2)
770 {
771 cerr << "Listing (-l) mode implies pass 2." << endl;
83b38ce6 772 exit (1);
8afee8bb 773 }
2b066ec1
FCE
774 break;
775
776 case 'I':
a0ace491
DB
777 if (client_options)
778 client_options_disallowed += client_options_disallowed.empty () ? "-I" : ", -I";
f4b28491 779 s.include_path.push_back (string (optarg));
2b066ec1
FCE
780 break;
781
a8368458 782 case 'd':
f6ac00e8
MW
783 {
784 // At runtime user module names are resolved through their
785 // canonical (absolute) path.
786 const char *mpath = canonicalize_file_name (optarg);
787 if (mpath == NULL) // Must be a kernel module name
788 mpath = optarg;
789 s.unwindsym_modules.insert (string (mpath));
790 // PR10228: trigger task-finder logic early if -d /USER-MODULE/
791 // given.
792 if (mpath[0] == '/')
793 enable_task_finder (s);
794 break;
795 }
a8368458 796
2b066ec1
FCE
797 case 'e':
798 if (have_script)
277c1957
DS
799 {
800 cerr << "Only one script can be given on the command line."
801 << endl;
83b38ce6 802 exit (1);
277c1957 803 }
2b066ec1
FCE
804 cmdline_script = string (optarg);
805 have_script = true;
806 break;
807
808 case 'o':
c0d1b5a0 809 // NB: client_options not a problem, since pass 1-4 does not use output_file.
08c68653 810 s.output_file = string (optarg);
2b066ec1
FCE
811 break;
812
f4b28491 813 case 'R':
83b38ce6 814 if (client_options) { cerr << "ERROR: -R invalid with --client-options" << endl; exit(1); }
f4b28491
FCE
815 s.runtime_path = string (optarg);
816 break;
817
818 case 'm':
a0ace491
DB
819 if (client_options)
820 client_options_disallowed += client_options_disallowed.empty () ? "-m" : ", -m";
f4b28491 821 s.module_name = string (optarg);
fc52ef5b 822 save_module = true;
c0d1b5a0 823 // XXX: convert to assert_regexp_match()
3b942fed 824 {
3b942fed
DS
825 // If the module name ends with '.ko', chop it off since
826 // modutils doesn't like modules named 'foo.ko.ko'.
60d98537 827 if (endswith(s.module_name, ".ko"))
3b942fed 828 {
60d98537 829 s.module_name.erase(s.module_name.size() - 3);
3b942fed
DS
830 cerr << "Truncating module name to '" << s.module_name
831 << "'" << endl;
832 }
833
834 // Make sure an empty module name wasn't specified (-m "")
60d98537 835 if (s.module_name.empty())
3b942fed
DS
836 {
837 cerr << "Module name cannot be empty." << endl;
83b38ce6 838 exit(1);
3b942fed
DS
839 }
840
841 // Make sure the module name is only composed of the
842 // following chars: [_a-zA-Z0-9]
843 const string identchars("_" "abcdefghijklmnopqrstuvwxyz"
844 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789");
845 if (s.module_name.find_first_not_of(identchars) != string::npos)
846 {
847 cerr << "Invalid module name (must only be composed of"
848 " characters [_a-zA-Z0-9])." << endl;
83b38ce6 849 exit(1);
3b942fed 850 }
98aab489
DS
851
852 // Make sure module name isn't too long.
853 if (s.module_name.size() >= (MODULE_NAME_LEN - 1))
854 {
855 s.module_name.resize(MODULE_NAME_LEN - 1);
856 cerr << "Truncating module name to '" << s.module_name
857 << "'" << endl;
858 }
3b942fed
DS
859 }
860
63d530ab 861 s.use_script_cache = false;
f4b28491
FCE
862 break;
863
864 case 'r':
c0d1b5a0 865 if (client_options) // NB: no paths!
cc9e5488 866 assert_regexp_match("-r parameter from client", optarg, "^[a-z0-9_.-]+$");
4d0a3330 867 setup_kernel_release(s, optarg);
f4b28491
FCE
868 break;
869
1392896d 870 case 'a':
c0d1b5a0
FCE
871 assert_regexp_match("-a parameter", optarg, "^[a-z0-9_-]+$");
872 s.architecture = string(optarg);
1392896d
FCE
873 break;
874
f4b28491
FCE
875 case 'k':
876 s.keep_tmpdir = true;
63d530ab 877 s.use_script_cache = false; /* User wants to keep a usable build tree. */
f4b28491
FCE
878 break;
879
377b8831
FCE
880 case 'g':
881 s.guru_mode = true;
882 break;
883
44f75386
FCE
884 case 'P':
885 s.prologue_searching = true;
886 break;
887
16d8de1b
TZ
888 case 'b':
889 s.bulk_mode = true;
16d8de1b
TZ
890 break;
891
cbfbbf69
FCE
892 case 'u':
893 s.unoptimized = true;
894 break;
895
16d8de1b 896 case 's':
5d8d4509
SW
897 s.buffer_size = (int) strtoul (optarg, &num_endptr, 10);
898 if (*num_endptr != '\0' || s.buffer_size < 1 || s.buffer_size > 4095)
16d8de1b 899 {
453b58ed 900 cerr << "Invalid buffer size (should be 1-4095)." << endl;
83b38ce6 901 exit(1);
16d8de1b
TZ
902 }
903 break;
904
4c5ff1bb
MH
905 case 'c':
906 s.cmd = string (optarg);
907 break;
908
909 case 'x':
c897e941
SW
910 s.target_pid = (int) strtoul(optarg, &num_endptr, 10);
911 if (*num_endptr != '\0')
912 {
913 cerr << "Invalid target process ID number." << endl;
83b38ce6 914 exit (1);
c897e941 915 }
4c5ff1bb
MH
916 break;
917
ed10c639 918 case 'D':
c8408b45 919 assert_regexp_match ("-D parameter", optarg, "^[a-z_][a-z_0-9]*(=-?[a-z_0-9]+)?$");
a0ace491
DB
920 if (client_options)
921 client_options_disallowed += client_options_disallowed.empty () ? "-D" : ", -D";
ed10c639
FCE
922 s.macros.push_back (string (optarg));
923 break;
924
701c41be 925 case 'S':
c0d1b5a0 926 assert_regexp_match ("-S parameter", optarg, "^[0-9]+(,[0-9]+)?$");
701c41be
MH
927 s.size_option = string (optarg);
928 break;
929
c3a3c0c9 930 case 'q':
83b38ce6 931 if (client_options) { cerr << "ERROR: -q invalid with --client-options" << endl; exit(1); }
c3a3c0c9
WC
932 s.tapset_compile_coverage = true;
933 break;
934
2b066ec1 935 case 'h':
277c1957
DS
936 usage (s, 0);
937 break;
938
d4e35ac8 939 case 'L':
8c39844b 940 s.listing_mode_vars = true;
1044139f 941 s.unoptimized = true; // This causes retention of variables for listing_mode
d4e35ac8 942
16442b90 943 case 'l':
4bd48e4b 944 s.suppress_warnings = true;
16442b90
FCE
945 s.listing_mode = true;
946 s.last_pass = 2;
947 if (have_script)
948 {
949 cerr << "Only one script can be given on the command line."
950 << endl;
83b38ce6 951 exit (1);
16442b90
FCE
952 }
953 cmdline_script = string("probe ") + string(optarg) + " {}";
954 have_script = true;
955 break;
956
2fa2a091
NT
957 case 'F':
958 s.load_only = true;
959 break;
960
1392896d 961 case 'B':
83b38ce6 962 if (client_options) { cerr << "ERROR: -B invalid with --client-options" << endl; exit(1); }
c0d1b5a0 963 s.kbuildflags.push_back (string (optarg));
1392896d
FCE
964 break;
965
5f0a03a6
JK
966 case 0:
967 switch (long_opt)
968 {
969 case LONG_OPT_KELF:
970 s.consult_symtab = true;
971 break;
972 case LONG_OPT_KMAP:
973 // Leave s.consult_symtab unset for now, to ease error checking.
974 if (!s.kernel_symtab_path.empty())
975 {
976 cerr << "You can't specify multiple --kmap options." << endl;
83b38ce6 977 exit(1);
5f0a03a6
JK
978 }
979 if (optarg)
980 s.kernel_symtab_path = optarg;
981 else
5f0a03a6
JK
982 s.kernel_symtab_path = PATH_TBD;
983 break;
984 case LONG_OPT_IGNORE_VMLINUX:
985 s.ignore_vmlinux = true;
986 break;
987 case LONG_OPT_IGNORE_DWARF:
988 s.ignore_dwarf = true;
989 break;
e0b4e89d
FCE
990 case LONG_OPT_VERBOSE_PASS:
991 {
992 bool ok = true;
993 if (strlen(optarg) < 1 || strlen(optarg) > 5)
994 ok = false;
995 if (ok)
b688229d 996 for (unsigned i=0; i<strlen(optarg); i++)
e0b4e89d
FCE
997 if (isdigit (optarg[i]))
998 s.perpass_verbose[i] += optarg[i]-'0';
999 else
1000 ok = false;
1001
1002 if (! ok)
1003 {
1004 cerr << "Invalid --vp argument: it takes 1 to 5 digits." << endl;
83b38ce6 1005 exit (1);
e0b4e89d
FCE
1006 }
1007 // NB: we don't do this: s.last_pass = strlen(optarg);
1008 break;
1009 }
3bd0d4df
RA
1010 case LONG_OPT_SKIP_BADVARS:
1011 s.skip_badvars = true;
1012 break;
2f54c4fe
DB
1013 case LONG_OPT_UNPRIVILEGED:
1014 s.unprivileged = true;
cf4a6df8
FCE
1015 /* NB: for server security, it is essential that once this flag is
1016 set, no future flag be able to unset it. */
2f54c4fe 1017 break;
c72dd3c7
PP
1018 case LONG_OPT_OMIT_WERROR:
1019 s.omit_werror = true;
1020 break;
a0ace491
DB
1021 case LONG_OPT_CLIENT_OPTIONS:
1022 client_options = true;
3c070417 1023 break;
83b38ce6
FCE
1024 case LONG_OPT_HELP:
1025 usage (s, 0);
1026 break;
d105f664
JS
1027
1028 // The caching options should not be available to server clients
1029 case LONG_OPT_DISABLE_CACHE:
1030 if (client_options) {
1031 cerr << "ERROR: --disable-cache is invalid with --client-options" << endl;
1032 exit(1);
1033 }
1034 s.use_cache = s.use_script_cache = false;
1035 break;
1036 case LONG_OPT_POISON_CACHE:
1037 if (client_options) {
1038 cerr << "ERROR: --poison-cache is invalid with --client-options" << endl;
1039 exit(1);
1040 }
1041 s.poison_cache = true;
1042 break;
1043 case LONG_OPT_CLEAN_CACHE:
1044 if (client_options) {
1045 cerr << "ERROR: --clean-cache is invalid with --client-options" << endl;
1046 exit(1);
1047 }
1048 clean_cache(s);
1049 exit(0);
1050
db135493
FCE
1051 case LONG_OPT_COMPATIBLE:
1052 s.compatible = optarg;
1053 break;
1054
ef06c938
FCE
1055 case LONG_OPT_LDD:
1056 s.unwindsym_ldd = true;
1057 break;
1058
5f0a03a6 1059 default:
db135493
FCE
1060 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
1061 cerr << "Unhandled long argument id " << long_opt << endl;
83b38ce6 1062 exit(1);
5f0a03a6
JK
1063 }
1064 break;
1065
2b066ec1 1066 default:
db135493
FCE
1067 // NOTREACHED unless one added a getopt option but not a corresponding switch/case:
1068 cerr << "Unhandled argument code " << (char)grc << endl;
83b38ce6 1069 exit(1);
277c1957 1070 break;
2b066ec1
FCE
1071 }
1072 }
1073
8f222481 1074 // Check for options conflicts.
75c2a31d 1075
cf4a6df8
FCE
1076 if (client_options && s.last_pass > 4)
1077 {
1078 s.last_pass = 4; /* Quietly downgrade. Server passed through -p5 naively. */
1079 }
a0ace491
DB
1080 if (client_options && s.unprivileged && ! client_options_disallowed.empty ())
1081 {
1082 cerr << "You can't specify " << client_options_disallowed << " when --unprivileged is specified." << endl;
1083 usage (s, 1);
1084 }
75c2a31d
FCE
1085 if ((s.cmd != "") && (s.target_pid))
1086 {
1087 cerr << "You can't specify -c and -x options together." << endl;
1088 usage (s, 1);
1089 }
1090 if (s.unprivileged && s.guru_mode)
1091 {
1092 cerr << "You can't specify -g and --unprivileged together." << endl;
1093 usage (s, 1);
1094 }
1095 if (!s.kernel_symtab_path.empty())
1096 {
1097 if (s.consult_symtab)
1098 {
1099 cerr << "You can't specify --kelf and --kmap together." << endl;
1100 usage (s, 1);
1101 }
1102 s.consult_symtab = true;
1103 if (s.kernel_symtab_path == PATH_TBD)
1104 s.kernel_symtab_path = string("/boot/System.map-") + s.kernel_release;
1105 }
b5e66ada
FCE
1106 // Warn in case the target kernel release doesn't match the running one.
1107 if (s.last_pass > 4 &&
1108 (string(buf.release) != s.kernel_release ||
d27e6fd5 1109 machine != s.architecture)) // NB: squashed ARCH by PR4186 logic
b5e66ada
FCE
1110 {
1111 if(! s.suppress_warnings)
1112 cerr << "WARNING: kernel release/architecture mismatch with host forces last-pass 4." << endl;
1113 s.last_pass = 4;
1114 }
ea3f75ae 1115
2b066ec1
FCE
1116 for (int i = optind; i < argc; i++)
1117 {
1118 if (! have_script)
1119 {
1120 script_file = string (argv[i]);
1121 have_script = true;
1122 }
1123 else
f4b28491 1124 s.args.push_back (string (argv[i]));
2b066ec1
FCE
1125 }
1126
1127 // need a user file
83b38ce6 1128 // NB: this is also triggered if stap is invoked with no arguments at all
2b066ec1 1129 if (! have_script)
277c1957
DS
1130 {
1131 cerr << "A script must be specified." << endl;
1132 usage(s, 1);
1133 }
f4b28491 1134
a929fd0f
Z
1135 // translate path of runtime to absolute path
1136 if (s.runtime_path[0] != '/')
1137 {
1138 char cwd[PATH_MAX];
1139 if (getcwd(cwd, sizeof(cwd)))
1140 {
1141 s.runtime_path = string(cwd) + "/" + s.runtime_path;
1142 }
1143 }
1144
f4b28491 1145 int rc = 0;
c31df222
FCE
1146
1147 // PASS 0: setting up
1148 s.verbose = s.perpass_verbose[0];
ce91eebd
KS
1149 STAP_PROBE1(stap, pass0__start, &s);
1150
2b066ec1 1151
d0a7f5a9
FCE
1152 // For PR1477, we used to override $PATH and $LC_ALL and other stuff
1153 // here. We seem to use complete pathnames in
1154 // buildrun.cxx/tapsets.cxx now, so this is not necessary. Further,
1155 // it interferes with util.cxx:find_executable(), used for $PATH
1156 // resolution.
861c2f28 1157
197a4d62
JS
1158 s.kernel_base_release.assign(s.kernel_release, 0, s.kernel_release.find('-'));
1159
2b066ec1 1160 // arguments parsed; get down to business
72d18b98 1161 if (s.verbose > 1)
c0e526f0
FCE
1162 {
1163 version ();
1164 clog << "Session arch: " << s.architecture
1165 << " release: " << s.kernel_release
1166 << endl;
1167 }
2b066ec1 1168
f4b28491
FCE
1169 // Create a temporary directory to build within.
1170 // Be careful with this, as "s.tmpdir" is "rm -rf"'d at the end.
1171 {
c72dc86c 1172 const char* tmpdir_env = getenv("TMPDIR");
ea8ea02c
FCE
1173 if (! tmpdir_env)
1174 tmpdir_env = "/tmp";
dff50e09 1175
ea8ea02c
FCE
1176 string stapdir = "/stapXXXXXX";
1177 string tmpdirt = tmpdir_env + stapdir;
533af4f0 1178 mode_t mask = umask(0);
ea8ea02c 1179 const char* tmpdir = mkdtemp((char *)tmpdirt.c_str());
533af4f0 1180 umask(mask);
f4b28491
FCE
1181 if (! tmpdir)
1182 {
1183 const char* e = strerror (errno);
ea8ea02c
FCE
1184 cerr << "ERROR: cannot create temporary directory (\"" << tmpdirt << "\"): " << e << endl;
1185 exit (1); // die
f4b28491
FCE
1186 }
1187 else
1188 s.tmpdir = tmpdir;
0d49d7bc 1189
b0ee93c4 1190 if (s.verbose>1)
0d49d7bc 1191 clog << "Created temporary directory \"" << s.tmpdir << "\"" << endl;
f4b28491 1192 }
2b066ec1 1193
561079c8 1194 // Now that no further changes to s.kernel_build_tree can occur, let's use it.
6861e056 1195 if (parse_kernel_config (s) != 0)
70e6d6c9
FCE
1196 exit (1);
1197
1198 if (parse_kernel_exports (s) != 0)
1199 exit (1);
6861e056 1200
561079c8 1201
1b78aef5
DS
1202 // Create the name of the C source file within the temporary
1203 // directory.
1204 s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
1205
dff50e09 1206 // Set up our handler to catch routine signals, to allow clean
49abf162 1207 // and reasonably timely exit.
3972b443 1208 setup_signals(&handle_interrupt);
49abf162 1209
ce91eebd
KS
1210 STAP_PROBE1(stap, pass0__end, &s);
1211
5ee1c56b
FCE
1212 struct tms tms_before;
1213 times (& tms_before);
1d738eed
FCE
1214 struct timeval tv_before;
1215 gettimeofday (&tv_before, NULL);
2b066ec1
FCE
1216
1217 // PASS 1a: PARSING USER SCRIPT
ce91eebd 1218 STAP_PROBE1(stap, pass1a__start, &s);
f59e98c4
FCE
1219
1220 struct stat user_file_stat;
1221 int user_file_stat_rc = -1;
1222
69c68955 1223 if (script_file == "-")
129be0ac
FCE
1224 {
1225 s.user_file = parser::parse (s, cin, s.guru_mode);
1226 user_file_stat_rc = fstat (STDIN_FILENO, & user_file_stat);
1227 }
69c68955 1228 else if (script_file != "")
f59e98c4
FCE
1229 {
1230 s.user_file = parser::parse (s, script_file, s.guru_mode);
1231 user_file_stat_rc = stat (script_file.c_str(), & user_file_stat);
1232 }
2b066ec1
FCE
1233 else
1234 {
1235 istringstream ii (cmdline_script);
177a8ead 1236 s.user_file = parser::parse (s, ii, s.guru_mode);
2b066ec1
FCE
1237 }
1238 if (s.user_file == 0)
1239 // syntax errors already printed
1240 rc ++;
377b8831 1241
5519d363 1242 // Construct arch / kernel-versioning search path
377b8831 1243 vector<string> version_suffixes;
6f9f33e2 1244 string kvr = s.kernel_release;
5519d363
KS
1245 const string& arch = s.architecture;
1246 // add full kernel-version-release (2.6.NN-FOOBAR) + arch
1247 version_suffixes.push_back ("/" + kvr + "/" + arch);
377b8831 1248 version_suffixes.push_back ("/" + kvr);
5519d363 1249 // add kernel version (2.6.NN) + arch
197a4d62
JS
1250 if (kvr != s.kernel_base_release) {
1251 kvr = s.kernel_base_release;
6f9f33e2
JS
1252 version_suffixes.push_back ("/" + kvr + "/" + arch);
1253 version_suffixes.push_back ("/" + kvr);
5519d363
KS
1254 }
1255 // add kernel family (2.6) + arch
6f9f33e2
JS
1256 string::size_type dot1_index = kvr.find ('.');
1257 string::size_type dot2_index = kvr.rfind ('.');
1258 while (dot2_index > dot1_index && dot2_index != string::npos) {
1259 kvr.erase(dot2_index);
1260 version_suffixes.push_back ("/" + kvr + "/" + arch);
1261 version_suffixes.push_back ("/" + kvr);
1262 dot2_index = kvr.rfind ('.');
5519d363
KS
1263 }
1264 // add architecture search path
1265 version_suffixes.push_back("/" + arch);
377b8831
FCE
1266 // add empty string as last element
1267 version_suffixes.push_back ("");
2b066ec1
FCE
1268
1269 // PASS 1b: PARSING LIBRARY SCRIPTS
ce91eebd
KS
1270 STAP_PROBE1(stap, pass1b__start, &s);
1271
f4b28491 1272 for (unsigned i=0; i<s.include_path.size(); i++)
2b066ec1 1273 {
377b8831
FCE
1274 // now iterate upon it
1275 for (unsigned k=0; k<version_suffixes.size(); k++)
2b066ec1 1276 {
377b8831
FCE
1277 glob_t globbuf;
1278 string dir = s.include_path[i] + version_suffixes[k] + "/*.stp";
1279 int r = glob(dir.c_str (), 0, NULL, & globbuf);
1280 if (r == GLOB_NOSPACE || r == GLOB_ABORTED)
2b066ec1 1281 rc ++;
377b8831
FCE
1282 // GLOB_NOMATCH is acceptable
1283
c4a94c1a 1284 if (s.verbose>1 && globbuf.gl_pathc > 0)
561079c8 1285 clog << "Searched \"" << dir << "\", "
c4a94c1a 1286 << "found " << globbuf.gl_pathc << endl;
2b066ec1 1287
377b8831
FCE
1288 for (unsigned j=0; j<globbuf.gl_pathc; j++)
1289 {
49abf162
FCE
1290 if (pending_interrupts)
1291 break;
1292
1293 // XXX: privilege only for /usr/share/systemtap?
177a8ead 1294 stapfile* f = parser::parse (s, globbuf.gl_pathv[j], true);
377b8831 1295 if (f == 0)
1d844b57
JS
1296 s.print_warning("tapset '" + string(globbuf.gl_pathv[j])
1297 + "' has errors, and will be skipped.");
377b8831 1298 else
24cb178f 1299 s.library_files.push_back (f);
f59e98c4
FCE
1300
1301 struct stat tapset_file_stat;
1302 int stat_rc = stat (globbuf.gl_pathv[j], & tapset_file_stat);
1303 if (stat_rc == 0 && user_file_stat_rc == 0 &&
1304 user_file_stat.st_dev == tapset_file_stat.st_dev &&
1305 user_file_stat.st_ino == tapset_file_stat.st_ino)
1306 {
129be0ac
FCE
1307 clog << "usage error: tapset file '" << globbuf.gl_pathv[j]
1308 << "' cannot be run directly as a session script." << endl;
f59e98c4
FCE
1309 rc ++;
1310 }
1311
377b8831 1312 }
d54d4661 1313
377b8831
FCE
1314 globfree (& globbuf);
1315 }
2b066ec1 1316 }
1d844b57
JS
1317 if (s.num_errors())
1318 rc ++;
2b066ec1 1319
f4b28491 1320 if (rc == 0 && s.last_pass == 1)
2b066ec1 1321 {
f4b28491
FCE
1322 cout << "# parse tree dump" << endl;
1323 s.user_file->print (cout);
1324 cout << endl;
ae56fddd
FCE
1325 if (s.verbose)
1326 for (unsigned i=0; i<s.library_files.size(); i++)
1327 {
1328 s.library_files[i]->print (cout);
1329 cout << endl;
1330 }
2b066ec1
FCE
1331 }
1332
5ee1c56b
FCE
1333 struct tms tms_after;
1334 times (& tms_after);
1335 unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK);
1d738eed
FCE
1336 struct timeval tv_after;
1337 gettimeofday (&tv_after, NULL);
5ee1c56b 1338
28b768e1 1339#define TIMESPRINT "in " << \
5ee1c56b 1340 (tms_after.tms_cutime + tms_after.tms_utime \
1d738eed 1341 - tms_before.tms_cutime - tms_before.tms_utime) * 1000 / (_sc_clk_tck) << "usr/" \
5ee1c56b 1342 << (tms_after.tms_cstime + tms_after.tms_stime \
1d738eed
FCE
1343 - tms_before.tms_cstime - tms_before.tms_stime) * 1000 / (_sc_clk_tck) << "sys/" \
1344 << ((tv_after.tv_sec - tv_before.tv_sec) * 1000 + \
1345 ((long)tv_after.tv_usec - (long)tv_before.tv_usec) / 1000) << "real ms."
5ee1c56b 1346
eaf134e7 1347 // syntax errors, if any, are already printed
5ee1c56b
FCE
1348 if (s.verbose)
1349 {
1350 clog << "Pass 1: parsed user script and "
1351 << s.library_files.size()
28b768e1
MW
1352 << " library script(s) "
1353 << getmemusage()
5ee1c56b
FCE
1354 << TIMESPRINT
1355 << endl;
1356 }
0d49d7bc 1357
708ce1f3 1358 if (rc && !s.listing_mode)
2cfb0e46 1359 cerr << "Pass 1: parse failed. "
c3157bcd 1360 << "Try again with another '--vp 1' option."
2cfb0e46
FCE
1361 << endl;
1362
ce91eebd
KS
1363 STAP_PROBE1(stap, pass1__end, &s);
1364
49abf162 1365 if (rc || s.last_pass == 1 || pending_interrupts) goto cleanup;
f4b28491 1366
5ee1c56b 1367 times (& tms_before);
1d738eed 1368 gettimeofday (&tv_before, NULL);
5ee1c56b 1369
2b066ec1 1370 // PASS 2: ELABORATION
e0b4e89d 1371 s.verbose = s.perpass_verbose[1];
ce91eebd 1372 STAP_PROBE1(stap, pass2__start, &s);
0d49d7bc 1373 rc = semantic_pass (s);
f4b28491 1374
16442b90 1375 if (s.listing_mode || (rc == 0 && s.last_pass == 2))
1b78aef5 1376 printscript(s, cout);
2b066ec1 1377
5ee1c56b 1378 times (& tms_after);
1d738eed
FCE
1379 gettimeofday (&tv_after, NULL);
1380
b0ee93c4 1381 if (s.verbose) clog << "Pass 2: analyzed script: "
0d49d7bc
FCE
1382 << s.probes.size() << " probe(s), "
1383 << s.functions.size() << " function(s), "
b20febf3 1384 << s.embeds.size() << " embed(s), "
28b768e1
MW
1385 << s.globals.size() << " global(s) "
1386 << getmemusage()
5ee1c56b
FCE
1387 << TIMESPRINT
1388 << endl;
0d49d7bc 1389
708ce1f3 1390 if (rc && !s.listing_mode)
377b8831 1391 cerr << "Pass 2: analysis failed. "
c3157bcd 1392 << "Try again with another '--vp 01' option."
2cfb0e46 1393 << endl;
6b067d7d
JS
1394
1395 /* Print out list of missing files. XXX should be "if (rc)" ? */
1396 missing_rpm_list_print(s);
1397
1398 STAP_PROBE1(stap, pass2__end, &s);
1399
1400 if (rc || s.listing_mode || s.last_pass == 2 || pending_interrupts) goto cleanup;
1401
1b78aef5
DS
1402 // Generate hash. There isn't any point in generating the hash
1403 // if last_pass is 2, since we'll quit before using it.
6b067d7d 1404 if (s.use_script_cache)
1b78aef5
DS
1405 {
1406 ostringstream o;
1407 unsigned saved_verbose;
1b78aef5 1408
9abec538
FCE
1409 {
1410 // Make sure we're in verbose mode, so that printscript()
1411 // will output function/probe bodies.
1412 saved_verbose = s.verbose;
1413 s.verbose = 3;
1414 printscript(s, o); // Print script to 'o'
1415 s.verbose = saved_verbose;
1416 }
1b78aef5
DS
1417
1418 // Generate hash
9b3c54b2 1419 find_script_hash (s, o.str());
1b78aef5
DS
1420
1421 // See if we can use cached source/module.
9b3c54b2 1422 if (get_script_from_cache(s))
1b78aef5 1423 {
db3a383b
JK
1424 // If our last pass isn't 5, we're done (since passes 3 and
1425 // 4 just generate what we just pulled out of the cache).
49abf162 1426 if (s.last_pass < 5 || pending_interrupts) goto cleanup;
1b78aef5 1427
db3a383b
JK
1428 // Short-circuit to pass 5.
1429 goto pass_5;
1b78aef5
DS
1430 }
1431 }
377b8831 1432
2b066ec1 1433 // PASS 3: TRANSLATION
e0b4e89d 1434 s.verbose = s.perpass_verbose[2];
5ee1c56b 1435 times (& tms_before);
1d738eed 1436 gettimeofday (&tv_before, NULL);
ce91eebd 1437 STAP_PROBE1(stap, pass3__start, &s);
1d738eed 1438
0d49d7bc 1439 rc = translate_pass (s);
f4b28491
FCE
1440
1441 if (rc == 0 && s.last_pass == 3)
1442 {
1443 ifstream i (s.translated_source.c_str());
1444 cout << i.rdbuf();
1445 }
0d49d7bc 1446
5ee1c56b 1447 times (& tms_after);
1d738eed 1448 gettimeofday (&tv_after, NULL);
5ee1c56b 1449
0d49d7bc
FCE
1450 if (s.verbose) clog << "Pass 3: translated to C into \""
1451 << s.translated_source
28b768e1
MW
1452 << "\" "
1453 << getmemusage()
5ee1c56b
FCE
1454 << TIMESPRINT
1455 << endl;
0d49d7bc 1456
377b8831 1457 if (rc)
2cfb0e46 1458 cerr << "Pass 3: translation failed. "
c3157bcd 1459 << "Try again with another '--vp 001' option."
2cfb0e46 1460 << endl;
377b8831 1461
ce91eebd
KS
1462 STAP_PROBE1(stap, pass3__end, &s);
1463
49abf162 1464 if (rc || s.last_pass == 3 || pending_interrupts) goto cleanup;
d54d4661 1465
f4b28491 1466 // PASS 4: COMPILATION
e0b4e89d 1467 s.verbose = s.perpass_verbose[3];
5ee1c56b 1468 times (& tms_before);
1d738eed 1469 gettimeofday (&tv_before, NULL);
ce91eebd 1470 STAP_PROBE1(stap, pass4__start, &s);
9b3c54b2
JS
1471
1472 if (s.use_cache)
1473 {
1474 find_stapconf_hash(s);
1475 get_stapconf_from_cache(s);
1476 }
0d49d7bc 1477 rc = compile_pass (s);
9abec538
FCE
1478
1479 if (rc == 0 && s.last_pass == 4)
422dc4e1
FCE
1480 {
1481 cout << ((s.hash_path == "") ? (s.module_name + string(".ko")) : s.hash_path);
1482 cout << endl;
1483 }
9abec538 1484
5ee1c56b 1485 times (& tms_after);
1d738eed 1486 gettimeofday (&tv_after, NULL);
5ee1c56b
FCE
1487
1488 if (s.verbose) clog << "Pass 4: compiled C into \""
1489 << s.module_name << ".ko"
28b768e1 1490 << "\" "
5ee1c56b
FCE
1491 << TIMESPRINT
1492 << endl;
f4b28491 1493
eaf134e7
FCE
1494 if (rc)
1495 cerr << "Pass 4: compilation failed. "
c3157bcd 1496 << "Try again with another '--vp 0001' option."
2cfb0e46 1497 << endl;
fc52ef5b 1498 else
1b78aef5 1499 {
72bfb1fd 1500 // Update cache. Cache cleaning is kicked off at the beginning of this function.
63d530ab 1501 if (s.use_script_cache)
9b3c54b2
JS
1502 add_script_to_cache(s);
1503 if (s.use_cache)
1504 add_stapconf_to_cache(s);
fc52ef5b 1505
f4d5049b
FCE
1506 // We may need to save the module in $CWD if the cache was
1507 // inaccessible for some reason.
63d530ab 1508 if (! s.use_script_cache && s.last_pass == 4)
f4d5049b 1509 save_module = true;
e16dc041 1510
fc52ef5b 1511 // Copy module to the current directory.
49abf162 1512 if (save_module && !pending_interrupts)
fc52ef5b
DS
1513 {
1514 string module_src_path = s.tmpdir + "/" + s.module_name + ".ko";
1515 string module_dest_path = s.module_name + ".ko";
e16dc041 1516 copy_file(module_src_path, module_dest_path, s.verbose > 1);
fc52ef5b 1517 }
1b78aef5 1518 }
eaf134e7 1519
ce91eebd
KS
1520 STAP_PROBE1(stap, pass4__end, &s);
1521
49abf162 1522 if (rc || s.last_pass == 4 || pending_interrupts) goto cleanup;
f4b28491 1523
9abec538 1524
0d49d7bc 1525 // PASS 5: RUN
1b78aef5 1526pass_5:
e0b4e89d 1527 s.verbose = s.perpass_verbose[4];
5ee1c56b 1528 times (& tms_before);
1d738eed 1529 gettimeofday (&tv_before, NULL);
03d569d3
FCE
1530 // NB: this message is a judgement call. The other passes don't emit
1531 // a "hello, I'm starting" message, but then the others aren't interactive
1532 // and don't take an indefinite amount of time.
ce91eebd 1533 STAP_PROBE1(stap, pass5__start, &s);
03d569d3 1534 if (s.verbose) clog << "Pass 5: starting run." << endl;
0d49d7bc 1535 rc = run_pass (s);
5ee1c56b 1536 times (& tms_after);
1d738eed 1537 gettimeofday (&tv_after, NULL);
28b768e1 1538 if (s.verbose) clog << "Pass 5: run completed "
5ee1c56b
FCE
1539 << TIMESPRINT
1540 << endl;
f4b28491 1541
eaf134e7
FCE
1542 if (rc)
1543 cerr << "Pass 5: run failed. "
c3157bcd 1544 << "Try again with another '--vp 00001' option."
2cfb0e46 1545 << endl;
eaf134e7 1546
0d49d7bc 1547 // if (rc) goto cleanup;
2b066ec1 1548
ce91eebd
KS
1549 STAP_PROBE1(stap, pass5__end, &s);
1550
c31df222 1551 // PASS 6: cleaning up
0d49d7bc 1552 cleanup:
c3a3c0c9 1553
ce91eebd
KS
1554 STAP_PROBE1(stap, pass6__start, &s);
1555
c3a3c0c9 1556 // update the database information
49abf162 1557 if (!rc && s.tapset_compile_coverage && !pending_interrupts) {
1c0b94ef 1558#ifdef HAVE_LIBSQLITE3
c3a3c0c9 1559 update_coverage_db(s);
1c0b94ef
FCE
1560#else
1561 cerr << "Coverage database not available without libsqlite3" << endl;
1562#endif
c3a3c0c9
WC
1563 }
1564
f4b28491
FCE
1565 // Clean up temporary directory. Obviously, be careful with this.
1566 if (s.tmpdir == "")
1567 ; // do nothing
1568 else
1569 {
1570 if (s.keep_tmpdir)
cf4a6df8
FCE
1571 // NB: the format of this message needs to match the expectations
1572 // of stap-server-connect.c.
0d49d7bc 1573 clog << "Keeping temporary directory \"" << s.tmpdir << "\"" << endl;
f4b28491
FCE
1574 else
1575 {
3972b443
DS
1576 // Ignore signals while we're deleting the temporary directory.
1577 setup_signals (SIG_IGN);
1578
1579 // Remove the temporary directory.
ce3187ac 1580 string cleanupcmd = "rm -rf ";
f4b28491 1581 cleanupcmd += s.tmpdir;
36ef6d6a
FCE
1582
1583 (void) stap_system (s.verbose, cleanupcmd);
f4b28491
FCE
1584 }
1585 }
2b066ec1 1586
ce91eebd
KS
1587 STAP_PROBE1(stap, pass6__end, &s);
1588
49abf162 1589 return (rc||pending_interrupts) ? EXIT_FAILURE : EXIT_SUCCESS;
2b066ec1 1590}
73267b89 1591
6e683641
FCE
1592
1593/*
1594Perngrq sebz fzvyrlgnc.fit, rkcbegrq gb n 1484k1110 fzvyrlgnc.cat,
1595gurapr catgbcnz | cazfpnyr -jvqgu 160 |
1596cczqvgure -qvz 4 -erq 2 -terra 2 -oyhr 2 | cczgbnafv -2k4 | bq -i -j19 -g k1 |
1597phg -s2- -q' ' | frq -r 'f,^,\\k,' -r 'f, ,\\k,t' -r 'f,^,",' -r 'f,$,",'
1598*/
1599const char* morehelp =
1600"\x1b\x5b\x30\x6d\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1601"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1602"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1603"\x20\x20\x20\x60\x20\x20\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1604"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20"
1605"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1606"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1607"\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x1b\x5b"
1608"\x33\x33\x6d\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1609"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1610"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1611"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x20\x60"
1612"\x2e\x60\x1b\x5b\x33\x37\x6d\x20\x3a\x2c\x3a\x2e\x60\x20\x60\x20\x60\x20\x60"
1613"\x2c\x3b\x2c\x3a\x20\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d"
1614"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1615"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1616"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x1b\x5b\x33"
1617"\x33\x6d\x20\x60\x20\x60\x20\x3a\x27\x60\x1b\x5b\x33\x37\x6d\x20\x60\x60\x60"
1618"\x20\x20\x20\x60\x20\x60\x60\x60\x20\x1b\x5b\x33\x33\x6d\x60\x3a\x60\x20\x60"
1619"\x20\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1620"\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1621"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1622"\x20\x2e\x1b\x5b\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x20\x1b\x5b\x33"
1623"\x37\x6d\x20\x3a\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x2e\x1b\x5b\x33\x33"
1624"\x6d\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20"
1625"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x2e\x3a\x20\x20"
1626"\x20\x20\x20\x20\x20\x20\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1627"\x20\x20\x2e\x76\x53\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x1b\x5b"
1628"\x33\x31\x6d\x2b\x1b\x5b\x33\x33\x6d\x60\x20\x60\x20\x60\x20\x20\x20\x20\x1b"
1629"\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x33\x6d\x2b\x1b\x5b"
1630"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x2e\x1b\x5b\x33\x30\x6d\x24\x1b\x5b"
1631"\x33\x37\x6d\x3b\x1b\x5b\x33\x31\x6d\x7c\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1632"\x20\x60\x20\x60\x1b\x5b\x33\x31\x6d\x2c\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33"
1633"\x37\x6d\x53\x53\x3e\x2c\x2e\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x2e"
1634"\x3b\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x20\x20\x20\x20\x20\x20"
1635"\x20\x20\x20\x2e\x2e\x3a\x1b\x5b\x33\x30\x6d\x26\x46\x46\x46\x48\x46\x1b\x5b"
1636"\x33\x33\x6d\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x30\x6d\x4d\x4d"
1637"\x46\x1b\x5b\x33\x33\x6d\x20\x20\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x1b\x5b"
1638"\x33\x33\x6d\x20\x3a\x1b\x5b\x33\x30\x6d\x4d\x4d\x46\x1b\x5b\x33\x33\x6d\x20"
1639"\x20\x20\x60\x20\x60\x2e\x60\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x30\x6d\x46"
1640"\x46\x46\x24\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x0a\x20\x20\x20"
1641"\x20\x2e\x3c\x3a\x60\x20\x20\x20\x20\x2e\x3a\x2e\x3a\x2e\x2e\x3b\x27\x20\x20"
1642"\x20\x20\x20\x20\x2e\x60\x2e\x3a\x60\x60\x3c\x27\x1b\x5b\x33\x31\x6d\x3c\x27"
1643"\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x3c\x1b\x5b\x33"
1644"\x30\x6d\x26\x1b\x5b\x33\x31\x6d\x3f\x1b\x5b\x33\x33\x6d\x20\x1b\x5b\x33\x37"
1645"\x6d\x20\x1b\x5b\x33\x33\x6d\x20\x20\x20\x20\x20\x1b\x5b\x33\x37\x6d\x60\x1b"
1646"\x5b\x33\x30\x6d\x2a\x46\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x20\x60"
1647"\x20\x60\x20\x60\x20\x60\x20\x1b\x5b\x33\x31\x6d\x60\x3a\x1b\x5b\x33\x37\x6d"
1648"\x27\x3c\x1b\x5b\x33\x30\x6d\x23\x1b\x5b\x33\x37\x6d\x3c\x60\x3a\x20\x20\x20"
1649"\x0a\x20\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x20\x60\x3a\x2e\x2e\x2e\x2e\x3c"
1650"\x3c\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x60\x20\x20\x20\x60\x1b\x5b\x33"
1651"\x33\x6d\x3a\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x20"
1652"\x60\x20\x60\x20\x60\x20\x60\x1b\x5b\x33\x37\x6d\x20\x20\x1b\x5b\x33\x33\x6d"
1653"\x20\x60\x20\x20\x20\x60\x1b\x5b\x33\x37\x6d\x20\x60\x20\x60\x1b\x5b\x33\x33"
1654"\x6d\x20\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1655"\x20\x60\x3a\x2e\x60\x2e\x20\x0a\x20\x20\x20\x60\x3a\x60\x3a\x60\x20\x20\x20"
1656"\x20\x20\x60\x60\x60\x60\x20\x3a\x2d\x20\x20\x20\x20\x20\x60\x20\x60\x20\x20"
1657"\x20\x20\x20\x60\x1b\x5b\x33\x33\x6d\x3a\x60\x2e\x60\x20\x60\x20\x60\x20\x60"
1658"\x20\x60\x20\x20\x2e\x3b\x1b\x5b\x33\x31\x6d\x76\x1b\x5b\x33\x30\x6d\x24\x24"
1659"\x24\x1b\x5b\x33\x31\x6d\x2b\x53\x1b\x5b\x33\x33\x6d\x2c\x60\x20\x60\x20\x60"
1660"\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x31\x6d\x60\x1b\x5b\x33\x33\x6d\x3a"
1661"\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x2e\x60\x20\x20\x0a\x20\x20\x20\x60"
1662"\x3a\x3a\x3a\x3a\x20\x20\x20\x20\x3a\x60\x60\x60\x60\x3a\x53\x20\x20\x20\x20"
1663"\x20\x20\x3a\x2e\x60\x2e\x20\x20\x20\x20\x20\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1664"\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20\x60"
1665"\x20\x3a\x1b\x5b\x33\x30\x6d\x24\x46\x46\x48\x46\x46\x46\x46\x46\x1b\x5b\x33"
1666"\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2e"
1667"\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x20\x20"
1668"\x20\x2e\x60\x2e\x3a\x20\x20\x0a\x20\x20\x20\x60\x3a\x3a\x3a\x60\x20\x20\x20"
1669"\x60\x3a\x20\x2e\x20\x3b\x27\x3a\x20\x20\x20\x20\x20\x20\x3a\x2e\x60\x3a\x20"
1670"\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x60\x1b"
1671"\x5b\x33\x33\x6d\x2e\x60\x20\x60\x20\x60\x20\x60\x2e\x1b\x5b\x33\x30\x6d\x53"
1672"\x46\x46\x46\x53\x46\x46\x46\x53\x46\x46\x1b\x5b\x33\x33\x6d\x20\x60\x20\x60"
1673"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x20"
1674"\x20\x20\x20\x3a\x60\x3a\x60\x20\x20\x0a\x20\x20\x20\x20\x60\x3c\x3b\x3c\x20"
1675"\x20\x20\x20\x20\x60\x60\x60\x20\x3a\x3a\x20\x20\x20\x20\x20\x20\x20\x3a\x3a"
1676"\x2e\x60\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d"
1677"\x3c\x3a\x60\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x60\x3a\x1b\x5b\x33\x30"
1678"\x6d\x53\x46\x53\x46\x46\x46\x53\x46\x46\x46\x53\x1b\x5b\x33\x33\x6d\x2e\x60"
1679"\x20\x60\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b"
1680"\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x3a\x3a\x60\x20\x20\x20\x0a\x20\x20"
1681"\x20\x20\x20\x60\x3b\x3c\x20\x20\x20\x20\x20\x20\x20\x3a\x3b\x60\x20\x20\x20"
1682"\x20\x20\x20\x20\x20\x20\x60\x3a\x60\x2e\x20\x20\x20\x20\x20\x3a\x1b\x5b\x33"
1683"\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33"
1684"\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x2e\x60\x2e\x60\x20\x1b\x5b\x33\x31\x6d\x3a"
1685"\x1b\x5b\x33\x30\x6d\x46\x53\x46\x53\x46\x53\x46\x53\x46\x1b\x5b\x33\x31\x6d"
1686"\x3f\x1b\x5b\x33\x33\x6d\x20\x60\x2e\x60\x2e\x3a\x3a\x1b\x5b\x33\x31\x6d\x3c"
1687"\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x37\x6d\x60\x20"
1688"\x20\x20\x3a\x3a\x3a\x60\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x53\x3c"
1689"\x20\x20\x20\x20\x20\x20\x3a\x53\x3a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1690"\x20\x60\x3a\x3a\x60\x2e\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1691"\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a"
1692"\x60\x2e\x60\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x53\x24\x53\x46\x53\x24\x1b\x5b"
1693"\x33\x33\x6d\x60\x3a\x1b\x5b\x33\x31\x6d\x3a\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b"
1694"\x33\x31\x6d\x3a\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b"
1695"\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x2e\x60\x3a\x3a\x60\x20"
1696"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x3b\x3c\x2e\x2e\x2c\x2e\x2e\x20"
1697"\x3a\x3c\x3b\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a"
1698"\x60\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31"
1699"\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33"
1700"\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x3c\x3c\x1b\x5b\x33\x30\x6d\x53\x24\x53\x1b"
1701"\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x37\x6d\x27\x1b\x5b\x33\x33\x6d\x2e\x3a\x3b"
1702"\x1b\x5b\x33\x31\x6d\x3c\x3b\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x31\x6d"
1703"\x3c\x1b\x5b\x33\x33\x6d\x3a\x1b\x5b\x33\x37\x6d\x60\x20\x20\x20\x60\x2e\x3a"
1704"\x3a\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x2e\x3a\x3a\x3c\x53\x3c\x3a\x60"
1705"\x3a\x3a\x3a\x3a\x53\x1b\x5b\x33\x32\x6d\x53\x1b\x5b\x33\x37\x6d\x3b\x27\x3a"
1706"\x3c\x2c\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x3a\x3a\x3a\x2e\x60"
1707"\x2e\x60\x2e\x60\x3a\x1b\x5b\x33\x33\x6d\x3c\x3a\x1b\x5b\x33\x31\x6d\x3c\x1b"
1708"\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b"
1709"\x33\x31\x6d\x3c\x2c\x1b\x5b\x33\x33\x6d\x3c\x3b\x3a\x1b\x5b\x33\x31\x6d\x2c"
1710"\x1b\x5b\x33\x33\x6d\x3c\x3b\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x53"
1711"\x1b\x5b\x33\x31\x6d\x3c\x1b\x5b\x33\x33\x6d\x3b\x3c\x1b\x5b\x33\x37\x6d\x3a"
1712"\x60\x2e\x60\x2e\x3b\x1b\x5b\x33\x34\x6d\x53\x1b\x5b\x33\x37\x6d\x53\x3f\x27"
1713"\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x3a\x3c\x53\x53\x3b\x3c"
1714"\x3a\x60\x3a\x3a\x53\x53\x53\x3c\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x1b\x5b"
1715"\x33\x37\x6d\x2b\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x3a\x1b\x5b\x33\x34"
1716"\x6d\x53\x1b\x5b\x33\x30\x6d\x53\x46\x24\x1b\x5b\x33\x37\x6d\x2c\x60\x3a\x3a"
1717"\x3a\x3c\x3a\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33"
1718"\x33\x6d\x53\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31"
1719"\x6d\x53\x3b\x53\x1b\x5b\x33\x33\x6d\x3b\x1b\x5b\x33\x31\x6d\x53\x1b\x5b\x33"
1720"\x33\x6d\x53\x1b\x5b\x33\x37\x6d\x3c\x1b\x5b\x33\x33\x6d\x53\x1b\x5b\x33\x37"
1721"\x6d\x3c\x53\x3c\x3a\x3a\x3a\x3a\x3f\x1b\x5b\x33\x30\x6d\x53\x24\x48\x1b\x5b"
1722"\x33\x37\x6d\x27\x60\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x2e\x60\x3a\x60\x2e"
1723"\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x2e\x1b\x5b\x33"
1724"\x30\x6d\x53\x46\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20"
1725"\x60\x3a\x1b\x5b\x33\x30\x6d\x3c\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60"
1726"\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3c\x3a\x60\x3a\x27\x3a\x60\x3a\x60\x3a"
1727"\x60\x3a\x60\x3b\x1b\x5b\x33\x30\x6d\x53\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27"
1728"\x20\x60\x20\x60\x20\x60\x20\x20\x20\x20\x0a\x20\x3c\x3b\x3a\x2e\x60\x20\x60"
1729"\x2e\x60\x20\x60\x2e\x60\x20\x60\x2e\x60\x2c\x53\x1b\x5b\x33\x32\x6d\x53\x1b"
1730"\x5b\x33\x30\x6d\x53\x1b\x5b\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1731"\x20\x20\x60\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x46\x46\x1b\x5b\x33\x34\x6d"
1732"\x2b\x1b\x5b\x33\x37\x6d\x3a\x20\x60\x20\x60\x20\x60\x2e\x60\x20\x60\x2e\x60"
1733"\x20\x60\x2e\x60\x20\x60\x20\x60\x2c\x1b\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b"
1734"\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x0a\x20"
1735"\x60\x3a\x1b\x5b\x33\x30\x6d\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3b\x3c"
1736"\x2c\x60\x2c\x3b\x3b\x53\x3f\x53\x1b\x5b\x33\x30\x6d\x24\x46\x3c\x1b\x5b\x33"
1737"\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x60"
1738"\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x3f\x2e\x60\x20"
1739"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x3b\x76\x1b\x5b\x33\x30\x6d"
1740"\x48\x46\x48\x46\x1b\x5b\x33\x37\x6d\x27\x20\x60\x20\x20\x20\x60\x20\x20\x20"
1741"\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x46\x24\x1b"
1742"\x5b\x33\x37\x6d\x53\x53\x53\x53\x53\x53\x1b\x5b\x33\x30\x6d\x53\x24\x53\x46"
1743"\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1744"\x20\x20\x20\x20\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x23\x46\x46\x46"
1745"\x24\x1b\x5b\x33\x37\x6d\x76\x2c\x2c\x20\x2e\x20\x2e\x20\x2c\x2c\x76\x1b\x5b"
1746"\x33\x30\x6d\x26\x24\x46\x46\x48\x3c\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x20"
1747"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x60"
1748"\x3c\x1b\x5b\x33\x30\x6d\x53\x46\x46\x24\x46\x24\x46\x46\x48\x46\x53\x1b\x5b"
1749"\x33\x37\x6d\x20\x20\x20\x20\x20\x20\x20\x20\x2e\x60\x20\x60\x2e\x60\x2e\x60"
1750"\x2e\x60\x2e\x60\x3a\x3a\x3a\x3a\x3a\x1b\x5b\x33\x30\x6d\x2a\x46\x46\x46\x48"
1751"\x46\x48\x46\x48\x46\x46\x46\x48\x46\x48\x46\x48\x1b\x5b\x33\x37\x6d\x3c\x22"
1752"\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x2e\x60\x20\x20\x20\x20\x20\x20\x20\x20\x0a"
1753"\x20\x20\x20\x20\x20\x20\x20\x60\x3a\x1b\x5b\x33\x30\x6d\x48\x46\x46\x46\x48"
1754"\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x20\x20\x20\x60\x20\x60\x2e\x60\x20\x60"
1755"\x2e\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x3a\x3a\x60\x3a\x3c\x3c"
1756"\x1b\x5b\x33\x30\x6d\x3c\x46\x48\x46\x46\x46\x48\x46\x46\x46\x1b\x5b\x33\x37"
1757"\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1758"\x60\x20\x60\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b"
1759"\x33\x30\x6d\x2a\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x20\x20\x60\x20\x60"
1760"\x2e\x60\x20\x60\x2e\x60\x2e\x60\x3a\x60\x2e\x60\x3a\x60\x3a\x60\x3a\x60\x3a"
1761"\x60\x3a\x60\x3a\x60\x3a\x60\x3a\x1b\x5b\x33\x30\x6d\x46\x46\x48\x46\x48\x46"
1762"\x1b\x5b\x33\x37\x6d\x27\x3a\x60\x3a\x60\x3a\x60\x3a\x60\x2e\x60\x3a\x60\x2e"
1763"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x20\x60\x0a\x20\x20\x20\x20\x20\x20\x20"
1764"\x20\x20\x20\x20\x60\x3c\x1b\x5b\x33\x30\x6d\x48\x46\x46\x1b\x5b\x33\x37\x6d"
1765"\x2b\x60\x20\x20\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2e\x60\x20"
1766"\x60\x2e\x60\x20\x60\x2e\x60\x20\x60\x3a\x60\x2e\x60\x3b\x1b\x5b\x33\x30\x6d"
1767"\x48\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x2e\x60\x2e\x60\x20\x60\x2e\x60\x20"
1768"\x60\x2e\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60\x20\x20\x0a\x20"
1769"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x22\x1b\x5b\x33\x30\x6d\x3c"
1770"\x48\x46\x53\x1b\x5b\x33\x37\x6d\x2b\x3a\x20\x20\x20\x60\x20\x60\x20\x60\x20"
1771"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x2c\x1b"
1772"\x5b\x33\x30\x6d\x24\x46\x48\x46\x1b\x5b\x33\x37\x6d\x3f\x20\x60\x20\x60\x20"
1773"\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x60\x20\x20\x20\x60"
1774"\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1775"\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x48\x24\x46\x46\x1b\x5b\x33\x37\x6d\x3e\x2c"
1776"\x2e\x2e\x20\x20\x20\x20\x20\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x3b"
1777"\x2c\x2c\x1b\x5b\x33\x30\x6d\x24\x53\x46\x46\x46\x1b\x5b\x33\x37\x6d\x27\x22"
1778"\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x60\x20\x20\x20\x20\x20\x20\x20\x20"
1779"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20\x20\x20\x20\x20\x20\x20"
1780"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x60\x22\x1b\x5b\x33\x30\x6d\x2a\x3c\x48"
1781"\x46\x46\x24\x53\x24\x1b\x5b\x33\x37\x6d\x53\x53\x53\x3e\x3e\x3e\x3e\x3e\x53"
1782"\x3e\x53\x1b\x5b\x33\x30\x6d\x24\x53\x24\x46\x24\x48\x46\x23\x1b\x5b\x33\x37"
1783"\x6d\x27\x22\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1784"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x20\x20"
1785"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1786"\x60\x60\x22\x3c\x1b\x5b\x33\x30\x6d\x2a\x3c\x3c\x3c\x48\x46\x46\x46\x48\x46"
1787"\x46\x46\x23\x3c\x1b\x5b\x33\x36\x6d\x3c\x1b\x5b\x33\x37\x6d\x3c\x27\x22\x22"
1788"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20"
1789"\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x20\x0a\x1b"
1790 "\x5b\x30\x6d";
1791
1792
73267b89 1793/* vim: set sw=2 ts=8 cino=>4,n-2,{2,^-2,t0,(0,u0,w1,M1 : */
6861e056 1794
This page took 0.32322 seconds and 5 git commands to generate.