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 */