From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 945 invoked by alias); 10 Sep 2009 23:21:12 -0000 Received: (qmail 931 invoked by uid 22791); 10 Sep 2009 23:21:10 -0000 X-SWARE-Spam-Status: No, hits=-1.1 required=5.0 tests=AWL,BAYES_00,J_CHICKENPOX_56,KAM_STOCKGEN,SPF_PASS X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.33.17) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 Sep 2009 23:19:33 +0000 Received: from wpaz24.hot.corp.google.com (wpaz24.hot.corp.google.com [172.24.198.88]) by smtp-out.google.com with ESMTP id n8ANJEIH013843; Fri, 11 Sep 2009 00:19:15 +0100 Received: from localhost (ruffy.mtv.corp.google.com [172.18.118.116]) by wpaz24.hot.corp.google.com with ESMTP id n8ANJC8k002459; Thu, 10 Sep 2009 16:19:12 -0700 Received: by localhost (Postfix, from userid 67641) id 0733A843B9; Thu, 10 Sep 2009 16:19:11 -0700 (PDT) To: gdb-patches@sourceware.org, tromey@redhat.com Subject: [RFC] better dwarf checking for values on the stack Message-Id: <20090910231912.0733A843B9@localhost> Date: Thu, 10 Sep 2009 23:21:00 -0000 From: dje@google.com (Doug Evans) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-09/txt/msg00295.txt.bz2 This patch builds on the patch here: http://sourceware.org/ml/gdb-patches/2009-09/msg00106.html The purpose is to call set_value_stack only for values actually on the stack. This addresses the issues identified here: http://sourceware.org/ml/gdb-patches/2009-09/msg00069.html I'd like to get this in 7.0, otherwise we have to consider pulling "set stack-cache" out. 2009-09-10 Doug Evans Add better checking for values on stack. * dwarf2expr.h (dwarf_value_location): Rename DWARF_VALUE_STACK to DWARF_VALUE_DWARF_STACK, all uses updated. New enum DWARF_VALUE_MEMORY_STACK. * dwarf2expr.c (execute_stack_op, case DW_OP_fbreg): Mark location as DWARF_VALUE_MEMORY_STACK. (execute_stack_op, case DW_OP_call_frame_cfa): Ditto. (execute_stack_op, cases DW_OP_deref, DW_OP_deref_size): Mark location as DWARF_VALUE_MEMORY. (execute_stack_op, case DW_OP_piece): Remove unused addr_or_regnum. * dwarf2loc.c (read_pieced_value): Handle DWARF_VALUE_MEMORY_STACK. (write_pieced_value): Ditto. (dwarf2_evaluate_loc_desc): Ditto. Only call set_value_stack for values known to be on the stack. * dwarf2-frame.c (execute_stack_op): Handle DWARF_VALUE_MEMORY_STACK. --- ../../../dcache-for-stack2/src/gdb/dwarf2expr.h 2009-09-10 11:23:40.000000000 -0700 +++ ./dwarf2expr.h 2009-09-10 11:50:25.000000000 -0700 @@ -26,12 +26,25 @@ /* The location of a value. */ enum dwarf_value_location { - /* The piece is in memory. */ + /* The piece is in memory. + The value on the dwarf stack is its address. */ DWARF_VALUE_MEMORY, - /* The piece is in a register. */ + + /* The piece is in memory and known to be on the stack. + The value on the dwarf stack is its address. + Stack memory is treated specially as it allows optimized access + for remote targets. + NOTE: This is an optimization. It is always ok to use + DWARF_VALUE_MEMORY instead. */ + DWARF_VALUE_MEMORY_STACK, + + /* The piece is in a register. + The value on the dwarf stack is the register number. */ DWARF_VALUE_REGISTER, - /* The piece is on the stack. */ - DWARF_VALUE_STACK, + + /* The piece is on the dwarf stack. */ + DWARF_VALUE_DWARF_STACK, + /* The piece is a literal. */ DWARF_VALUE_LITERAL }; @@ -111,7 +124,7 @@ struct dwarf_expr_context Each time DW_OP_piece is executed, we add a new element to the end of this array, recording the current top of the stack, the current location, and the size given as the operand to - DW_OP_piece. We then pop the top value from the stack, rest the + DW_OP_piece. We then pop the top value from the stack, reset the location, and resume evaluation. The Dwarf spec doesn't say whether DW_OP_piece pops the top value --- ../../../dcache-for-stack2/src/gdb/dwarf2expr.c 2009-09-10 11:23:40.000000000 -0700 +++ ./dwarf2expr.c 2009-09-10 15:37:20.000000000 -0700 @@ -483,7 +483,7 @@ execute_stack_op (struct dwarf_expr_cont goto no_push; case DW_OP_stack_value: - ctx->location = DWARF_VALUE_STACK; + ctx->location = DWARF_VALUE_DWARF_STACK; require_composition (op_ptr, op_end, "DW_OP_stack_value"); goto no_push; @@ -551,14 +551,14 @@ execute_stack_op (struct dwarf_expr_cont (ctx->get_frame_base) (ctx->baton, &datastart, &datalen); dwarf_expr_eval (ctx, datastart, datalen); if (ctx->location == DWARF_VALUE_LITERAL - || ctx->location == DWARF_VALUE_STACK) + || ctx->location == DWARF_VALUE_DWARF_STACK) error (_("Not implemented: computing frame base using explicit value operator")); result = dwarf_expr_fetch (ctx, 0); if (ctx->location == DWARF_VALUE_REGISTER) result = (ctx->read_reg) (ctx->baton, result); result = result + offset; ctx->stack_len = before_stack_len; - ctx->location = DWARF_VALUE_MEMORY; + ctx->location = DWARF_VALUE_MEMORY_STACK; } break; case DW_OP_dup: @@ -627,6 +627,7 @@ execute_stack_op (struct dwarf_expr_cont result = dwarf2_read_address (ctx->gdbarch, buf, buf + ctx->addr_size, ctx->addr_size); + ctx->location = DWARF_VALUE_MEMORY; } break; @@ -638,6 +639,7 @@ execute_stack_op (struct dwarf_expr_cont result = dwarf2_read_address (ctx->gdbarch, buf, buf + addr_size, addr_size); + ctx->location = DWARF_VALUE_MEMORY; } break; @@ -758,6 +760,7 @@ execute_stack_op (struct dwarf_expr_cont case DW_OP_call_frame_cfa: result = (ctx->get_frame_cfa) (ctx->baton); + ctx->location = DWARF_VALUE_MEMORY_STACK; break; case DW_OP_GNU_push_tls_address: @@ -794,7 +797,6 @@ execute_stack_op (struct dwarf_expr_cont case DW_OP_piece: { ULONGEST size; - CORE_ADDR addr_or_regnum; /* Record the piece. */ op_ptr = read_uleb128 (op_ptr, op_end, &size); --- ../../../dcache-for-stack2/src/gdb/dwarf2loc.c 2009-09-10 11:23:40.000000000 -0700 +++ ./dwarf2loc.c 2009-09-10 11:57:01.000000000 -0700 @@ -220,7 +220,7 @@ struct piece_closure /* The number of pieces used to describe this variable. */ int n_pieces; - /* The architecture, used only for DWARF_VALUE_STACK. */ + /* The architecture, used only for DWARF_VALUE_DWARF_STACK. */ struct gdbarch *arch; /* The pieces themselves. */ @@ -275,7 +275,11 @@ read_pieced_value (struct value *v) read_memory (p->v.value, contents + offset, p->size); break; - case DWARF_VALUE_STACK: + case DWARF_VALUE_MEMORY_STACK: + read_stack (p->v.value, contents + offset, p->size); + break; + + case DWARF_VALUE_DWARF_STACK: { gdb_byte bytes[sizeof (ULONGEST)]; size_t n; @@ -335,6 +339,7 @@ write_pieced_value (struct value *to, st } break; case DWARF_VALUE_MEMORY: + case DWARF_VALUE_MEMORY_STACK: write_memory (p->v.value, contents + offset, p->size); break; default: @@ -432,18 +437,20 @@ dwarf2_evaluate_loc_desc (struct symbol break; case DWARF_VALUE_MEMORY: + case DWARF_VALUE_MEMORY_STACK: { 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); + if (ctx->location == DWARF_VALUE_MEMORY_STACK) + set_value_stack (retval, 1); set_value_address (retval, address); } break; - case DWARF_VALUE_STACK: + case DWARF_VALUE_DWARF_STACK: { gdb_byte bytes[sizeof (ULONGEST)]; ULONGEST value = (ULONGEST) dwarf_expr_fetch (ctx, 0); @@ -485,10 +492,6 @@ dwarf2_evaluate_loc_desc (struct symbol return retval; } - - - - /* Helper functions and baton for dwarf2_loc_desc_needs_frame. */ --- ../../../dcache-for-stack2/src/gdb/dwarf2-frame.c 2009-09-10 11:23:40.000000000 -0700 +++ ./dwarf2-frame.c 2009-09-10 11:42:07.000000000 -0700 @@ -381,7 +381,8 @@ execute_stack_op (gdb_byte *exp, ULONGES if (ctx->location == DWARF_VALUE_REGISTER) result = read_reg (this_frame, result); - else if (ctx->location != DWARF_VALUE_MEMORY) + else if (ctx->location != DWARF_VALUE_MEMORY + && ctx->location != DWARF_VALUE_MEMORY_STACK) { /* This is actually invalid DWARF, but if we ever do run across it somehow, we might as well support it. So, instead, report