summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--elaborate.cxx18
-rw-r--r--loc2c.c31
-rw-r--r--loc2c.h9
-rw-r--r--staptree.cxx11
-rw-r--r--staptree.h3
-rw-r--r--tapsets.cxx49
-rw-r--r--testsuite/ChangeLog5
-rwxr-xr-xtestsuite/buildok/twentynine.stp6
9 files changed, 117 insertions, 29 deletions
diff --git a/ChangeLog b/ChangeLog
index 07cee9dc..a30ecdba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
diff --git a/loc2c.c b/loc2c.c
index 6834e9f6..52381b82 100644
--- a/loc2c.c
+++ b/loc2c.c
@@ -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)
diff --git a/loc2c.h b/loc2c.h
index 96cc2568..03f9e74c 100644
--- a/loc2c.h
+++ b/loc2c.h
@@ -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)
diff --git a/staptree.h b/staptree.h
index acb56719..136472fd 100644
--- a/staptree.h
+++ b/staptree.h
@@ -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;
+}