summaryrefslogtreecommitdiffstats
path: root/loc2c.c
diff options
context:
space:
mode:
authorfche <fche>2007-06-06 00:40:13 +0000
committerfche <fche>2007-06-06 00:40:13 +0000
commite41b2484eaf36459eb9e80080c1ec3da277c9e36 (patch)
tree2dcdc4699b53353ce376ff08709e4bf223502d11 /loc2c.c
parent357081d3ced4beb537cd1ec49ae71e8a8de2db64 (diff)
downloadsystemtap-steved-e41b2484eaf36459eb9e80080c1ec3da277c9e36.tar.gz
systemtap-steved-e41b2484eaf36459eb9e80080c1ec3da277c9e36.tar.xz
systemtap-steved-e41b2484eaf36459eb9e80080c1ec3da277c9e36.zip
2007-06-05 Frank Ch. Eigler <fche@redhat.com>
PR 3331. * loc2c.c (emit_base_fetch): Emit size/signedness cast for every low-level fetch. (translate_base_fetch, c_translate_fetch, c_translate_store, c_translate_pointer): Fetch & pass the $target signedness. 2007-06-05 Frank Ch. Eigler <fche@elastic.org> PR 3331. * systemtap.base/deref2.*: New test, disabled.
Diffstat (limited to 'loc2c.c')
-rw-r--r--loc2c.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/loc2c.c b/loc2c.c
index f940fb0a..bfae4853 100644
--- a/loc2c.c
+++ b/loc2c.c
@@ -1017,24 +1017,25 @@ c_translate_location (struct obstack *pool,
/* Emit "uintNN_t TARGET = ...;". */
static bool
emit_base_fetch (struct obstack *pool, Dwarf_Word byte_size,
- const char *target, bool decl, struct location *loc)
+ bool signed_p, const char *target, struct location *loc)
{
- if (decl)
- obstack_printf (pool, "uint%" PRIu64 "_t ", byte_size * 8);
+ obstack_printf (pool, "%s = ", target);
+
+ /* Emit size/signed coercion. */
+ obstack_printf (pool, "(%sint%" PRIu64 "_t)",
+ (signed_p ? "" : "u"), byte_size * 8);
switch (loc->type)
{
case loc_address:
if (byte_size != 0 && byte_size != (Dwarf_Word) -1)
- obstack_printf (pool, "%s = deref (%" PRIu64 ", addr);",
- target, byte_size);
+ obstack_printf (pool, "deref (%" PRIu64 ", addr);", byte_size);
else
- obstack_printf (pool, "%s = deref (sizeof %s, addr);",
- target, target);
+ obstack_printf (pool, "deref (sizeof %s, addr);", target);
return true;
case loc_register:
- obstack_printf (pool, "%s = fetch_register (%u);", target, loc->regno);
+ obstack_printf (pool, "fetch_register (%u);", loc->regno);
break;
case loc_noncontiguous:
@@ -1248,7 +1249,7 @@ get_bitfield (struct location *loc,
at the *INPUT location and store it in lvalue TARGET. */
static void
translate_base_fetch (struct obstack *pool, int indent, Dwarf_Word byte_size,
- struct location **input, const char *target)
+ bool signed_p, struct location **input, const char *target)
{
bool deref = false;
@@ -1269,7 +1270,8 @@ translate_base_fetch (struct obstack *pool, int indent, Dwarf_Word byte_size,
*input = newp;
snprintf (&piece[sizeof "u.pieces.p" - 1], 20, "%" PRIu64, offset);
- translate_base_fetch (pool, indent, p->byte_size, input, piece);
+ translate_base_fetch (pool, indent, p->byte_size, signed_p /* ? */,
+ input, piece);
(*input)->type = loc_fragment;
offset += p->byte_size;
@@ -1287,7 +1289,7 @@ translate_base_fetch (struct obstack *pool, int indent, Dwarf_Word byte_size,
case 4:
case 8:
obstack_printf (pool, "%*s", indent * 2, "");
- deref = emit_base_fetch (pool, byte_size, target, false, *input);
+ deref = emit_base_fetch (pool, byte_size, signed_p, target, *input);
obstack_printf (pool, "\n");
break;
@@ -1334,6 +1336,13 @@ c_translate_fetch (struct obstack *pool, int indent,
|| dwarf_formudata (&size_attr, &byte_size) != 0)
byte_size = base_byte_size (typedie, *input);
+ Dwarf_Attribute encoding_attr;
+ Dwarf_Word encoding;
+ if (dwarf_attr_integrate (die, DW_AT_encoding, &encoding_attr) == NULL
+ || dwarf_formudata (&encoding_attr, &encoding) != 0)
+ encoding = DW_ATE_unsigned; /* default */
+ bool signed_p = (encoding == DW_ATE_signed);
+
*input = discontiguify (pool, indent, *input, byte_size,
max_fetch_size (*input, die));
@@ -1342,7 +1351,7 @@ c_translate_fetch (struct obstack *pool, int indent,
/* This is a bit field. Fetch the containing base type into a
temporary variable. */
- translate_base_fetch (pool, indent, byte_size, input, "tmp");
+ translate_base_fetch (pool, indent, byte_size, signed_p, input, "tmp");
(*input)->type = loc_fragment;
(*input)->address.declare = "tmp";
@@ -1359,7 +1368,7 @@ c_translate_fetch (struct obstack *pool, int indent,
*input = loc;
}
else
- translate_base_fetch (pool, indent, byte_size, input, target);
+ translate_base_fetch (pool, indent, byte_size, signed_p, input, target);
}
/* Translate a fragment to store RVALUE into the base-type value of
@@ -1445,6 +1454,13 @@ c_translate_store (struct obstack *pool, int indent,
|| dwarf_formudata (&size_attr, &byte_size) != 0)
byte_size = base_byte_size (typedie, *input);
+ Dwarf_Attribute encoding_attr;
+ Dwarf_Word encoding;
+ if (dwarf_attr_integrate (die, DW_AT_encoding, &encoding_attr) == NULL
+ || dwarf_formudata (&encoding_attr, &encoding) != 0)
+ encoding = DW_ATE_unsigned; /* default */
+ bool signed_p = (encoding == DW_ATE_signed);
+
*input = discontiguify (pool, indent, *input, byte_size,
max_fetch_size (*input, die));
@@ -1455,7 +1471,7 @@ c_translate_store (struct obstack *pool, int indent,
/* This is a bit field. Fetch the containing base type into a
temporary variable. */
- translate_base_fetch (pool, indent, byte_size, input, "tmp");
+ translate_base_fetch (pool, indent, byte_size, signed_p, input, "tmp");
(*input)->type = loc_fragment;
(*input)->address.declare = "tmp";
@@ -1502,7 +1518,14 @@ c_translate_pointer (struct obstack *pool, int indent,
dwarf_diename (typedie) ?: "<anonymous>",
dwarf_errmsg (-1));
- translate_base_fetch (pool, indent + 1, byte_size, input, "addr");
+ Dwarf_Attribute encoding_attr;
+ Dwarf_Word encoding;
+ if (dwarf_attr_integrate (typedie, DW_AT_encoding, &encoding_attr) == NULL
+ || dwarf_formudata (&encoding_attr, &encoding) != 0)
+ encoding = DW_ATE_unsigned; /* default */
+ bool signed_p = (encoding == DW_ATE_signed);
+
+ translate_base_fetch (pool, indent + 1, byte_size, signed_p, input, "addr");
(*input)->type = loc_address;
}