From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9739 invoked by alias); 7 Jun 2010 20:00:53 -0000 Received: (qmail 9713 invoked by uid 22791); 7 Jun 2010 20:00:50 -0000 X-SWARE-Spam-Status: No, hits=-5.0 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,TW_BJ,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 07 Jun 2010 20:00:38 +0000 Received: from int-mx02.intmail.prod.int.phx2.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o57K0adP017837 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 7 Jun 2010 16:00:36 -0400 Received: from host0.dyn.jankratochvil.net (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by int-mx02.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o57K0Yae026202 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Mon, 7 Jun 2010 16:00:35 -0400 Received: from host0.dyn.jankratochvil.net (localhost [127.0.0.1]) by host0.dyn.jankratochvil.net (8.14.4/8.14.4) with ESMTP id o57K0Xda031835; Mon, 7 Jun 2010 22:00:33 +0200 Received: (from jkratoch@localhost) by host0.dyn.jankratochvil.net (8.14.4/8.14.4/Submit) id o57K0XbU031834; Mon, 7 Jun 2010 22:00:33 +0200 Date: Mon, 07 Jun 2010 20:00:00 -0000 From: Jan Kratochvil To: Tom Tromey Cc: gdb-patches@sourceware.org Subject: Re: [patch 2/2] DW_OP_call: Support DW_OP_call2 and DW_OP_call4 Message-ID: <20100607200033.GB31093@host0.dyn.jankratochvil.net> References: <20100607115645.GC24148@host0.dyn.jankratochvil.net> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.20 (2009-12-10) 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: 2010-06/txt/msg00189.txt.bz2 On Mon, 07 Jun 2010 20:12:58 +0200, Tom Tromey wrote: > Would you mind filing a new PR for DW_OP_call_ref? Filed now PR 11674. > Jan> +struct dwarf2_locexpr_baton > Jan> +fetch_die_location_block (unsigned int offset, struct dwarf2_per_cu_data *per_cu) > > I think this function name should have a dwarf2_ prefix. > Also it looks like this line wraps. I agree, fixed, mistake while making it public. > Jan> --- a/gdb/symfile.h > Jan> +++ b/gdb/symfile.h > Jan> +struct dwarf2_per_cu_data; > Jan> +extern struct dwarf2_locexpr_baton fetch_die_location_block > Jan> + (unsigned int offset, struct dwarf2_per_cu_data *per_cu); > > I think this should go in one of the dwarf headers, not symfile.h. > I think probably dwarf2loc.h, near the other functions taking a > dwarf2_per_cu_data. I agree, moved there. > Ok with these changes. Thanks. Checked-in. Thanks, Jan http://sourceware.org/ml/gdb-cvs/2010-06/msg00063.html --- src/gdb/ChangeLog 2010/06/07 19:42:58 1.11884 +++ src/gdb/ChangeLog 2010/06/07 19:55:33 1.11885 @@ -1,5 +1,23 @@ 2010-06-07 Jan Kratochvil + Fix PR 10640. + * dwarf2-frame.c (no_dwarf_call): New function. + (execute_stack_op): Set CTX->DWARF_CALL. + * dwarf2expr.c (execute_stack_op) : New. + * dwarf2expr.h (struct dwarf_expr_context) : New. + (struct dwarf_expr_context) : Remove the #if0-ed field. + * dwarf2loc.c (per_cu_dwarf_call, dwarf_expr_dwarf_call): New functions. + (dwarf2_evaluate_loc_desc): Initialize CTX->DWARF_CALL. + (needs_frame_dwarf_call): New function. + (dwarf2_loc_desc_needs_frame): Initialize CTX->DWARF_CALL. + * dwarf2read.c (follow_die_offset): Based on former follow_die_ref. + Update the comment. Move variables die, offset and error call to ... + (follow_die_ref): ... a new function. + (dwarf2_fetch_die_location_block): New function. + * dwarf2loc.h (dwarf2_fetch_die_location_block): New prototype. + +2010-06-07 Jan Kratochvil + * dwarf2loc.c (struct dwarf_expr_baton) Replace objfile by per_cu. (dwarf_expr_tls_address): Use per_cu instead of objfile. (dwarf2_evaluate_loc_desc): Drop initialization of BATON.OBJFILE. --- src/gdb/dwarf2-frame.c 2010/05/25 16:41:45 1.111 +++ src/gdb/dwarf2-frame.c 2010/06/07 19:55:33 1.112 @@ -328,6 +328,15 @@ _("Support for DW_OP_GNU_push_tls_address is unimplemented")); } +/* Helper function for execute_stack_op. */ + +static void +no_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset) +{ + internal_error (__FILE__, __LINE__, + _("Support for DW_OP_call* is invalid in CFI")); +} + /* Execute the required actions for both the DW_CFA_restore and DW_CFA_restore_extended instructions. */ static void @@ -378,6 +387,7 @@ ctx->get_frame_base = no_get_frame_base; ctx->get_frame_cfa = no_get_frame_cfa; ctx->get_tls_address = no_get_tls_address; + ctx->dwarf_call = no_dwarf_call; dwarf_expr_push (ctx, initial, initial_in_stack_memory); dwarf_expr_eval (ctx, exp, len); --- src/gdb/dwarf2expr.c 2010/05/25 16:41:46 1.45 +++ src/gdb/dwarf2expr.c 2010/06/07 19:55:33 1.46 @@ -911,6 +911,18 @@ ctx->initialized = 0; goto no_push; + case DW_OP_call2: + result = extract_unsigned_integer (op_ptr, 2, byte_order); + op_ptr += 2; + ctx->dwarf_call (ctx, result); + goto no_push; + + case DW_OP_call4: + result = extract_unsigned_integer (op_ptr, 4, byte_order); + op_ptr += 4; + ctx->dwarf_call (ctx, result); + goto no_push; + default: error (_("Unhandled dwarf expression opcode 0x%x"), op); } --- src/gdb/dwarf2expr.h 2010/06/02 19:37:55 1.24 +++ src/gdb/dwarf2expr.h 2010/06/07 19:55:33 1.25 @@ -97,15 +97,14 @@ DW_OP_GNU_push_tls_address. */ CORE_ADDR (*get_tls_address) (void *baton, CORE_ADDR offset); + /* Execute DW_AT_location expression for the DWARF expression subroutine in + the DIE at DIE_OFFSET in the CU from CTX. Do not touch STACK while it + being passed to and returned from the called DWARF subroutine. */ + void (*dwarf_call) (struct dwarf_expr_context *ctx, size_t die_offset); + #if 0 /* Not yet implemented. */ - /* Return the location expression for the dwarf expression - subroutine in the die at OFFSET in the current compilation unit. - The result must be live until the current expression evaluation - is complete. */ - unsigned char *(*get_subr) (void *baton, off_t offset, size_t *length); - /* Return the `object address' for DW_OP_push_object_address. */ CORE_ADDR (*get_object_address) (void *baton); #endif --- src/gdb/dwarf2loc.c 2010/06/07 19:42:58 1.87 +++ src/gdb/dwarf2loc.c 2010/06/07 19:55:33 1.88 @@ -232,6 +232,33 @@ return target_translate_tls_address (objfile, offset); } +/* Call DWARF subroutine from DW_AT_location of DIE at DIE_OFFSET in current CU + (as is PER_CU). State of the CTX is not affected by the call and return. */ + +static void +per_cu_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset, + struct dwarf2_per_cu_data *per_cu) +{ + struct dwarf2_locexpr_baton block; + + block = dwarf2_fetch_die_location_block (die_offset, per_cu); + + /* DW_OP_call_ref is currently not supported. */ + gdb_assert (block.per_cu == per_cu); + + dwarf_expr_eval (ctx, block.data, block.size); +} + +/* Helper interface of per_cu_dwarf_call for dwarf2_evaluate_loc_desc. */ + +static void +dwarf_expr_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset) +{ + struct dwarf_expr_baton *debaton = ctx->baton; + + return per_cu_dwarf_call (ctx, die_offset, debaton->per_cu); +} + struct piece_closure { /* Reference count. */ @@ -815,6 +842,7 @@ ctx->get_frame_base = dwarf_expr_frame_base; ctx->get_frame_cfa = dwarf_expr_frame_cfa; ctx->get_tls_address = dwarf_expr_tls_address; + ctx->dwarf_call = dwarf_expr_dwarf_call; dwarf_expr_eval (ctx, data, size); if (ctx->num_pieces > 0) @@ -962,6 +990,16 @@ return 1; } +/* Helper interface of per_cu_dwarf_call for dwarf2_loc_desc_needs_frame. */ + +static void +needs_frame_dwarf_call (struct dwarf_expr_context *ctx, size_t die_offset) +{ + struct needs_frame_baton *nf_baton = ctx->baton; + + return per_cu_dwarf_call (ctx, die_offset, nf_baton->per_cu); +} + /* Return non-zero iff the location expression at DATA (length SIZE) requires a frame to evaluate. */ @@ -988,6 +1026,7 @@ ctx->get_frame_base = needs_frame_frame_base; ctx->get_frame_cfa = needs_frame_frame_cfa; ctx->get_tls_address = needs_frame_tls_address; + ctx->dwarf_call = needs_frame_dwarf_call; dwarf_expr_eval (ctx, data, size); --- src/gdb/dwarf2loc.h 2010/06/02 19:37:55 1.16 +++ src/gdb/dwarf2loc.h 2010/06/07 19:55:33 1.17 @@ -37,6 +37,9 @@ /* Return the offset size given in the compilation unit header for CU. */ int dwarf2_per_cu_offset_size (struct dwarf2_per_cu_data *cu); +struct dwarf2_locexpr_baton dwarf2_fetch_die_location_block + (unsigned int offset, struct dwarf2_per_cu_data *per_cu); + /* The symbol location baton types used by the DWARF-2 reader (i.e. SYMBOL_LOCATION_BATON for a LOC_COMPUTED symbol). "struct dwarf2_locexpr_baton" is for a symbol with a single location --- src/gdb/dwarf2read.c 2010/06/07 19:42:58 1.396 +++ src/gdb/dwarf2read.c 2010/06/07 19:55:33 1.397 @@ -10736,30 +10736,25 @@ return die; } -/* Follow reference attribute ATTR of SRC_DIE. - On entry *REF_CU is the CU of SRC_DIE. +/* Follow reference OFFSET. + On entry *REF_CU is the CU of source DIE referencing OFFSET. On exit *REF_CU is the CU of the result. */ static struct die_info * -follow_die_ref (struct die_info *src_die, struct attribute *attr, - struct dwarf2_cu **ref_cu) +follow_die_offset (unsigned int offset, struct dwarf2_cu **ref_cu) { - struct die_info *die; - unsigned int offset; struct die_info temp_die; struct dwarf2_cu *target_cu, *cu = *ref_cu; gdb_assert (cu->per_cu != NULL); - offset = dwarf2_get_ref_die_offset (attr); - if (cu->per_cu->from_debug_types) { /* .debug_types CUs cannot reference anything outside their CU. If they need to, they have to reference a signatured type via DW_FORM_sig8. */ if (! offset_in_cu_p (&cu->header, offset)) - goto not_found; + return NULL; target_cu = cu; } else if (! offset_in_cu_p (&cu->header, offset)) @@ -10779,15 +10774,67 @@ *ref_cu = target_cu; temp_die.offset = offset; - die = htab_find_with_hash (target_cu->die_hash, &temp_die, offset); - if (die) - return die; + return htab_find_with_hash (target_cu->die_hash, &temp_die, offset); +} - not_found: +/* Follow reference attribute ATTR of SRC_DIE. + On entry *REF_CU is the CU of SRC_DIE. + On exit *REF_CU is the CU of the result. */ - error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " - "at 0x%x [in module %s]"), - offset, src_die->offset, cu->objfile->name); +static struct die_info * +follow_die_ref (struct die_info *src_die, struct attribute *attr, + struct dwarf2_cu **ref_cu) +{ + unsigned int offset = dwarf2_get_ref_die_offset (attr); + struct dwarf2_cu *cu = *ref_cu; + struct die_info *die; + + die = follow_die_offset (offset, ref_cu); + if (!die) + error (_("Dwarf Error: Cannot find DIE at 0x%x referenced from DIE " + "at 0x%x [in module %s]"), + offset, src_die->offset, cu->objfile->name); + + return die; +} + +/* Return DWARF block and its CU referenced by OFFSET at PER_CU. Returned + value is intended for DW_OP_call*. */ + +struct dwarf2_locexpr_baton +dwarf2_fetch_die_location_block (unsigned int offset, + struct dwarf2_per_cu_data *per_cu) +{ + struct dwarf2_cu *cu = per_cu->cu; + struct die_info *die; + struct attribute *attr; + struct dwarf2_locexpr_baton retval; + + die = follow_die_offset (offset, &cu); + if (!die) + error (_("Dwarf Error: Cannot find DIE at 0x%x referenced in module %s"), + offset, per_cu->cu->objfile->name); + + attr = dwarf2_attr (die, DW_AT_location, cu); + if (!attr) + { + /* DWARF: "If there is no such attribute, then there is no effect.". */ + + retval.data = NULL; + retval.size = 0; + } + else + { + if (!attr_form_is_block (attr)) + error (_("Dwarf Error: DIE at 0x%x referenced in module %s " + "is neither DW_FORM_block* nor DW_FORM_exprloc"), + offset, per_cu->cu->objfile->name); + + retval.data = DW_BLOCK (attr)->data; + retval.size = DW_BLOCK (attr)->size; + } + retval.per_cu = cu->per_cu; + return retval; } /* Follow the signature attribute ATTR in SRC_DIE. --- src/gdb/testsuite/ChangeLog 2010/06/07 16:11:33 1.2320 +++ src/gdb/testsuite/ChangeLog 2010/06/07 19:55:33 1.2321 @@ -1,3 +1,8 @@ +2010-06-07 Jan Kratochvil + + Test PR 10640. + * gdb.dwarf2/dw2-op-call.exp, gdb.dwarf2/dw2-op-call.S: New. + 2010-06-07 Sami Wagiaalla * gdb.cp/koenig.exp: Test for ADL operators. --- src/gdb/testsuite/gdb.dwarf2/dw2-op-call.S +++ src/gdb/testsuite/gdb.dwarf2/dw2-op-call.S 2010-06-07 19:56:46.801150000 +0000 @@ -0,0 +1,119 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2009 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Test DW_OP_call2 and DW_OP_call4, PR gdb/10640. */ + + .section .data +array1: .2byte 1 +array2: .2byte 2 +array3: .2byte 3 + + .section .debug_info +.Lcu1_begin: + /* CU header */ + .4byte .Lcu1_end - .Lcu1_start /* Length of Compilation Unit */ +.Lcu1_start: + .2byte 2 /* DWARF Version */ + .4byte .Labbrev1_begin /* Offset into abbrev section */ + .byte 4 /* Pointer size */ + + /* CU die */ + .uleb128 1 /* Abbrev: DW_TAG_compile_unit */ + .ascii "file1.txt\0" /* DW_AT_name */ + .ascii "GNU C 3.3.3\0" /* DW_AT_producer */ + .byte 2 /* DW_LANG_C (C) */ + +.L2byte_type: + .uleb128 2 /* Abbrev: DW_TAG_base_type */ + .ascii "2byte\0" /* DW_AT_name */ + .byte 2 /* DW_AT_byte_size */ + .byte 7 /* DW_AT_encoding: DW_ATE_unsigned */ + +.Larray1: + .uleb128 3 /* Abbrev: DW_TAG_variable */ + .ascii "array1\0" /* DW_AT_name */ + .4byte .L2byte_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 3 /* DW_OP_addr */ + .4byte array /* */ +2: + + .uleb128 3 /* Abbrev: DW_TAG_variable */ + .ascii "array2\0" /* DW_AT_name */ + .4byte .L2byte_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 0x98 /* DW_OP_call2 */ + .2byte .Larray1-.Lcu1_begin /* */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 array2-array1 /* */ +2: + + .uleb128 3 /* Abbrev: DW_TAG_variable */ + .ascii "array3\0" /* DW_AT_name */ + .4byte .L2byte_type-.Lcu1_begin /* DW_AT_type */ + .byte 2f - 1f /* DW_AT_location */ +1: .byte 0x99 /* DW_OP_call4 */ + .4byte .Larray1-.Lcu1_begin /* */ + .byte 0x23 /* DW_OP_plus_uconst */ + .uleb128 array3-array1 /* */ +2: + + .byte 0 /* End of children of CU */ + +.Lcu1_end: + +/* Abbrev table */ + .section .debug_abbrev +.Labbrev1_begin: + .uleb128 1 /* Abbrev code */ + .uleb128 0x11 /* DW_TAG_compile_unit */ + .byte 1 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x25 /* DW_AT_producer */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x13 /* DW_AT_language */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 2 /* Abbrev code */ + .uleb128 0x24 /* DW_TAG_base_type */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0xb /* DW_AT_byte_size */ + .uleb128 0xb /* DW_FORM_data1 */ + .uleb128 0x3e /* DW_AT_encoding */ + .uleb128 0xb /* DW_FORM_data1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .uleb128 3 /* Abbrev code */ + .uleb128 0x34 /* DW_TAG_variable */ + .byte 0 /* has_children */ + .uleb128 0x3 /* DW_AT_name */ + .uleb128 0x8 /* DW_FORM_string */ + .uleb128 0x49 /* DW_AT_type */ + .uleb128 0x13 /* DW_FORM_ref4 */ + .uleb128 0x2 /* DW_AT_location */ + .uleb128 0xa /* DW_FORM_block1 */ + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ + + .byte 0x0 /* Terminator */ + .byte 0x0 /* Terminator */ --- src/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp +++ src/gdb/testsuite/gdb.dwarf2/dw2-op-call.exp 2010-06-07 19:56:47.302709000 +0000 @@ -0,0 +1,41 @@ +# Copyright 2009 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# Test DW_OP_call2 and DW_OP_call4, PR gdb/10640. + +# This test can only be run on targets which support DWARF-2 and use gas. +# For now pick a sampling of likely targets. +if {![istarget *-*-linux*] + && ![istarget *-*-gnu*] + && ![istarget *-*-elf*] + && ![istarget *-*-openbsd*] + && ![istarget arm-*-eabi*] + && ![istarget powerpc-*-eabi*]} { + return 0 +} + +set testfile "dw2-op-call" +set srcfile ${testfile}.S +set executable ${testfile}.x + +if { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${objdir}/${subdir}/${executable}" object {nodebug}] != "" } { + return -1 +} + +clean_restart $executable + +gdb_test "p array1" " = 1" +gdb_test "p array2" " = 2" "array2 using DW_OP_call2" +gdb_test "p array3" " = 3" "array3 using DW_OP_call4"