diff options
author | Tom Tromey <tromey@redhat.com> | 2011-05-12 17:40:55 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2011-05-12 17:40:55 +0000 |
commit | 8a9b8146fd539229c51c6a4e5a4f682df2a630b0 (patch) | |
tree | 56c7dadd7ba248c915d0bdbf33cb36840d21dc71 /gdb/dwarf2loc.c | |
parent | e8d28ef4f324014dfd424acab461bbf4393b0b69 (diff) | |
download | gdb-8a9b8146fd539229c51c6a4e5a4f682df2a630b0.zip gdb-8a9b8146fd539229c51c6a4e5a4f682df2a630b0.tar.gz gdb-8a9b8146fd539229c51c6a4e5a4f682df2a630b0.tar.bz2 |
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.c | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index 4c13307..04f16e9 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; |