From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 26826 invoked by alias); 10 Feb 2005 09:55:56 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 26673 invoked from network); 10 Feb 2005 09:55:37 -0000 Received: from unknown (HELO mail.codesourcery.com) (65.74.133.9) by sourceware.org with SMTP; 10 Feb 2005 09:55:37 -0000 Received: (qmail 27018 invoked from network); 10 Feb 2005 09:55:35 -0000 Received: from localhost (HELO ?192.168.189.167?) (nathan@127.0.0.1) by mail.codesourcery.com with SMTP; 10 Feb 2005 09:55:35 -0000 Message-ID: <420B2F90.4060403@codesourcery.com> Date: Thu, 10 Feb 2005 13:53:00 -0000 From: Nathan Sidwell Organization: Codesourcery LLC User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.7.3) Gecko/20040913 MIME-Version: 1.0 To: gdb-patches@sources.redhat.com CC: Paul Brook Subject: [patch] Dwarf2 virtual frame pointer Content-Type: multipart/mixed; boundary="------------030505020104060107040602" X-SW-Source: 2005-02/txt/msg00085.txt.bz2 This is a multi-part message in MIME format. --------------030505020104060107040602 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 715 Hi, The default frame pointer accessor only copes with a fixed frame pointer. I've added a dwarf2_virtual_frame_pointer function, which can be enabled with set_gdbarch_virtual_frame_pointer (gdbarch, dwarf2_virtual_frame_pointer) It executes the cfa for the supplied PC and determines which register is the frame pointer at that point. I've not hooked it into any existing architectures, but verified its functionality on an unrealeased architecture where $sp or $fp might be the relevent register. I've tested on i686-pc-linux-gnu also, ok? nathan -- Nathan Sidwell :: http://www.codesourcery.com :: CodeSourcery LLC nathan@codesourcery.com :: http://www.planetfall.pwp.blueyonder.co.uk --------------030505020104060107040602 Content-Type: text/plain; name="dwarf-vfp.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="dwarf-vfp.patch" Content-length: 6125 2005-02-10 Nathan Sidwell * dwarf2-frame.c: #include arch-utils.h (execute_cfa_program): Take pc argument, not next_frame. Adjust. (dwarf2_frame_cache): Adjust execute_cfa_program calls. (dwarf2_virtual_frame_pointer): New. * dwarf2-frame.h (dwarf2_virtual_frame_pointer): New. Index: dwarf2-frame.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.c,v retrieving revision 1.47 diff -c -3 -p -r1.47 dwarf2-frame.c *** dwarf2-frame.c 20 Nov 2004 10:10:17 -0000 1.47 --- dwarf2-frame.c 10 Feb 2005 09:13:58 -0000 *************** *** 32,37 **** --- 32,38 ---- #include "symtab.h" #include "objfiles.h" #include "regcache.h" + #include "arch-utils.h" #include "gdb_assert.h" #include "gdb_string.h" *************** execute_stack_op (unsigned char *exp, UL *** 266,275 **** static void execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end, ! struct frame_info *next_frame, ! struct dwarf2_frame_state *fs) { - CORE_ADDR pc = frame_pc_unwind (next_frame); int bytes_read; while (insn_ptr < insn_end && fs->pc <= pc) --- 267,274 ---- static void execute_cfa_program (unsigned char *insn_ptr, unsigned char *insn_end, ! CORE_ADDR pc, struct dwarf2_frame_state *fs) { int bytes_read; while (insn_ptr < insn_end && fs->pc <= pc) *************** dwarf2_frame_cache (struct frame_info *n *** 599,604 **** --- 598,604 ---- struct dwarf2_frame_cache *cache; struct dwarf2_frame_state *fs; struct dwarf2_fde *fde; + CORE_ADDR pc; if (*this_cache) return *this_cache; *************** dwarf2_frame_cache (struct frame_info *n *** 628,634 **** reliable the method is though; there is the potential for the register state pre-call being different to that on return. */ fs->pc = frame_unwind_address_in_block (next_frame); ! /* Find the correct FDE. */ fde = dwarf2_frame_find_fde (&fs->pc); gdb_assert (fde != NULL); --- 628,635 ---- reliable the method is though; there is the potential for the register state pre-call being different to that on return. */ fs->pc = frame_unwind_address_in_block (next_frame); ! pc = frame_pc_unwind (next_frame); ! /* Find the correct FDE. */ fde = dwarf2_frame_find_fde (&fs->pc); gdb_assert (fde != NULL); *************** dwarf2_frame_cache (struct frame_info *n *** 639,653 **** fs->retaddr_column = fde->cie->return_address_register; /* First decode all the insns in the CIE. */ ! execute_cfa_program (fde->cie->initial_instructions, ! fde->cie->end, next_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->instructions, fde->end, next_frame, fs); /* Caclulate the CFA. */ switch (fs->cfa_how) --- 640,654 ---- fs->retaddr_column = fde->cie->return_address_register; /* First decode all the insns in the CIE. */ ! execute_cfa_program (fde->cie->initial_instructions, fde->cie->end, ! 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->instructions, fde->end, pc, fs); /* Caclulate the CFA. */ switch (fs->cfa_how) *************** dwarf2_frame_base_sniffer (struct frame_ *** 938,943 **** --- 939,1000 ---- return NULL; } + + /* Find the frame register that is in use at pc. */ + + void + dwarf2_virtual_frame_pointer (CORE_ADDR pc, + int *frame_regnum, LONGEST *frame_offset) + { + static CORE_ADDR cached_pc; + static int cached_regnum; + static int cached_offset; + + if (cached_pc != pc) + { + struct cleanup *old_chain; + struct gdbarch *gdbarch = current_gdbarch; /* Bleah! */ + struct dwarf2_frame_state *fs; + struct dwarf2_fde *fde; + + /* Allocate and initialize the frame state. */ + fs = XMALLOC (struct dwarf2_frame_state); + memset (fs, 0, sizeof (struct dwarf2_frame_state)); + old_chain = make_cleanup (dwarf2_frame_state_free, fs); + + fs->pc = pc; + + /* Find the correct FDE. */ + fde = dwarf2_frame_find_fde (&fs->pc); + if (!fde) + { + legacy_virtual_frame_pointer (pc, frame_regnum, frame_offset); + return; + } + + /* 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; + + /* First decode all the insns in the CIE. */ + execute_cfa_program (fde->cie->initial_instructions, fde->cie->end, + pc, fs); + + /* Then decode the insns in the FDE up to our target PC. */ + execute_cfa_program (fde->instructions, fde->end, pc, fs); + + cached_pc = pc; + cached_regnum = DWARF2_REG_TO_REGNUM (fs->cfa_reg); + cached_offset = 0; + + do_cleanups (old_chain); + } + + *frame_regnum = cached_regnum; + *frame_offset = cached_offset; + } + /* A minimal decoding of DWARF2 compilation units. We only decode what's needed to get to the call frame information. */ Index: dwarf2-frame.h =================================================================== RCS file: /cvs/src/src/gdb/dwarf2-frame.h,v retrieving revision 1.7 diff -c -3 -p -r1.7 dwarf2-frame.h *** dwarf2-frame.h 7 Nov 2004 21:16:11 -0000 1.7 --- dwarf2-frame.h 10 Feb 2005 09:13:58 -0000 *************** extern const struct frame_base * *** 103,106 **** --- 103,109 ---- void dwarf2_frame_build_info (struct objfile *objfile); + void dwarf2_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum, + LONGEST *frame_offset); + #endif /* dwarf2-frame.h */ --------------030505020104060107040602--