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