diff options
author | Tom Tromey <tromey@redhat.com> | 2011-06-03 14:57:27 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-06-03 14:57:27 +0000 |
commit | 00a69a4bc9472e28ea8a13e23af8b9e59f955c43 (patch) | |
tree | 491b87e1d02208f742964101eee3b8b5db0cd793 | |
parent | a876f5f5511df1b28c75e1a951831d78bcc3170f (diff) | |
download | gdb-00a69a4bc9472e28ea8a13e23af8b9e59f955c43.tar.gz |
* dwarf2expr.c (get_signed_type): New function.
(execute_stack_op) <DW_OP_shra>: Always perform a signed shift.
-rw-r--r-- | gdb/ChangeLog | 5 | ||||
-rw-r--r-- | gdb/dwarf2expr.c | 34 |
2 files changed, 39 insertions, 0 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 182909d482e..97a30af6abb 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,8 @@ +2011-06-03 Tom Tromey <tromey@redhat.com> + + * dwarf2expr.c (get_signed_type): New function. + (execute_stack_op) <DW_OP_shra>: Always perform a signed shift. + 2011-06-02 Keith Seitz <keiths@redhat.com> * objc-lang.c (find_methods): Increment objfile_csym earlier. diff --git a/gdb/dwarf2expr.c b/gdb/dwarf2expr.c index 5cd33a6df84..3c60b6ab1b4 100644 --- a/gdb/dwarf2expr.c +++ b/gdb/dwarf2expr.c @@ -229,6 +229,28 @@ get_unsigned_type (struct gdbarch *gdbarch, struct type *type) } } +/* Return the signed form of TYPE. TYPE is necessarily an integral + type. */ + +static struct type * +get_signed_type (struct gdbarch *gdbarch, struct type *type) +{ + switch (TYPE_LENGTH (type)) + { + case 1: + return builtin_type (gdbarch)->builtin_int8; + case 2: + return builtin_type (gdbarch)->builtin_int16; + case 4: + return builtin_type (gdbarch)->builtin_int32; + case 8: + return builtin_type (gdbarch)->builtin_int64; + default: + error (_("no signed variant found for type, while evaluating " + "DWARF expression")); + } +} + /* Retrieve the N'th item on CTX's stack, converted to an address. */ CORE_ADDR @@ -996,7 +1018,19 @@ execute_stack_op (struct dwarf_expr_context *ctx, case DW_OP_shra: dwarf_require_integral (value_type (first)); dwarf_require_integral (value_type (second)); + if (TYPE_UNSIGNED (value_type (first))) + { + struct type *stype + = get_signed_type (ctx->gdbarch, value_type (first)); + + first = value_cast (stype, first); + } + result_val = value_binop (first, second, BINOP_RSH); + /* Make sure we wind up with the same type we started + with. */ + if (value_type (result_val) != value_type (second)) + result_val = value_cast (value_type (second), result_val); break; case DW_OP_xor: dwarf_require_integral (value_type (first)); |