summaryrefslogtreecommitdiffstats
path: root/gdb/dwarf2loc.c
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2011-05-12 17:40:55 +0000
committerTom Tromey <tromey@redhat.com>2011-05-12 17:40:55 +0000
commit8a9b8146fd539229c51c6a4e5a4f682df2a630b0 (patch)
tree56c7dadd7ba248c915d0bdbf33cb36840d21dc71 /gdb/dwarf2loc.c
parente8d28ef4f324014dfd424acab461bbf4393b0b69 (diff)
downloadppe42-binutils-8a9b8146fd539229c51c6a4e5a4f682df2a630b0.tar.gz
ppe42-binutils-8a9b8146fd539229c51c6a4e5a4f682df2a630b0.zip
gdb
PR gdb/12617: * value.h (value_from_contents): Declare. * value.c (value_from_contents): New function. * dwarf2read.c (dwarf_stack_op_name): Add new values. (dwarf2_get_die_type): New function. * dwarf2loc.c (dwarf_expr_get_base_type): New function. (allocate_piece_closure): Acquire reference to values. (read_pieced_value): Update for value-based expressions. (write_pieced_value): Likewise. (free_pieced_value_closure): Call value_free as needed. (dwarf2_evaluate_loc_desc_full): Set get_base_type field. Update for value-based expressions. * dwarf2loc.h (dwarf2_get_die_type): Declare. * dwarf2expr.h (struct dwarf_stack_value) <value>: Change type. <get_base_type>: New field. (struct dwarf_expr_piece) <v.value>: Change type. <v.regno>: New field. (struct dwarf_expr_context) <mark>: New field. (dwarf_expr_piece, dwarf_expr_fetch): Update. (dwarf_expr_pop, dwarf_expr_push): Remove. (dwarf_expr_push_address): Declare. * dwarf2expr.c (dwarf_arch_cookie): New global. (struct dwarf_gdbarch_types): New. (dwarf_gdbarch_types_init, dwarf_expr_address_type): New functions. (dwarf_expr_push): Change type of 'value' argument. Update. Now static. (dwarf_expr_push_address): New function. (dwarf_expr_pop): Now static. (dwarf_expr_fetch): Change return type. (dwarf_require_integral): New function. (dwarf_expr_fetch): Simplify. (add_piece): Update. (base_types_equal_p, dwarf_get_base_type, get_unsigned_type): New functions. (execute_stack_op) <sign_ext>: Remove. Use values for DWARF stack. <DW_OP_GNU_const_type, DW_OP_GNU_deref_type, DW_OP_GNU_regval_type, DW_OP_GNU_convert, DW_OP_GNU_reinterpret>: New cases. (_initialize_dwarf2expr): New function. (add_piece): Update. (new_dwarf_expr_context): Set new field. (free_dwarf_expr_context): Call value_free_to_mark. * dwarf2-frame.c (no_base_type): New function. (execute_stack_op): Set get_base_type field. Update. gdb/testsuite * gdb.dwarf2/typeddwarf.S: New file. * gdb.dwarf2/typeddwarf.c: New file. * gdb.dwarf2/typeddwarf.exp: New file.
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r--gdb/dwarf2loc.c60
1 files changed, 35 insertions, 25 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c
index 4c13307bb0..04f16e9780 100644
--- a/gdb/dwarf2loc.c
+++ b/gdb/dwarf2loc.c
@@ -286,6 +286,16 @@ dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset)
ctx->get_frame_pc, ctx->baton);
}
+/* Callback function for dwarf2_evaluate_loc_desc. */
+
+static struct type *
+dwarf_expr_get_base_type (struct dwarf_expr_context *ctx, size_t die_offset)
+{
+ struct dwarf_expr_baton *debaton = ctx->baton;
+
+ return dwarf2_get_die_type (die_offset, debaton->per_cu);
+}
+
struct piece_closure
{
/* Reference count. */
@@ -313,6 +323,7 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
int addr_size)
{
struct piece_closure *c = XZALLOC (struct piece_closure);
+ int i;
c->refc = 1;
c->per_cu = per_cu;
@@ -321,6 +332,9 @@ allocate_piece_closure (struct dwarf2_per_cu_data *per_cu,
c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece);
memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece));
+ for (i = 0; i < n_pieces; ++i)
+ if (c->pieces[i].location == DWARF_VALUE_STACK)
+ value_incref (c->pieces[i].v.value);
return c;
}
@@ -576,7 +590,7 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
int reg_offset = source_offset;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -609,7 +623,7 @@ read_pieced_value (struct value *v)
else
{
error (_("Unable to access DWARF register number %s"),
- paddress (arch, p->v.value));
+ paddress (arch, p->v.regno));
}
}
break;
@@ -623,7 +637,6 @@ read_pieced_value (struct value *v)
case DWARF_VALUE_STACK:
{
- struct gdbarch *gdbarch = get_type_arch (value_type (v));
size_t n = this_size;
if (n > c->addr_size - source_offset)
@@ -634,18 +647,11 @@ read_pieced_value (struct value *v)
{
/* Nothing. */
}
- else if (source_offset == 0)
- store_unsigned_integer (buffer, n,
- gdbarch_byte_order (gdbarch),
- p->v.value);
else
{
- gdb_byte bytes[sizeof (ULONGEST)];
+ const gdb_byte *val_bytes = value_contents_all (p->v.value);
- store_unsigned_integer (bytes, n + source_offset,
- gdbarch_byte_order (gdbarch),
- p->v.value);
- memcpy (buffer, bytes + source_offset, n);
+ intermediate_buffer = val_bytes + source_offset;
}
}
break;
@@ -776,7 +782,7 @@ write_pieced_value (struct value *to, struct value *from)
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value);
+ int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.regno);
int reg_offset = dest_offset;
if (gdbarch_byte_order (arch) == BFD_ENDIAN_BIG
@@ -816,7 +822,7 @@ write_pieced_value (struct value *to, struct value *from)
else
{
error (_("Unable to write to DWARF register number %s"),
- paddress (arch, p->v.value));
+ paddress (arch, p->v.regno));
}
}
break;
@@ -1033,6 +1039,12 @@ free_pieced_value_closure (struct value *v)
--c->refc;
if (c->refc == 0)
{
+ int i;
+
+ for (i = 0; i < c->n_pieces; ++i)
+ if (c->pieces[i].location == DWARF_VALUE_STACK)
+ value_free (c->pieces[i].v.value);
+
xfree (c->pieces);
xfree (c);
}
@@ -1106,6 +1118,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
ctx->get_frame_pc = dwarf_expr_frame_pc;
ctx->get_tls_address = dwarf_expr_tls_address;
ctx->dwarf_call = dwarf_expr_dwarf_call;
+ ctx->get_base_type = dwarf_expr_get_base_type;
TRY_CATCH (ex, RETURN_MASK_ERROR)
{
@@ -1148,7 +1161,7 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
case DWARF_VALUE_REGISTER:
{
struct gdbarch *arch = get_frame_arch (frame);
- ULONGEST dwarf_regnum = dwarf_expr_fetch (ctx, 0);
+ ULONGEST dwarf_regnum = value_as_long (dwarf_expr_fetch (ctx, 0));
int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum);
if (byte_offset != 0)
@@ -1176,26 +1189,23 @@ dwarf2_evaluate_loc_desc_full (struct type *type, struct frame_info *frame,
case DWARF_VALUE_STACK:
{
- ULONGEST value = dwarf_expr_fetch (ctx, 0);
- bfd_byte *contents, *tem;
- size_t n = ctx->addr_size;
+ struct value *value = dwarf_expr_fetch (ctx, 0);
+ gdb_byte *contents;
+ const gdb_byte *val_bytes;
+ size_t n = TYPE_LENGTH (value_type (value));
if (byte_offset + TYPE_LENGTH (type) > n)
invalid_synthetic_pointer ();
- tem = alloca (n);
- store_unsigned_integer (tem, n,
- gdbarch_byte_order (ctx->gdbarch),
- value);
-
- tem += byte_offset;
+ val_bytes = value_contents_all (value);
+ val_bytes += byte_offset;
n -= byte_offset;
retval = allocate_value (type);
contents = value_contents_raw (retval);
if (n > TYPE_LENGTH (type))
n = TYPE_LENGTH (type);
- memcpy (contents, tem, n);
+ memcpy (contents, val_bytes, n);
}
break;
OpenPOWER on IntegriCloud