Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [patch] Dwarf2 virtual frame pointer
@ 2005-02-10 13:53 Nathan Sidwell
  2005-02-12 13:04 ` Mark Kettenis
  0 siblings, 1 reply; 4+ messages in thread
From: Nathan Sidwell @ 2005-02-10 13:53 UTC (permalink / raw)
  To: gdb-patches; +Cc: Paul Brook

[-- Attachment #1: Type: text/plain, Size: 715 bytes --]

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


[-- Attachment #2: dwarf-vfp.patch --]
[-- Type: text/plain, Size: 6125 bytes --]

2005-02-10  Nathan Sidwell  <nathan@codesourcery.com>

	* 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;
  }
  \f
+ 
+ /* 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;
+ }
+ \f
  /* 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 */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Dwarf2 virtual frame pointer
  2005-02-10 13:53 [patch] Dwarf2 virtual frame pointer Nathan Sidwell
@ 2005-02-12 13:04 ` Mark Kettenis
  2005-02-12 15:52   ` Nathan Sidwell
  0 siblings, 1 reply; 4+ messages in thread
From: Mark Kettenis @ 2005-02-12 13:04 UTC (permalink / raw)
  To: nathan; +Cc: gdb-patches, paul

   From: Nathan Sidwell <nathan@codesourcery.com>
   Date: Thu, 10 Feb 2005 09:55:28 +0000

   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?

Almost certainly no.  Replacing `struct frame *next_frame' with
`CORE_ADDR pc' is moving backward instead of forward.  Any functions
that starts with legacy_ should not be used in generic code like the
code in dwarf2-frame.c.

Can you explains what you're trying to accomplish?

If you're trying to use the DWARF CFI for anything else than unwinding
the stack, like finding out whether the location of local variables is
relative to $sp or $fp then rethink your strategy.  This is not what
the DWARF CFI is for.

Mark


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Dwarf2 virtual frame pointer
  2005-02-12 13:04 ` Mark Kettenis
@ 2005-02-12 15:52   ` Nathan Sidwell
  2005-02-14  9:41     ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Nathan Sidwell @ 2005-02-12 15:52 UTC (permalink / raw)
  To: Mark Kettenis; +Cc: gdb-patches, paul

Mark Kettenis wrote:

> Almost certainly no.  Replacing `struct frame *next_frame' with
> `CORE_ADDR pc' is moving backward instead of forward.  Any functions
> that starts with legacy_ should not be used in generic code like the
> code in dwarf2-frame.c.
oh, ok.

> Can you explains what you're trying to accomplish?
> 
> If you're trying to use the DWARF CFI for anything else than unwinding
> the stack, like finding out whether the location of local variables is
> relative to $sp or $fp then rethink your strategy.  This is not what
> the DWARF CFI is for.

ok.  Then how do I find out that information? The compiler (gcc 3.4) is
emitting DW_OP_fbreg location information for the local variables, should
it be emitting something else?

nathan
-- 
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [patch] Dwarf2 virtual frame pointer
  2005-02-12 15:52   ` Nathan Sidwell
@ 2005-02-14  9:41     ` Daniel Jacobowitz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2005-02-14  9:41 UTC (permalink / raw)
  To: Nathan Sidwell; +Cc: Mark Kettenis, gdb-patches, paul

On Sat, Feb 12, 2005 at 01:04:28PM +0000, Nathan Sidwell wrote:
> Mark Kettenis wrote:
> 
> >Almost certainly no.  Replacing `struct frame *next_frame' with
> >`CORE_ADDR pc' is moving backward instead of forward.  Any functions
> >that starts with legacy_ should not be used in generic code like the
> >code in dwarf2-frame.c.
> oh, ok.
> 
> >Can you explains what you're trying to accomplish?
> >
> >If you're trying to use the DWARF CFI for anything else than unwinding
> >the stack, like finding out whether the location of local variables is
> >relative to $sp or $fp then rethink your strategy.  This is not what
> >the DWARF CFI is for.
> 
> ok.  Then how do I find out that information? The compiler (gcc 3.4) is
> emitting DW_OP_fbreg location information for the local variables, should
> it be emitting something else?

DW_OP_fbreg is fine.  It's not relative to the CFA.  It's relative to
the value of DW_AT_frame_base in the containing function.

Recent versions of GCC can emit location lists for DW_AT_frame_base,
making it just about as accurate as the CFA.  I'm not sure when that
was introduced.

-- 
Daniel Jacobowitz
CodeSourcery, LLC


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-02-12 16:05 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-10 13:53 [patch] Dwarf2 virtual frame pointer Nathan Sidwell
2005-02-12 13:04 ` Mark Kettenis
2005-02-12 15:52   ` Nathan Sidwell
2005-02-14  9:41     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox