diff options
author | fche <fche> | 2008-03-03 21:36:50 +0000 |
---|---|---|
committer | fche <fche> | 2008-03-03 21:36:50 +0000 |
commit | b0be9bdb8c6972d847cad50a1e699f1fa806ad99 (patch) | |
tree | 66b3e148a84447d69f1340447c5edba8bf2055cd | |
parent | aae3e9a9a9cb64560070de2d1de30b08252b1e81 (diff) | |
download | systemtap-steved-b0be9bdb8c6972d847cad50a1e699f1fa806ad99.tar.gz systemtap-steved-b0be9bdb8c6972d847cad50a1e699f1fa806ad99.tar.xz systemtap-steved-b0be9bdb8c6972d847cad50a1e699f1fa806ad99.zip |
PR5516: assignment to $pointers
2008-03-03 Frank Ch. Eigler <fche@elastic.org>
PR5516
* elaborate.cxx (symbol_fetcher, dead_assignment_remover):
Support unresolved $target lvalues. Propagate pretty error
messages.
* staptree.cxx (varuse_collecting_visitor target_symbol): Ditto.
* staptree.h: Corresponding decl.
* loc2c.c: c_translate_pointer_store: New function.
* loc2c.h: Corresponding decl.
* tapsets.cxx (dwflpp::translate_final_fetch_or_store): Call it
for $target pointer assignments.
2008-03-03 Frank Ch. Eigler <fche@elastic.org>
PR5516
* buildok/twentynine.stp: New test.
-rw-r--r-- | ChangeLog | 14 | ||||
-rw-r--r-- | elaborate.cxx | 18 | ||||
-rw-r--r-- | loc2c.c | 31 | ||||
-rw-r--r-- | loc2c.h | 9 | ||||
-rw-r--r-- | staptree.cxx | 11 | ||||
-rw-r--r-- | staptree.h | 3 | ||||
-rw-r--r-- | tapsets.cxx | 49 | ||||
-rw-r--r-- | testsuite/ChangeLog | 5 | ||||
-rwxr-xr-x | testsuite/buildok/twentynine.stp | 6 |
9 files changed, 117 insertions, 29 deletions
@@ -1,3 +1,17 @@ +2008-03-03 Frank Ch. Eigler <fche@elastic.org> + + PR5516 + * elaborate.cxx (symbol_fetcher, dead_assignment_remover): + Support unresolved $target lvalues. Propagate pretty error + messages. + * staptree.cxx (varuse_collecting_visitor target_symbol): Ditto. + * staptree.h: Corresponding decl. + + * loc2c.c: c_translate_pointer_store: New function. + * loc2c.h: Corresponding decl. + * tapsets.cxx (dwflpp::translate_final_fetch_or_store): Call it + for $target pointer assignments. + 2008-02-29 Will Cohen <wcohen@redhat.com> * main.cxx (handle_interrupts): Make compatible with GCC 4.3. diff --git a/elaborate.cxx b/elaborate.cxx index 75714102..abb4c73b 100644 --- a/elaborate.cxx +++ b/elaborate.cxx @@ -696,8 +696,7 @@ struct symbol_fetcher { symbol *&sym; - symbol_fetcher (symbol *&sym) - : sym(sym) + symbol_fetcher (symbol *&sym): sym(sym) {} void visit_symbol (symbol* e) @@ -705,6 +704,11 @@ struct symbol_fetcher sym = e; } + void visit_target_symbol (target_symbol* e) + { + sym = e; + } + void visit_arrayindex (arrayindex* e) { e->base->visit_indexable (this); @@ -722,9 +726,7 @@ get_symbol_within_expression (expression *e) symbol *sym = NULL; symbol_fetcher fetcher(sym); e->visit (&fetcher); - if (!sym) - throw semantic_error("Unable to find symbol in expression", e->tok); - return sym; + return sym; // NB: may be null! } static symbol * @@ -1718,12 +1720,12 @@ void dead_assignment_remover::visit_assignment (assignment* e) { symbol* left = get_symbol_within_expression (e->left); - vardecl* leftvar = left->referent; + vardecl* leftvar = left->referent; // NB: may be 0 for unresolved $target if (current_expr && // see XXX above: this case represents a missed // optimization opportunity - *current_expr == e) // we're not nested any deeper than expected + *current_expr == e && // we're not nested any deeper than expected + leftvar) // not unresolved $target; intended sideeffect cannot be elided { - // clog << "Checking assignment to " << leftvar->name << " at " << *e->tok << endl; if (vut.read.find(leftvar) == vut.read.end()) // var never read? { // NB: Not so fast! The left side could be an array whose @@ -1601,6 +1601,37 @@ c_translate_addressof (struct obstack *pool, int indent, } +/* Translate a fragment to write the given pointer value, + where *INPUT is the location of the pointer with that type. +*/ + +void +c_translate_pointer_store (struct obstack *pool, int indent, + Dwarf_Addr dwbias __attribute__ ((unused)), + Dwarf_Die *typedie, struct location **input, + const char *rvalue) +{ + assert (dwarf_tag (typedie) == DW_TAG_pointer_type); + + Dwarf_Attribute attr_mem; + Dwarf_Word byte_size; + if (dwarf_attr_integrate (typedie, DW_AT_byte_size, &attr_mem) == NULL) + byte_size = 0; + else if (dwarf_formudata (&attr_mem, &byte_size) != 0) + FAIL (*input, + N_("cannot get byte_size attribute for type %s: %s"), + dwarf_diename (typedie) ?: "<anonymous>", + dwarf_errmsg (-1)); + + translate_base_store (pool, indent + 1, byte_size, + input, *input, rvalue); + + // XXX: what about multiple-location lvalues? +} + + + + /* Determine the element stride of an array type. */ static Dwarf_Word array_stride (Dwarf_Die *typedie, struct location *origin) @@ -77,6 +77,15 @@ void c_translate_store (struct obstack *pool, int indent, Dwarf_Die *die, Dwarf_Die *typedie, struct location **input, const char *rvalue); +/* Translate a fragment to write the given pointer value, + where *INPUT is the location of the pointer with that type. */ +void +c_translate_pointer_store (struct obstack *pool, int indent, + Dwarf_Addr dwbias __attribute__ ((unused)), + Dwarf_Die *typedie, struct location **input, + const char *rvalue); + + /* Emit the C fragment built up at LOC (i.e., the return value from the first c_translate_location call made). INDENT should match that passed to c_translate_* previously. diff --git a/staptree.cxx b/staptree.cxx index 63c1fcf7..778691f4 100644 --- a/staptree.cxx +++ b/staptree.cxx @@ -1644,6 +1644,17 @@ varuse_collecting_visitor::visit_embeddedcode (embeddedcode *s) embedded_seen = true; } +void +varuse_collecting_visitor::visit_target_symbol (target_symbol *e) +{ + // Still-unresolved target symbol assignments get treated as + // generating side-effects like embedded-C, to prevent premature + // elision and later error message suppression (PR5516). rvalue use + // of unresolved target symbols is OTOH not considered a side-effect. + + if (is_active_lvalue (e)) + embedded_seen = true; +} void varuse_collecting_visitor::visit_print_format (print_format* e) @@ -222,7 +222,7 @@ struct symbol: }; -struct target_symbol : public expression +struct target_symbol: public symbol { enum component_type { @@ -749,6 +749,7 @@ struct varuse_collecting_visitor: public functioncall_traversing_visitor void visit_print_format (print_format *e); void visit_assignment (assignment *e); void visit_arrayindex (arrayindex *e); + void visit_target_symbol (target_symbol *e); void visit_symbol (symbol *e); void visit_pre_crement (pre_crement *e); void visit_post_crement (post_crement *e); diff --git a/tapsets.cxx b/tapsets.cxx index 52c14024..147ea3f0 100644 --- a/tapsets.cxx +++ b/tapsets.cxx @@ -1601,7 +1601,7 @@ struct dwflpp if (components[i].first == target_symbol::comp_literal_array_index) throw semantic_error ("cannot index pointer"); // XXX: of course, we should support this the same way C does, - // by explicit pointer arithmetic etc. + // by explicit pointer arithmetic etc. PR4166. c_translate_pointer (pool, 1, module_bias, die, tail); break; @@ -1773,10 +1773,7 @@ struct dwflpp case DW_TAG_array_type: case DW_TAG_pointer_type: - if (lvalue) - throw semantic_error ("cannot store into target pointer value"); - - { + { Dwarf_Die pointee_typedie_mem; Dwarf_Die *pointee_typedie; Dwarf_Word pointee_encoding; @@ -1790,21 +1787,33 @@ struct dwflpp dwarf_formudata (dwarf_attr_integrate (pointee_typedie, DW_AT_encoding, attr_mem), &pointee_encoding); - // We have the pointer: cast it to an integral type via &(*(...)) - - // NB: per bug #1187, at one point char*-like types were - // automagically converted here to systemtap string values. - // For several reasons, this was taken back out, leaving - // pointer-to-string "conversion" (copying) to tapset functions. - - ty = pe_long; - if (typetag == DW_TAG_array_type) - c_translate_array (pool, 1, module_bias, typedie, tail, NULL, 0); - else - c_translate_pointer (pool, 1, module_bias, typedie, tail); - c_translate_addressof (pool, 1, module_bias, NULL, pointee_typedie, tail, - "THIS->__retvalue"); - } + if (lvalue) + { + ty = pe_long; + if (typetag == DW_TAG_array_type) + throw semantic_error ("cannot write to array address"); + assert (typetag == DW_TAG_pointer_type); + c_translate_pointer_store (pool, 1, module_bias, typedie, tail, + "THIS->value"); + } + else + { + // We have the pointer: cast it to an integral type via &(*(...)) + + // NB: per bug #1187, at one point char*-like types were + // automagically converted here to systemtap string values. + // For several reasons, this was taken back out, leaving + // pointer-to-string "conversion" (copying) to tapset functions. + + ty = pe_long; + if (typetag == DW_TAG_array_type) + c_translate_array (pool, 1, module_bias, typedie, tail, NULL, 0); + else + c_translate_pointer (pool, 1, module_bias, typedie, tail); + c_translate_addressof (pool, 1, module_bias, NULL, pointee_typedie, tail, + "THIS->__retvalue"); + } + } break; } } diff --git a/testsuite/ChangeLog b/testsuite/ChangeLog index aee14fe6..2f6caac1 100644 --- a/testsuite/ChangeLog +++ b/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2008-03-03 Frank Ch. Eigler <fche@elastic.org> + + PR5516 + * buildok/twentynine.stp: New test. + 2008-02-27 Dave Brolley <brolley@redhat.com> PR5189 diff --git a/testsuite/buildok/twentynine.stp b/testsuite/buildok/twentynine.stp new file mode 100755 index 00000000..826f5e73 --- /dev/null +++ b/testsuite/buildok/twentynine.stp @@ -0,0 +1,6 @@ +#! stap -gp4 + +probe kernel.function("icmp_rcv") { + printf("skb = %x\n", $skb); + $skb = 0; +} |