From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5971 invoked by alias); 3 Sep 2009 23:44:04 -0000 Received: (qmail 5959 invoked by uid 22791); 3 Sep 2009 23:44:03 -0000 X-SWARE-Spam-Status: No, hits=-1.0 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_53,KAM_STOCKGEN,SPF_PASS X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (65.74.133.4) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 03 Sep 2009 23:43:59 +0000 Received: (qmail 17022 invoked from network); 3 Sep 2009 23:43:58 -0000 Received: from unknown (HELO localhost) (froydnj@127.0.0.2) by mail.codesourcery.com with ESMTPA; 3 Sep 2009 23:43:58 -0000 Date: Thu, 03 Sep 2009 23:44:00 -0000 From: Nathan Froyd To: Doug Evans Cc: Pedro Alves , gdb@sourceware.org Subject: Re: store.exp failure on i686-linux with newer gcc's Message-ID: <20090903234357.GR29075@codesourcery.com> References: <200909032303.56901.pedro@codesourcery.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.13 (2006-08-11) X-IsSubscribed: yes Mailing-List: contact gdb-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sourceware.org X-SW-Source: 2009-09/txt/msg00062.txt.bz2 On Thu, Sep 03, 2009 at 03:17:32PM -0700, Doug Evans wrote: > On Thu, Sep 3, 2009 at 3:03 PM, Pedro Alves wrote: > > On Thursday 03 September 2009 22:50:13, Doug Evans wrote: > >> Newer gcc's can store a 64 bit int in non-contiguous registers and use > >> DW_OP_piece to mark each piece. > >> > >> value->lval is set to not_lval and value_assign doesn't like that so > >> gdb refuses to set the variable with "Left operand of assignment is > >> not an lvalue." > > > > Nathan Froyd has a patch for this, using the lval_computed > > machinery. > > Good thing I checked first. :-) > Thanks. > > What's the status? [if I may ask - no rush, just curious] Here's the patch we have in our internal tree, applied to gdb HEAD or thereabouts. (We first found the problem with soft-float doubles on 32-bit targets.) It passes tests here; I'd be curious to hear if it works for you as well. If it does, maybe somebody will be so kind as to approve it in this thread rather than waiting for a resubmit. :) -Nathan diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3064089..607c551 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,15 @@ +2009-09-03 Nathan Froyd + + * dwarf2loc.c (struct piece_closure): New. + (allocate_piece_closure): New function. + (read_pieced_value): New function. + (write_pieced_value): New function. + (copy_pieced_value_closure): New function. + (free_pieced_value_closure): New function. + (pieced_value_funcs): Define. + (dwarf2_evaluate_loc_desc): Return a computed value for a variable + described with pieces. + 2009-09-03 Pierre Muller Richard Earnshaw diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index dc150a7..c3f6d40 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -215,6 +215,125 @@ dwarf_expr_tls_address (void *baton, CORE_ADDR offset) return target_translate_tls_address (debaton->objfile, offset); } +struct piece_closure +{ + /* The number of pieces used to describe this variable. */ + int n_pieces; + + /* The pieces themselves. */ + struct dwarf_expr_piece *pieces; +}; + +/* Allocate a closure for a value formed from separately-described + PIECES. */ + +static struct piece_closure * +allocate_piece_closure (int n_pieces, struct dwarf_expr_piece *pieces) +{ + struct piece_closure *c = XZALLOC (struct piece_closure); + + c->n_pieces = n_pieces; + c->pieces = XCALLOC (n_pieces, struct dwarf_expr_piece); + + memcpy (c->pieces, pieces, n_pieces * sizeof (struct dwarf_expr_piece)); + + return c; +} + +static void +read_pieced_value (struct value *v) +{ + int i; + long offset = 0; + gdb_byte *contents; + struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); + struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (v)); + + contents = value_contents_raw (v); + for (i = 0; i < c->n_pieces; i++) + { + struct dwarf_expr_piece *p = &c->pieces[i]; + + if (frame == NULL) + { + 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); + } + offset += p->size; + } +} + +static void +write_pieced_value (struct value *to, struct value *from) +{ + int i; + long offset = 0; + gdb_byte *contents; + struct piece_closure *c = (struct piece_closure *) value_computed_closure (to); + struct frame_info *frame = frame_find_by_id (VALUE_FRAME_ID (to)); + + if (frame == NULL) + { + set_value_optimized_out (to, 1); + return; + } + + contents = value_contents_raw (from); + for (i = 0; i < c->n_pieces; i++) + { + struct dwarf_expr_piece *p = &c->pieces[i]; + if (p->in_reg) + { + 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); + } + offset += p->size; + } +} + +static void * +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); +} + +static void +free_pieced_value_closure (struct value *v) +{ + struct piece_closure *c = (struct piece_closure *) value_computed_closure (v); + + xfree (c->pieces); + xfree (c); +} + +/* Functions for accessing a variable described by DW_OP_piece. */ +static struct lval_funcs pieced_value_funcs = { + read_pieced_value, + write_pieced_value, + copy_pieced_value_closure, + free_pieced_value_closure +}; + /* Evaluate a location description, starting at DATA and with length SIZE, to find the current location of variable VAR in the context of FRAME. */ @@ -254,29 +373,14 @@ dwarf2_evaluate_loc_desc (struct symbol *var, struct frame_info *frame, dwarf_expr_eval (ctx, data, size); if (ctx->num_pieces > 0) { - int i; - long offset = 0; - bfd_byte *contents; - - retval = allocate_value (SYMBOL_TYPE (var)); - contents = value_contents_raw (retval); - for (i = 0; i < ctx->num_pieces; i++) - { - struct dwarf_expr_piece *p = &ctx->pieces[i]; - if (p->in_reg) - { - struct gdbarch *arch = get_frame_arch (frame); - bfd_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 /* In memory? */ - { - read_memory (p->value, contents + offset, p->size); - } - offset += p->size; - } + struct piece_closure *c; + struct frame_id frame_id = get_frame_id (frame); + + c = allocate_piece_closure (ctx->num_pieces, ctx->pieces); + retval = allocate_computed_value (SYMBOL_TYPE (var), + &pieced_value_funcs, + c); + VALUE_FRAME_ID (retval) = frame_id; } else if (ctx->in_reg) {