From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 11439 invoked by alias); 16 Feb 2011 20:18:54 -0000 Received: (qmail 11429 invoked by uid 22791); 16 Feb 2011 20:18:51 -0000 X-SWARE-Spam-Status: No, hits=-6.9 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,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; Wed, 16 Feb 2011 20:18:46 +0000 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p1GKIaWa003970 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 16 Feb 2011 15:18:36 -0500 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id p1GKIaPs019898; Wed, 16 Feb 2011 15:18:36 -0500 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p1GKIZxo023649; Wed, 16 Feb 2011 15:18:35 -0500 Received: by opsy.redhat.com (Postfix, from userid 500) id D229F378CAD; Wed, 16 Feb 2011 13:18:34 -0700 (MST) From: Tom Tromey To: Pedro Alves Cc: gdb-patches@sourceware.org, Jan Kratochvil Subject: FYI: handle DW_OP_call_frame_cfa in AX compiler (Was: [unavailable values part 1, 16/17] don't merge almost but not quite adjacent memory ranges to collect) References: <201102071435.20804.pedro@codesourcery.com> <20110214120116.GI2454@host1.dyn.jankratochvil.net> <201102161303.16592.pedro@codesourcery.com> Date: Wed, 16 Feb 2011 21:01:00 -0000 In-Reply-To: (Tom Tromey's message of "Wed, 16 Feb 2011 11:07:29 -0700") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii 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: 2011-02/txt/msg00388.txt.bz2 Here is a patch to implement compilation of DW_OP_call_frame_cfa to agent expressions. Let me know what you think. It at least let collection.exp run here. I'll do a full regression test against gdbserver sometime soon. Tom 2011-02-16 Tom Tromey * dwarf2loc.c (compile_dwarf_to_ax) : Use dwarf2_compile_cfa_to_ax. * dwarf2-frame.h (dwarf2_compile_ftype): New typedef. (dwarf2_compile_cfa_to_ax): Declare. * dwarf2-frame.c: Include ax.h. (execute_cfa_program): Remove 'this_frame' argument; 'gdbarch' and 'pc'. (dwarf2_compile_cfa_to_ax): New function. (dwarf2_frame_cache): Update. diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c index 48f47af..014da44 100644 --- a/gdb/dwarf2-frame.c +++ b/gdb/dwarf2-frame.c @@ -38,6 +38,7 @@ #include "complaints.h" #include "dwarf2-frame.h" +#include "ax.h" struct comp_unit; @@ -428,13 +429,11 @@ Not implemented: computing unwound register using explicit value operator")); static void execute_cfa_program (struct dwarf2_fde *fde, const gdb_byte *insn_ptr, - const gdb_byte *insn_end, struct frame_info *this_frame, - struct dwarf2_frame_state *fs) + const gdb_byte *insn_end, struct gdbarch *gdbarch, + CORE_ADDR pc, struct dwarf2_frame_state *fs) { int eh_frame_p = fde->eh_frame_p; - CORE_ADDR pc = get_frame_pc (this_frame); int bytes_read; - struct gdbarch *gdbarch = get_frame_arch (this_frame); enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); while (insn_ptr < insn_end && fs->pc <= pc) @@ -902,6 +901,85 @@ dwarf2_frame_find_quirks (struct dwarf2_frame_state *fs, } +void +dwarf2_compile_cfa_to_ax (struct agent_expr *expr, struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + dwarf2_compile_ftype compile, + struct dwarf2_per_cu_data *data) +{ + const int num_regs = gdbarch_num_regs (gdbarch) + + gdbarch_num_pseudo_regs (gdbarch); + struct dwarf2_fde *fde; + CORE_ADDR text_offset, cfa; + struct dwarf2_frame_state fs; + int addr_size; + + memset (&fs, 0, sizeof (struct dwarf2_frame_state)); + + fs.pc = pc; + + /* Find the correct FDE. */ + fde = dwarf2_frame_find_fde (&fs.pc, &text_offset); + if (fde == NULL) + error (_("Could not compute CFA; needed to translate this expression")); + + /* Extract any interesting information from the CIE. */ + fs.data_align = fde->cie->data_alignment_factor; + fs.code_align = fde->cie->code_alignment_factor; + fs.retaddr_column = fde->cie->return_address_register; + addr_size = fde->cie->addr_size; + + /* Check for "quirks" - known bugs in producers. */ + dwarf2_frame_find_quirks (&fs, fde); + + /* First decode all the insns in the CIE. */ + execute_cfa_program (fde, fde->cie->initial_instructions, + fde->cie->end, gdbarch, pc, &fs); + + /* Save the initialized register set. */ + fs.initial = fs.regs; + fs.initial.reg = dwarf2_frame_state_copy_regs (&fs.regs); + + /* Then decode the insns in the FDE up to our target PC. */ + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, pc, &fs); + + /* Calculate the CFA. */ + switch (fs.regs.cfa_how) + { + case CFA_REG_OFFSET: + { + int regnum = gdbarch_dwarf2_reg_to_regnum (gdbarch, fs.regs.cfa_reg); + + if (regnum == -1) + error (_("Unable to access DWARF register number %d"), + (int) fs.regs.cfa_reg); /* FIXME */ + ax_reg (expr, regnum); + + if (fs.regs.cfa_offset != 0) + { + if (fs.armcc_cfa_offsets_reversed) + ax_const_l (expr, - fs.regs.cfa_offset); + else + ax_const_l (expr, fs.regs.cfa_offset); + ax_simple (expr, aop_add); + } + } + break; + + case CFA_EXP: + ax_const_l (expr, text_offset); + (*compile) (expr, loc, gdbarch, addr_size, + fs.regs.cfa_exp, fs.regs.cfa_exp + fs.regs.cfa_exp_len, + data); + break; + + default: + internal_error (__FILE__, __LINE__, _("Unknown CFA rule.")); + } +} + + struct dwarf2_frame_cache { /* DWARF Call Frame Address. */ @@ -979,14 +1057,15 @@ dwarf2_frame_cache (struct frame_info *this_frame, void **this_cache) /* First decode all the insns in the CIE. */ execute_cfa_program (fde, fde->cie->initial_instructions, - fde->cie->end, this_frame, fs); + fde->cie->end, gdbarch, get_frame_pc (this_frame), fs); /* Save the initialized register set. */ fs->initial = fs->regs; fs->initial.reg = dwarf2_frame_state_copy_regs (&fs->regs); /* Then decode the insns in the FDE up to our target PC. */ - execute_cfa_program (fde, fde->instructions, fde->end, this_frame, fs); + execute_cfa_program (fde, fde->instructions, fde->end, gdbarch, + get_frame_pc (this_frame), fs); /* Calculate the CFA. */ switch (fs->regs.cfa_how) diff --git a/gdb/dwarf2-frame.h b/gdb/dwarf2-frame.h index bf7134d..e8a3e85 100644 --- a/gdb/dwarf2-frame.h +++ b/gdb/dwarf2-frame.h @@ -26,6 +26,9 @@ struct gdbarch; struct objfile; struct frame_info; +struct dwarf2_per_cu_data; +struct agent_expr; +struct axs_value; /* Register rule. */ @@ -118,4 +121,26 @@ extern const struct frame_base * CORE_ADDR dwarf2_frame_cfa (struct frame_info *this_frame); +/* Type of the compilation function for dwarf2_compile_cfa_to_ax. */ + +typedef void (*dwarf2_compile_ftype) (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *arch, + unsigned int addr_size, + const gdb_byte *op_ptr, + const gdb_byte *op_end, + struct dwarf2_per_cu_data *data); + +/* Update the agent expression EXPR with code to compute the CFA for a + frame at PC. GDBARCH is the frame architecture. The COMPILE + function can be used to compile a location expression into EXPR. + DATA is passed to COMPILE if needed. */ + +extern void dwarf2_compile_cfa_to_ax (struct agent_expr *expr, + struct axs_value *loc, + struct gdbarch *gdbarch, + CORE_ADDR pc, + dwarf2_compile_ftype compile, + struct dwarf2_per_cu_data *data); + #endif /* dwarf2-frame.h */ diff --git a/gdb/dwarf2loc.c b/gdb/dwarf2loc.c index ac786e4..8840a81 100644 --- a/gdb/dwarf2loc.c +++ b/gdb/dwarf2loc.c @@ -1926,7 +1926,9 @@ compile_dwarf_to_ax (struct agent_expr *expr, struct axs_value *loc, break; case DW_OP_call_frame_cfa: - unimplemented (op); + dwarf2_compile_cfa_to_ax (expr, loc, arch, expr->scope, + compile_dwarf_to_ax, per_cu); + loc->kind = axs_lvalue_memory; break; case DW_OP_GNU_push_tls_address: