]> sourceware.org Git - systemtap.git/blame - main.cxx
bugfix for #3526:
[systemtap.git] / main.cxx
CommitLineData
f4b28491 1// systemtap translator/driver
213bee8f 2// Copyright (C) 2005-2006 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"
2b066ec1
FCE
21
22#include <iostream>
23#include <fstream>
24#include <sstream>
f4b28491 25#include <cerrno>
24cb178f 26#include <cstdlib>
2b066ec1
FCE
27
28extern "C" {
29#include <glob.h>
30#include <unistd.h>
f4b28491 31#include <sys/utsname.h>
5ee1c56b 32#include <sys/times.h>
1d738eed 33#include <sys/time.h>
f4b28491 34#include <time.h>
f8949662 35#include <elfutils/libdwfl.h>
2b066ec1
FCE
36}
37
38using namespace std;
39
40
f4b28491 41void
c0de7a8d 42version ()
2b066ec1 43{
d54d4661 44 clog
d04cf5ff 45 << "SystemTap translator/driver "
f4b28491 46 << "(version " << VERSION << " built " << DATE << ")" << endl
f8949662 47 << "(Using " << dwfl_version (NULL) << " libraries.)" << endl
b9b91512 48 << "Copyright (C) 2005-2006 Red Hat, Inc. and others" << endl
f8949662 49 << "This is free software; see the source for copying conditions." << endl;
c0de7a8d
FCE
50}
51
52void
277c1957 53usage (systemtap_session& s, int exitcode)
c0de7a8d
FCE
54{
55 version ();
56 clog
f4b28491 57 << endl
b2d5d95c 58 << "Usage: stap [options] FILE Run script in file."
f4b28491 59 << endl
b2d5d95c 60 << " or: stap [options] - Run script on stdin."
f4b28491 61 << endl
d54d4661 62 << " or: stap [options] -e SCRIPT Run given script."
f4b28491
FCE
63 << endl
64 << endl
c0de7a8d 65 << "Options:" << endl
f4b28491 66 << " -- no more options after this" << endl
b0ee93c4 67 << " -v increase verbosity [" << s.verbose << "]" << endl
c0de7a8d
FCE
68 << " -h show help" << endl
69 << " -V show version" << endl
d5d7c2cc 70 << " -k keep temporary directory" << endl
cbfbbf69 71 << " -u unoptimized translation" << (s.unoptimized ? " [set]" : "") << endl
377b8831 72 << " -g guru mode" << (s.guru_mode ? " [set]" : "") << endl
f12b2552 73 << " -b bulk (relayfs) mode" << (s.bulk_mode ? " [set]" : "") << endl
f272aacc 74 << " -M Don't merge per-cpu files for bulk (relayfs) mode" << (s.merge ? "" : " [set]") << endl
177a8ead
FCE
75 << " -s NUM buffer size in megabytes, instead of "
76 << s.buffer_size << endl
f8949662 77 << " -p NUM stop after pass NUM 1-5, instead of "
177a8ead 78 << s.last_pass << endl
f4b28491
FCE
79 << " (parse, elaborate, translate, compile, run)" << endl
80 << " -I DIR look in DIR for additional .stp script files";
81 if (s.include_path.size() == 0)
0d49d7bc 82 clog << endl;
f4b28491 83 else
24cb178f 84 clog << ", in addition to" << endl;
f4b28491 85 for (unsigned i=0; i<s.include_path.size(); i++)
0d49d7bc
FCE
86 clog << " " << s.include_path[i] << endl;
87 clog
ed10c639 88 << " -D NM=VAL emit macro definition into generated C code" << endl
24cb178f
FCE
89 << " -R DIR look in DIR for runtime, instead of" << endl
90 << " " << s.runtime_path << endl
177a8ead
FCE
91 << " -r RELEASE use kernel RELEASE, instead of "
92 << s.kernel_release << endl
f12b2552
FCE
93 << " -m MODULE set probe module name, instead of "
94 << s.module_name << endl
177a8ead 95 << " -o FILE send output to file, instead of stdout" << endl
f8949662 96 << " -c CMD start the probes, run CMD, and exit when it finishes"
f12b2552 97 << endl
4c5ff1bb 98 << " -x PID sets target() to PID" << endl
4b17d6af 99 << " -t benchmarking timing information generated" << endl
d5d7c2cc 100 ;
d54d4661 101 // -d: dump safety-related external references
2b066ec1 102
277c1957 103 exit (exitcode);
2b066ec1
FCE
104}
105
106
1b78aef5
DS
107static void
108printscript(systemtap_session& s, ostream& o)
109{
110 if (s.globals.size() > 0)
111 o << "# globals" << endl;
112 for (unsigned i=0; i<s.globals.size(); i++)
113 {
114 vardecl* v = s.globals[i];
115 v->printsig (o);
116 o << endl;
117 }
118
119 if (s.functions.size() > 0)
120 o << "# functions" << endl;
121 for (unsigned i=0; i<s.functions.size(); i++)
122 {
123 functiondecl* f = s.functions[i];
124 f->printsig (o);
125 o << endl;
126 if (f->locals.size() > 0)
127 o << " # locals" << endl;
128 for (unsigned j=0; j<f->locals.size(); j++)
129 {
130 vardecl* v = f->locals[j];
131 o << " ";
132 v->printsig (o);
133 o << endl;
134 }
135 if (s.verbose)
136 {
137 f->body->print (o);
138 o << endl;
139 }
140 }
141
142 if (s.probes.size() > 0)
143 o << "# probes" << endl;
144 for (unsigned i=0; i<s.probes.size(); i++)
145 {
146 derived_probe* p = s.probes[i];
147 p->printsig (o);
148 o << endl;
149 if (p->locals.size() > 0)
150 o << " # locals" << endl;
151 for (unsigned j=0; j<p->locals.size(); j++)
152 {
153 vardecl* v = p->locals[j];
154 o << " ";
155 v->printsig (o);
156 o << endl;
157 }
158 if (s.verbose)
159 {
160 p->body->print (o);
161 o << endl;
162 }
163 }
164}
165
2b066ec1
FCE
166int
167main (int argc, char * const argv [])
168{
2b066ec1
FCE
169 string cmdline_script; // -e PROGRAM
170 string script_file; // FILE
171 bool have_script = false;
ea3f75ae 172 bool release_changed = false;
f4b28491
FCE
173
174 // Initialize defaults
175 systemtap_session s;
176 struct utsname buf;
177 (void) uname (& buf);
178 s.kernel_release = string (buf.release);
44ce8ed5 179 s.architecture = string (buf.machine);
b0ee93c4 180 s.verbose = 0;
4b17d6af 181 s.timing = 0;
377b8831 182 s.guru_mode = false;
16d8de1b 183 s.bulk_mode = false;
cbfbbf69 184 s.unoptimized = false;
16d8de1b 185 s.buffer_size = 0;
f4b28491 186 s.last_pass = 5;
ae24723e 187 s.module_name = "stap_" + stringify(getpid());
08c68653 188 s.output_file = ""; // -o FILE
f4b28491 189 s.keep_tmpdir = false;
4c5ff1bb
MH
190 s.cmd = "";
191 s.target_pid = 0;
f272aacc 192 s.merge=true;
47dd066d 193 s.perfmon=0;
f1bad60c 194 s.symtab = false;
1b78aef5 195 s.use_cache = true;
24cb178f
FCE
196
197 const char* s_p = getenv ("SYSTEMTAP_TAPSET");
ec819dc3
LG
198 if (s_p != NULL)
199 {
24cb178f 200 s.include_path.push_back (s_p);
ec819dc3
LG
201 s.include_path.push_back (string(s_p) + "/LKET");
202 }
24cb178f 203 else
ec819dc3 204 {
24cb178f 205 s.include_path.push_back (string(PKGDATADIR) + "/tapset");
ec819dc3
LG
206 s.include_path.push_back (string(PKGDATADIR) + "/tapset/LKET");
207 }
24cb178f
FCE
208
209 const char* s_r = getenv ("SYSTEMTAP_RUNTIME");
210 if (s_r != NULL)
211 s.runtime_path = s_r;
212 else
213 s.runtime_path = string(PKGDATADIR) + "/runtime";
f4b28491 214
1b78aef5
DS
215 const char* s_d = getenv ("SYSTEMTAP_DIR");
216 if (s_d != NULL)
217 s.data_path = s_d;
218 else
219 s.data_path = get_home_directory() + string("/.systemtap");
220 if (create_dir(s.data_path.c_str()) == 1)
221 {
222 const char* e = strerror (errno);
223 cerr << "Warning: failed to create systemtap data directory (\""
224 << s.data_path << "\"): " << e << endl;
225 cerr << "Disabling cache support." << endl;
226 s.use_cache = false;
227 }
228
229 if (s.use_cache)
230 {
231 s.cache_path = s.data_path + "/cache";
232 if (create_dir(s.cache_path.c_str()) == 1)
233 {
234 const char* e = strerror (errno);
235 cerr << "Warning: failed to create cache directory (\""
236 << s.cache_path << "\"): " << e << endl;
237 cerr << "Disabling cache support." << endl;
238 s.use_cache = false;
239 }
240 }
241
2b066ec1
FCE
242 while (true)
243 {
f272aacc 244 int grc = getopt (argc, argv, "hVMvtp:I:e:o:R:r:m:kgc:x:D:bs:u");
2b066ec1
FCE
245 if (grc < 0)
246 break;
247 switch (grc)
248 {
c0de7a8d
FCE
249 case 'V':
250 version ();
251 exit (0);
252
f272aacc
LG
253 case 'M':
254 s.merge = false;
255 break;
256
bd2b1e68 257 case 'v':
b0ee93c4 258 s.verbose ++;
bd2b1e68
GH
259 break;
260
4b17d6af
WC
261 case 't':
262 s.timing ++;
263 break;
264
2b066ec1 265 case 'p':
f4b28491
FCE
266 s.last_pass = atoi (optarg);
267 if (s.last_pass < 1 || s.last_pass > 5)
2b066ec1 268 {
277c1957
DS
269 cerr << "Invalid pass number (should be 1-5)." << endl;
270 usage (s, 1);
2b066ec1
FCE
271 }
272 break;
273
274 case 'I':
f4b28491 275 s.include_path.push_back (string (optarg));
2b066ec1
FCE
276 break;
277
278 case 'e':
279 if (have_script)
277c1957
DS
280 {
281 cerr << "Only one script can be given on the command line."
282 << endl;
283 usage (s, 1);
284 }
2b066ec1
FCE
285 cmdline_script = string (optarg);
286 have_script = true;
287 break;
288
289 case 'o':
08c68653 290 s.output_file = string (optarg);
2b066ec1
FCE
291 break;
292
f4b28491
FCE
293 case 'R':
294 s.runtime_path = string (optarg);
295 break;
296
297 case 'm':
298 s.module_name = string (optarg);
1b78aef5
DS
299 cerr << "Warning: using '-m' disables cache support." << endl;
300 s.use_cache = false;
f4b28491
FCE
301 break;
302
303 case 'r':
304 s.kernel_release = string (optarg);
ea3f75ae 305 release_changed = true;
f4b28491
FCE
306 break;
307
308 case 'k':
309 s.keep_tmpdir = true;
310 break;
311
377b8831
FCE
312 case 'g':
313 s.guru_mode = true;
314 break;
315
16d8de1b
TZ
316 case 'b':
317 s.bulk_mode = true;
16d8de1b
TZ
318 break;
319
cbfbbf69
FCE
320 case 'u':
321 s.unoptimized = true;
322 break;
323
16d8de1b
TZ
324 case 's':
325 s.buffer_size = atoi (optarg);
326 if (s.buffer_size < 1 || s.buffer_size > 64)
327 {
277c1957
DS
328 cerr << "Invalid buffer size (should be 1-64)." << endl;
329 usage (s, 1);
16d8de1b
TZ
330 }
331 break;
332
4c5ff1bb
MH
333 case 'c':
334 s.cmd = string (optarg);
335 break;
336
337 case 'x':
338 s.target_pid = atoi(optarg);
339 break;
340
ed10c639
FCE
341 case 'D':
342 s.macros.push_back (string (optarg));
343 break;
344
2b066ec1 345 case 'h':
277c1957
DS
346 usage (s, 0);
347 break;
348
2b066ec1 349 default:
277c1957
DS
350 usage (s, 1);
351 break;
2b066ec1
FCE
352 }
353 }
354
f272aacc
LG
355 if(!s.bulk_mode && !s.merge)
356 {
357 cerr << "-M option is valid only for bulk (relayfs) mode." <<endl;
277c1957 358 usage (s, 1);
f272aacc
LG
359 }
360
361 if(!s.output_file.empty() && s.bulk_mode && !s.merge)
362 {
363 cerr << "You can't specify -M, -b and -o options together." <<endl;
277c1957 364 usage (s, 1);
f272aacc
LG
365 }
366
ea3f75ae
DS
367 if (s.last_pass > 4 && release_changed)
368 {
369 cerr << ("Warning: changing last pass to 4 since the kernel release"
370 " has changed.") << endl;
371 s.last_pass = 4;
372 }
373
2b066ec1
FCE
374 for (int i = optind; i < argc; i++)
375 {
376 if (! have_script)
377 {
378 script_file = string (argv[i]);
379 have_script = true;
380 }
381 else
f4b28491 382 s.args.push_back (string (argv[i]));
2b066ec1
FCE
383 }
384
385 // need a user file
386 if (! have_script)
277c1957
DS
387 {
388 cerr << "A script must be specified." << endl;
389 usage(s, 1);
390 }
f4b28491
FCE
391
392 int rc = 0;
2b066ec1 393
ce3187ac 394 // override PATH and LC_ALL
c72dc86c
JS
395 const char *path = "/bin:/sbin:/usr/bin:/usr/sbin";
396 rc = setenv("PATH", path, 1) || setenv("LC_ALL", "C", 1);
ce3187ac
FCE
397 if (rc)
398 {
399 const char* e = strerror (errno);
c72dc86c 400 cerr << "setenv (\"PATH=" << path << "\" + \"LC_ALL=C\"): "
ce3187ac
FCE
401 << e << endl;
402 }
f8949662 403
197a4d62
JS
404 s.kernel_base_release.assign(s.kernel_release, 0, s.kernel_release.find('-'));
405
ce3187ac 406
2b066ec1
FCE
407 // arguments parsed; get down to business
408
f4b28491
FCE
409 // Create a temporary directory to build within.
410 // Be careful with this, as "s.tmpdir" is "rm -rf"'d at the end.
411 {
c72dc86c 412 const char* tmpdir_env = getenv("TMPDIR");
ea8ea02c
FCE
413 if (! tmpdir_env)
414 tmpdir_env = "/tmp";
415
416 string stapdir = "/stapXXXXXX";
417 string tmpdirt = tmpdir_env + stapdir;
418 const char* tmpdir = mkdtemp((char *)tmpdirt.c_str());
f4b28491
FCE
419 if (! tmpdir)
420 {
421 const char* e = strerror (errno);
ea8ea02c
FCE
422 cerr << "ERROR: cannot create temporary directory (\"" << tmpdirt << "\"): " << e << endl;
423 exit (1); // die
f4b28491
FCE
424 }
425 else
426 s.tmpdir = tmpdir;
0d49d7bc 427
b0ee93c4 428 if (s.verbose>1)
0d49d7bc 429 clog << "Created temporary directory \"" << s.tmpdir << "\"" << endl;
f4b28491 430 }
2b066ec1 431
1b78aef5
DS
432 // Create the name of the C source file within the temporary
433 // directory.
434 s.translated_source = string(s.tmpdir) + "/" + s.module_name + ".c";
435
5ee1c56b
FCE
436 struct tms tms_before;
437 times (& tms_before);
1d738eed
FCE
438 struct timeval tv_before;
439 gettimeofday (&tv_before, NULL);
2b066ec1
FCE
440
441 // PASS 1a: PARSING USER SCRIPT
442 // XXX: pass args vector, so parser (or lexer?) can substitute
443 // $1..$NN with actual arguments
69c68955 444 if (script_file == "-")
177a8ead 445 s.user_file = parser::parse (s, cin, s.guru_mode);
69c68955 446 else if (script_file != "")
177a8ead 447 s.user_file = parser::parse (s, script_file, s.guru_mode);
2b066ec1
FCE
448 else
449 {
450 istringstream ii (cmdline_script);
177a8ead 451 s.user_file = parser::parse (s, ii, s.guru_mode);
2b066ec1
FCE
452 }
453 if (s.user_file == 0)
454 // syntax errors already printed
455 rc ++;
377b8831 456
5519d363 457 // Construct arch / kernel-versioning search path
377b8831 458 vector<string> version_suffixes;
6f9f33e2 459 string kvr = s.kernel_release;
5519d363
KS
460 const string& arch = s.architecture;
461 // add full kernel-version-release (2.6.NN-FOOBAR) + arch
462 version_suffixes.push_back ("/" + kvr + "/" + arch);
377b8831 463 version_suffixes.push_back ("/" + kvr);
5519d363 464 // add kernel version (2.6.NN) + arch
197a4d62
JS
465 if (kvr != s.kernel_base_release) {
466 kvr = s.kernel_base_release;
6f9f33e2
JS
467 version_suffixes.push_back ("/" + kvr + "/" + arch);
468 version_suffixes.push_back ("/" + kvr);
5519d363
KS
469 }
470 // add kernel family (2.6) + arch
6f9f33e2
JS
471 string::size_type dot1_index = kvr.find ('.');
472 string::size_type dot2_index = kvr.rfind ('.');
473 while (dot2_index > dot1_index && dot2_index != string::npos) {
474 kvr.erase(dot2_index);
475 version_suffixes.push_back ("/" + kvr + "/" + arch);
476 version_suffixes.push_back ("/" + kvr);
477 dot2_index = kvr.rfind ('.');
5519d363
KS
478 }
479 // add architecture search path
480 version_suffixes.push_back("/" + arch);
377b8831
FCE
481 // add empty string as last element
482 version_suffixes.push_back ("");
2b066ec1
FCE
483
484 // PASS 1b: PARSING LIBRARY SCRIPTS
f4b28491 485 for (unsigned i=0; i<s.include_path.size(); i++)
2b066ec1 486 {
377b8831
FCE
487 // now iterate upon it
488 for (unsigned k=0; k<version_suffixes.size(); k++)
2b066ec1 489 {
377b8831
FCE
490 glob_t globbuf;
491 string dir = s.include_path[i] + version_suffixes[k] + "/*.stp";
492 int r = glob(dir.c_str (), 0, NULL, & globbuf);
493 if (r == GLOB_NOSPACE || r == GLOB_ABORTED)
2b066ec1 494 rc ++;
377b8831
FCE
495 // GLOB_NOMATCH is acceptable
496
b0ee93c4 497 if (s.verbose>1)
377b8831
FCE
498 clog << "Searched '" << dir << "', "
499 << "match count " << globbuf.gl_pathc << endl;
2b066ec1 500
377b8831
FCE
501 for (unsigned j=0; j<globbuf.gl_pathc; j++)
502 {
24cb178f 503 // privilege only for /usr/share/systemtap?
177a8ead 504 stapfile* f = parser::parse (s, globbuf.gl_pathv[j], true);
377b8831
FCE
505 if (f == 0)
506 rc ++;
507 else
24cb178f 508 s.library_files.push_back (f);
377b8831 509 }
d54d4661 510
377b8831
FCE
511 globfree (& globbuf);
512 }
2b066ec1
FCE
513 }
514
f4b28491 515 if (rc == 0 && s.last_pass == 1)
2b066ec1 516 {
f4b28491
FCE
517 cout << "# parse tree dump" << endl;
518 s.user_file->print (cout);
519 cout << endl;
ae56fddd
FCE
520 if (s.verbose)
521 for (unsigned i=0; i<s.library_files.size(); i++)
522 {
523 s.library_files[i]->print (cout);
524 cout << endl;
525 }
2b066ec1
FCE
526 }
527
5ee1c56b
FCE
528 struct tms tms_after;
529 times (& tms_after);
530 unsigned _sc_clk_tck = sysconf (_SC_CLK_TCK);
1d738eed
FCE
531 struct timeval tv_after;
532 gettimeofday (&tv_after, NULL);
5ee1c56b
FCE
533
534#define TIMESPRINT \
535 (tms_after.tms_cutime + tms_after.tms_utime \
1d738eed 536 - tms_before.tms_cutime - tms_before.tms_utime) * 1000 / (_sc_clk_tck) << "usr/" \
5ee1c56b 537 << (tms_after.tms_cstime + tms_after.tms_stime \
1d738eed
FCE
538 - tms_before.tms_cstime - tms_before.tms_stime) * 1000 / (_sc_clk_tck) << "sys/" \
539 << ((tv_after.tv_sec - tv_before.tv_sec) * 1000 + \
540 ((long)tv_after.tv_usec - (long)tv_before.tv_usec) / 1000) << "real ms."
5ee1c56b 541
eaf134e7 542 // syntax errors, if any, are already printed
5ee1c56b
FCE
543 if (s.verbose)
544 {
545 clog << "Pass 1: parsed user script and "
546 << s.library_files.size()
547 << " library script(s) in "
548 << TIMESPRINT
549 << endl;
550 }
0d49d7bc 551
2cfb0e46
FCE
552 if (rc)
553 cerr << "Pass 1: parse failed. "
213bee8f 554 << "Try again with more '-v' (verbose) options."
2cfb0e46
FCE
555 << endl;
556
0d49d7bc 557 if (rc || s.last_pass == 1) goto cleanup;
f4b28491 558
5ee1c56b 559 times (& tms_before);
1d738eed 560 gettimeofday (&tv_before, NULL);
5ee1c56b 561
2b066ec1 562 // PASS 2: ELABORATION
0d49d7bc 563 rc = semantic_pass (s);
f4b28491
FCE
564
565 if (rc == 0 && s.last_pass == 2)
1b78aef5 566 printscript(s, cout);
2b066ec1 567
5ee1c56b 568 times (& tms_after);
1d738eed
FCE
569 gettimeofday (&tv_after, NULL);
570
b0ee93c4 571 if (s.verbose) clog << "Pass 2: analyzed script: "
0d49d7bc
FCE
572 << s.probes.size() << " probe(s), "
573 << s.functions.size() << " function(s), "
b20febf3 574 << s.embeds.size() << " embed(s), "
5ee1c56b
FCE
575 << s.globals.size() << " global(s) in "
576 << TIMESPRINT
577 << endl;
0d49d7bc 578
377b8831
FCE
579 if (rc)
580 cerr << "Pass 2: analysis failed. "
213bee8f 581 << "Try again with more '-v' (verbose) options."
2cfb0e46 582 << endl;
1b78aef5
DS
583 // Generate hash. There isn't any point in generating the hash
584 // if last_pass is 2, since we'll quit before using it.
585 else if (s.last_pass != 2 && s.use_cache)
586 {
587 ostringstream o;
588 unsigned saved_verbose;
589
590 // Make sure we're in verbose mode, so that printscript()
591 // will output function/probe bodies.
592 saved_verbose = s.verbose;
593 s.verbose = 3;
594
595 // Print script to 'o'
596 printscript(s, o);
597
598 // Restore original verbose mode setting.
599 s.verbose = saved_verbose;
600
601 // Generate hash
602 find_hash (s, o.str());
603
604 // See if we can use cached source/module.
605 if (get_from_cache(s))
606 {
607 // If our last pass isn't 5, we're done (since passes 3 and
608 // 4 just generate what we just pulled out of the cache).
609 if (s.last_pass < 5) goto cleanup;
610
611 // Short-circuit to pass 5.
612 goto pass_5;
613 }
614 }
377b8831 615
0d49d7bc 616 if (rc || s.last_pass == 2) goto cleanup;
f4b28491 617
2b066ec1 618 // PASS 3: TRANSLATION
5ee1c56b
FCE
619
620 times (& tms_before);
1d738eed
FCE
621 gettimeofday (&tv_before, NULL);
622
0d49d7bc 623 rc = translate_pass (s);
f4b28491
FCE
624
625 if (rc == 0 && s.last_pass == 3)
626 {
627 ifstream i (s.translated_source.c_str());
628 cout << i.rdbuf();
629 }
0d49d7bc 630
5ee1c56b 631 times (& tms_after);
1d738eed 632 gettimeofday (&tv_after, NULL);
5ee1c56b 633
0d49d7bc
FCE
634 if (s.verbose) clog << "Pass 3: translated to C into \""
635 << s.translated_source
5ee1c56b
FCE
636 << "\" in "
637 << TIMESPRINT
638 << endl;
0d49d7bc 639
377b8831 640 if (rc)
2cfb0e46 641 cerr << "Pass 3: translation failed. "
213bee8f 642 << "Try again with more '-v' (verbose) options."
2cfb0e46 643 << endl;
377b8831 644
0d49d7bc 645 if (rc || s.last_pass == 3) goto cleanup;
d54d4661 646
f4b28491 647 // PASS 4: COMPILATION
5ee1c56b 648 times (& tms_before);
1d738eed 649 gettimeofday (&tv_before, NULL);
0d49d7bc 650 rc = compile_pass (s);
5ee1c56b 651 times (& tms_after);
1d738eed 652 gettimeofday (&tv_after, NULL);
5ee1c56b
FCE
653
654 if (s.verbose) clog << "Pass 4: compiled C into \""
655 << s.module_name << ".ko"
656 << "\" in "
657 << TIMESPRINT
658 << endl;
f4b28491 659
eaf134e7
FCE
660 if (rc)
661 cerr << "Pass 4: compilation failed. "
213bee8f 662 << "Try again with more '-v' (verbose) options."
2cfb0e46 663 << endl;
1b78aef5
DS
664 else if (s.use_cache)
665 {
666 // Update cache.
667 add_to_cache(s);
668 }
eaf134e7 669
f8949662 670 // XXX: what to do if rc==0 && last_pass == 4? dump .ko file to stdout?
0d49d7bc 671 if (rc || s.last_pass == 4) goto cleanup;
f4b28491 672
0d49d7bc 673 // PASS 5: RUN
1b78aef5 674pass_5:
5ee1c56b 675 times (& tms_before);
1d738eed 676 gettimeofday (&tv_before, NULL);
03d569d3
FCE
677 // NB: this message is a judgement call. The other passes don't emit
678 // a "hello, I'm starting" message, but then the others aren't interactive
679 // and don't take an indefinite amount of time.
680 if (s.verbose) clog << "Pass 5: starting run." << endl;
0d49d7bc 681 rc = run_pass (s);
5ee1c56b 682 times (& tms_after);
1d738eed 683 gettimeofday (&tv_after, NULL);
5ee1c56b
FCE
684 if (s.verbose) clog << "Pass 5: run completed in "
685 << TIMESPRINT
686 << endl;
f4b28491 687
eaf134e7
FCE
688 if (rc)
689 cerr << "Pass 5: run failed. "
213bee8f 690 << "Try again with more '-v' (verbose) options."
2cfb0e46 691 << endl;
eaf134e7 692
0d49d7bc 693 // if (rc) goto cleanup;
2b066ec1 694
0d49d7bc 695 cleanup:
f4b28491
FCE
696 // Clean up temporary directory. Obviously, be careful with this.
697 if (s.tmpdir == "")
698 ; // do nothing
699 else
700 {
701 if (s.keep_tmpdir)
0d49d7bc 702 clog << "Keeping temporary directory \"" << s.tmpdir << "\"" << endl;
f4b28491
FCE
703 else
704 {
ce3187ac 705 string cleanupcmd = "rm -rf ";
f4b28491 706 cleanupcmd += s.tmpdir;
b0ee93c4 707 if (s.verbose>1) clog << "Running " << cleanupcmd << endl;
d54d4661 708 int status = system (cleanupcmd.c_str());
b0ee93c4 709 if (status != 0 && s.verbose>1)
d54d4661 710 clog << "Cleanup command failed, status: " << status << endl;
f4b28491
FCE
711 }
712 }
2b066ec1 713
54dfabe9 714 return rc ? EXIT_FAILURE : EXIT_SUCCESS;
2b066ec1 715}
This page took 0.127571 seconds and 5 git commands to generate.