diff options
author | Frank Ch. Eigler <fche@elastic.org> | 2008-03-28 12:34:05 -0400 |
---|---|---|
committer | Frank Ch. Eigler <fche@elastic.org> | 2008-03-28 12:34:05 -0400 |
commit | 5e5189b38b0b1b788d32190361961d18e4456ae6 (patch) | |
tree | d388205113589bf73857efc6ef997bc8c39e112b /translate.cxx | |
parent | bf6c85c35a749ca8cc6bea20a7774d063c218938 (diff) | |
parent | 1e00cfb1b6caa8b8ac343fac8e3d08f2d6a5d785 (diff) | |
download | systemtap-steved-5e5189b38b0b1b788d32190361961d18e4456ae6.tar.gz systemtap-steved-5e5189b38b0b1b788d32190361961d18e4456ae6.tar.xz systemtap-steved-5e5189b38b0b1b788d32190361961d18e4456ae6.zip |
Merge branch 'master' of git://sources.redhat.com/git/systemtap
* 'master' of git://sources.redhat.com/git/systemtap: (24 commits)
2008-03-27 Frank Ch. Eigler <fche@elastic.org>
2008-03-27 Frank Ch. Eigler <fche@elastic.org>
2008-03-26 Frank Ch. Eigler <fche@elastic.org>
Revert "dummy commit"
dummy commit
* clarify utility of epilogue-type probe aliases in documentation
2008-03-23 Frank Ch. Eigler <fche@elastic.org>
2008-03-23 Frank Ch. Eigler <fche@elastic.org>
2008-03-21 Eugene Teo <eugeneteo@kernel.sg>
spelling fixes
2008-03-20 Frank Ch. Eigler <fche@elastic.org>
* clarify $variables available in .return probes
2008-03-20 Frank Ch. Eigler <fche@elastic.org>
2008-03-17 Eugene Teo <eteo@redhat.com>
* systemtap.base/maxactive.exp, probefunc.exp: Standardize pass msg.
2008-03-14 Masami Hiramatsu <mhiramat@redhat.com>
2008-03-13 Frank Ch. Eigler <fche@elastic.org>
* release prep: 0.6.2 version bump
2008-03-12 Dave Brolley <brolley@redhat.com>
2008-03-11 Will Cohen <wcohen@redhat.com>
...
Diffstat (limited to 'translate.cxx')
-rw-r--r-- | translate.cxx | 78 |
1 files changed, 76 insertions, 2 deletions
diff --git a/translate.cxx b/translate.cxx index 855a8e93..f30fca7b 100644 --- a/translate.cxx +++ b/translate.cxx @@ -43,6 +43,7 @@ struct c_unparser: public unparser, public visitor functiondecl* current_function; unsigned tmpvar_counter; unsigned label_counter; + bool probe_or_function_needs_deref_fault_handler; varuse_collecting_visitor vcv_needs_global_locks; @@ -1359,6 +1360,9 @@ c_unparser::emit_function (functiondecl* v) o->newline() << "#define THIS l"; o->newline() << "if (0) goto out;"; // make sure out: is marked used + // set this, in case embedded-c code sets last_error but doesn't otherwise identify itself + o->newline() << "c->last_stmt = " << lex_cast_qstring(*v->tok) << ";"; + // check/increment nesting level o->newline() << "if (unlikely (c->nesting+2 >= MAXNESTING)) {"; o->newline(1) << "c->last_error = \"MAXNESTING exceeded\";"; @@ -1386,6 +1390,7 @@ c_unparser::emit_function (functiondecl* v) } o->newline() << "#define return goto out"; // redirect embedded-C return + this->probe_or_function_needs_deref_fault_handler = false; v->body->visit (this); o->newline() << "#undef return"; @@ -1402,6 +1407,15 @@ c_unparser::emit_function (functiondecl* v) o->newline(1) << "c->last_error = 0;"; o->indent(-1); + if (this->probe_or_function_needs_deref_fault_handler) { + // Emit this handler only if the body included a + // print/printf/etc. using a string or memory buffer! + o->newline(1) << "return;"; + o->newline() << "CATCH_DEREF_FAULT ();"; + o->newline() << "goto out;"; + o->indent(-1); + } + o->newline() << "#undef CONTEXT"; o->newline() << "#undef THIS"; o->newline(-1) << "}\n"; @@ -1486,6 +1500,8 @@ c_unparser::emit_probe (derived_probe* v) } else // This probe is unique. Remember it and output it. { + this->probe_or_function_needs_deref_fault_handler = false; + o->newline(); o->newline() << "#ifdef STP_TIMING"; o->newline() << "static __cacheline_aligned Stat " << "time_" << v->basest()->name << ";"; @@ -1546,6 +1562,14 @@ c_unparser::emit_probe (derived_probe* v) if (v->needs_global_locks ()) emit_unlocks (vut); + if (this->probe_or_function_needs_deref_fault_handler) { + // Emit this handler only if the body included a + // print/printf/etc. using a string or memory buffer! + o->newline() << "return;"; + o->newline() << "CATCH_DEREF_FAULT ();"; + o->newline() << "goto out;"; + } + o->newline(-1) << "}\n"; } @@ -4113,11 +4137,43 @@ c_unparser::visit_print_format (print_format* e) { use_print = 1; tmp[0].override(tmp[0].value() + "\"\\n\""); + components[0].type = print_format::conv_literal; } // Make the [s]printf call, but not if there was an error evaluating the args o->newline() << "if (likely (! c->last_error)) {"; o->indent(1); + + // Generate code to check that any pointer arguments are actually accessible. */ + int arg_ix = 0; + for (unsigned i = 0; i < components.size(); ++i) { + if (components[i].type == print_format::conv_literal) + continue; + + /* Take note of the width and precision arguments, if any. */ + int width_ix = -1, prec_ix= -1; + if (components[i].widthtype == print_format::width_dynamic) + width_ix = arg_ix++; + if (components[i].prectype == print_format::prec_dynamic) + prec_ix = arg_ix++; + + /* Generate a noop call to deref_buffer for %m. */ + if (components[i].type == print_format::conv_memory) { + this->probe_or_function_needs_deref_fault_handler = true; + o->newline() << "deref_buffer (0, " << tmp[arg_ix].value() << ", "; + if (prec_ix == -1) + if (width_ix != -1) + prec_ix = width_ix; + if (prec_ix != -1) + o->line() << tmp[prec_ix].value(); + else + o->line() << "1"; + o->line() << ");"; + } + + ++arg_ix; + } + if (e->print_to_stream) { if (e->print_char) @@ -4151,8 +4207,26 @@ c_unparser::visit_print_format (print_format* e) o->line() << '"' << format_string << '"'; - for (unsigned i = 0; i < tmp.size(); ++i) - o->line() << ", " << tmp[i].value(); + /* Generate the actual arguments. Make sure that they match the expected type of the + format specifier. */ + arg_ix = 0; + for (unsigned i = 0; i < components.size(); ++i) { + if (components[i].type == print_format::conv_literal) + continue; + + /* Cast the width and precision arguments, if any, to 'int'. */ + if (components[i].widthtype == print_format::width_dynamic) + o->line() << ", (int)" << tmp[arg_ix++].value(); + if (components[i].prectype == print_format::prec_dynamic) + o->line() << ", (int)" << tmp[arg_ix++].value(); + + /* The type of the %m argument is 'char*'. */ + if (components[i].type == print_format::conv_memory) + o->line() << ", (char*)(uintptr_t)" << tmp[arg_ix++].value(); + else + o->line() << ", " << tmp[arg_ix++].value(); + } + o->line() << ");"; o->newline(-1) << "}"; o->newline() << res.value() << ";"; |