diff options
author | Tom Tromey <tromey@redhat.com> | 2009-09-11 18:38:39 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2009-09-11 18:38:39 +0000 |
commit | cec03d703f8c80f4a3f98fe0e3e35dde7e9b1835 (patch) | |
tree | 2faf4cf446d7c4f9eedfb9f15c4cfe890722b62d /gdb/dwarf2loc.c | |
parent | a05e8785c75bf89c90799f675f126782aabbb20e (diff) | |
download | gdb-cec03d703f8c80f4a3f98fe0e3e35dde7e9b1835.zip gdb-cec03d703f8c80f4a3f98fe0e3e35dde7e9b1835.tar.gz gdb-cec03d703f8c80f4a3f98fe0e3e35dde7e9b1835.tar.bz2 |
gdb
* dwarf2loc.c (struct piece_closure) <arch>: New field.
(dwarf2_evaluate_loc_desc): Update.
(dwarf2_loc_desc_needs_frame): Likewise.
(allocate_piece_closure): Initialize new field.
(read_pieced_value): Update.
(write_pieced_value): Update.
(copy_pieced_value_closure): Update.
* dwarf2expr.h (enum dwarf_value_location): New.
(struct dwarf_expr_context) <in_reg>: Remove.
<location, len, data>: New fields.
(struct dwarf_expr_piece) <in_reg, value>: Remove.
<location, v>: New fields.
* dwarf2expr.c (add_piece): Remove in_reg, value arguments.
Update.
(require_composition): New function.
(execute_stack_op): Update.
<DW_OP_implicit_value, DW_OP_stack_value>: New cases.
<DW_OP_reg0>: Set location, not in_reg.
<DW_OP_regx>: Likewise. Use require_composition.
<DW_OP_fbreg>: Update.
<DW_OP_piece>: Likewise.
* dwarf2-frame.c (execute_stack_op): Update.
gdb/testsuite
* gdb.dwarf2/valop.S: New file.
* gdb.dwarf2/valop.exp: New file.
Diffstat (limited to 'gdb/dwarf2loc.c')
-rw-r--r-- | gdb/dwarf2loc.c | 167 |
1 files changed, 123 insertions, 44 deletions
diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index c3f6d40..c314a78 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -220,6 +220,9 @@ struct piece_closure /* The number of pieces used to describe this variable. */ int n_pieces; + /* The architecture, used only for DWARF_VALUE_STACK. */ + struct gdbarch *arch; + /* The pieces themselves. */ struct dwarf_expr_piece *pieces; }; @@ -228,11 +231,13 @@ struct piece_closure PIECES. */ static struct piece_closure * -allocate_piece_closure (int n_pieces, struct dwarf_expr_piece *pieces) +allocate_piece_closure (int n_pieces, struct dwarf_expr_piece *pieces, + struct gdbarch *arch) { struct piece_closure *c = XZALLOC (struct piece_closure); c->n_pieces = n_pieces; + c->arch = arch; c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece); memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece)); @@ -253,24 +258,49 @@ read_pieced_value (struct value *v) for (i = 0; i < c->n_pieces; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - - if (frame == NULL) + switch (p->location) { - memset (contents + offset, 0, p->size); - set_value_optimized_out (v, 1); - } - else if (p->in_reg) - { - struct gdbarch *arch = get_frame_arch (frame); - gdb_byte regval[MAX_REGISTER_SIZE]; - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->value); - - get_frame_register (frame, gdb_regnum, regval); - memcpy (contents + offset, regval, p->size); - } - else - { - read_memory (p->value, contents + offset, p->size); + case DWARF_VALUE_REGISTER: + { + struct gdbarch *arch = get_frame_arch (frame); + bfd_byte regval[MAX_REGISTER_SIZE]; + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, + p->v.value); + get_frame_register (frame, gdb_regnum, regval); + memcpy (contents + offset, regval, p->size); + } + break; + + case DWARF_VALUE_MEMORY: + read_memory (p->v.value, contents + offset, p->size); + break; + + case DWARF_VALUE_STACK: + { + gdb_byte bytes[sizeof (ULONGEST)]; + size_t n; + int addr_size = gdbarch_addr_bit (c->arch) / 8; + store_unsigned_integer (bytes, addr_size, + gdbarch_byte_order (c->arch), + p->v.value); + n = p->size; + if (n > addr_size) + n = addr_size; + memcpy (contents + offset, bytes, n); + } + break; + + case DWARF_VALUE_LITERAL: + { + size_t n = p->size; + if (n > p->v.literal.length) + n = p->v.literal.length; + memcpy (contents + offset, p->v.literal.data, n); + } + break; + + default: + internal_error (__FILE__, __LINE__, _("invalid location type")); } offset += p->size; } @@ -295,15 +325,21 @@ write_pieced_value (struct value *to, struct value *from) for (i = 0; i < c->n_pieces; i++) { struct dwarf_expr_piece *p = &c->pieces[i]; - if (p->in_reg) + switch (p->location) { - struct gdbarch *arch = get_frame_arch (frame); - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->value); - put_frame_register (frame, gdb_regnum, contents + offset); - } - else - { - write_memory (p->value, contents + offset, p->size); + case DWARF_VALUE_REGISTER: + { + struct gdbarch *arch = get_frame_arch (frame); + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, p->v.value); + put_frame_register (frame, gdb_regnum, contents + offset); + } + break; + case DWARF_VALUE_MEMORY: + write_memory (p->v.value, contents + offset, p->size); + break; + default: + set_value_optimized_out (to, 1); + return; } offset += p->size; } @@ -314,7 +350,7 @@ copy_pieced_value_closure (struct value *v) { struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); - return allocate_piece_closure (c->n_pieces, c->pieces); + return allocate_piece_closure (c->n_pieces, c->pieces, c->arch); } static void @@ -376,28 +412,71 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, struct piece_closure *c; struct frame_id frame_id = get_frame_id (frame); - c = allocate_piece_closure (ctx->num_pieces, ctx->pieces); + c = allocate_piece_closure (ctx->num_pieces, ctx->pieces, ctx->gdbarch); retval = allocate_computed_value (SYMBOL_TYPE (var), &pieced_value_funcs, c); VALUE_FRAME_ID (retval) = frame_id; } - else if (ctx->in_reg) - { - struct gdbarch *arch = get_frame_arch (frame); - CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0); - int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum); - retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame); - } else { - CORE_ADDR address = dwarf_expr_fetch (ctx, 0); - - retval = allocate_value (SYMBOL_TYPE (var)); - VALUE_LVAL (retval) = lval_memory; - set_value_lazy (retval, 1); - set_value_stack (retval, 1); - set_value_address (retval, address); + switch (ctx->location) + { + case DWARF_VALUE_REGISTER: + { + struct gdbarch *arch = get_frame_arch (frame); + CORE_ADDR dwarf_regnum = dwarf_expr_fetch (ctx, 0); + int gdb_regnum = gdbarch_dwarf2_reg_to_regnum (arch, dwarf_regnum); + retval = value_from_register (SYMBOL_TYPE (var), gdb_regnum, frame); + } + break; + + case DWARF_VALUE_MEMORY: + { + CORE_ADDR address = dwarf_expr_fetch (ctx, 0); + + retval = allocate_value (SYMBOL_TYPE (var)); + VALUE_LVAL (retval) = lval_memory; + set_value_lazy (retval, 1); + set_value_stack (retval, 1); + set_value_address (retval, address); + } + break; + + case DWARF_VALUE_STACK: + { + gdb_byte bytes[sizeof (ULONGEST)]; + ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0); + bfd_byte *contents; + size_t n = ctx->addr_size; + + store_unsigned_integer (bytes, ctx->addr_size, + gdbarch_byte_order (ctx->gdbarch), + value); + retval = allocate_value (SYMBOL_TYPE (var)); + contents = value_contents_raw (retval); + if (n > TYPE_LENGTH (SYMBOL_TYPE (var))) + n = TYPE_LENGTH (SYMBOL_TYPE (var)); + memcpy (contents, bytes, n); + } + break; + + case DWARF_VALUE_LITERAL: + { + bfd_byte *contents; + size_t n = ctx->len; + + retval = allocate_value (SYMBOL_TYPE (var)); + contents = value_contents_raw (retval); + if (n > TYPE_LENGTH (SYMBOL_TYPE (var))) + n = TYPE_LENGTH (SYMBOL_TYPE (var)); + memcpy (contents, ctx->data, n); + } + break; + + default: + internal_error (__FILE__, __LINE__, _("invalid location type")); + } } set_value_initialized (retval, ctx->initialized); @@ -494,7 +573,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size, dwarf_expr_eval (ctx, data, size); - in_reg = ctx->in_reg; + in_reg = ctx->location == DWARF_VALUE_REGISTER; if (ctx->num_pieces > 0) { @@ -503,7 +582,7 @@ dwarf2_loc_desc_needs_frame (gdb_byte *data, unsigned short size, /* If the location has several pieces, and any of them are in registers, then we will need a frame to fetch them from. */ for (i = 0; i < ctx->num_pieces; i++) - if (ctx->pieces[i].in_reg) + if (ctx->pieces[i].location == DWARF_VALUE_REGISTER) in_reg = 1; } |