This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] Darwin: recognize signal frames


Hi,

this patch adds the bit to correctly recognize signal frames.

Although Darwin use signal trampolines that have dwarf-2 CFI, we can't use
them as the trampoline will only be recognized as a normal frame.

This patch fixes about 50 regressions in sigstep.exp.

Tristan.

2008-12-05  Tristan Gingold  <gingold@adacore.com>

	* i386-darwin-tdep.c (darwin_sigtramp_p): New function.
	(i386_darwin_sigcontext_addr): Ditto.
	(amd64_darwin_sigcontext_addr): Ditto.
	(darwin_dwarf_signal_frame_p): Ditto.
	(i386_darwin_init_abi): Handle signal frames, use the const for
	sc_num_regs.
	(x86_darwin_init_abi_64): Ditto.


diff -c -p -r1.1 i386-darwin-tdep.c
*** i386-darwin-tdep.c	27 Nov 2008 09:23:01 -0000	1.1
--- i386-darwin-tdep.c	5 Dec 2008 15:16:28 -0000
***************
*** 39,44 ****
--- 39,45 ----
  #include "frame.h"
  #include "gdb_assert.h"
  #include "i386-darwin-tdep.h"
+ #include "dwarf2-frame.h"
  
  /* Offsets into the struct i386_thread_state where we'll find the saved regs.
     From <mach/i386/thread_status.h> and i386-tdep.h.  */
*************** int amd64_darwin_thread_state_reg_offset
*** 98,103 ****
--- 99,180 ----
  const int amd64_darwin_thread_state_num_regs = 
    ARRAY_SIZE (amd64_darwin_thread_state_reg_offset);
  
+ 
+ /* Return whether THIS_FRAME corresponds to a Darwin sigtramp
+    routine.  */
+ 
+ static int
+ darwin_sigtramp_p (struct frame_info *this_frame)
+ {
+   CORE_ADDR pc = get_frame_pc (this_frame);
+   char *name;
+ 
+   find_pc_partial_function (pc, &name, NULL, NULL);
+ 
+   return name && strcmp (name, "_sigtramp") == 0;
+ }
+ 
+ /* Assuming THIS_FRAME is a Darwin sigtramp routine, return the
+    address of the associated sigcontext structure.  */
+ 
+ static CORE_ADDR
+ i386_darwin_sigcontext_addr (struct frame_info *this_frame)
+ {
+   CORE_ADDR bp;
+   CORE_ADDR si;
+   gdb_byte buf[4];
+ 
+   get_frame_register (this_frame, I386_EBP_REGNUM, buf);
+   bp = extract_unsigned_integer (buf, 4);
+ 
+   /* A pointer to the ucontext is passed as the fourth argument
+      to the signal handler.  */
+   read_memory (bp + 24, buf, 4);
+   si = extract_unsigned_integer (buf, 4);
+ 
+   /* The pointer to mcontext is at offset 28.  */
+   read_memory (si + 28, buf, 4);
+ 
+   /* First register (eax) is at offset 12.  */
+   return extract_unsigned_integer (buf, 4) + 12;
+ }
+ 
+ static CORE_ADDR
+ amd64_darwin_sigcontext_addr (struct frame_info *this_frame)
+ {
+   CORE_ADDR rbx;
+   CORE_ADDR si;
+   gdb_byte buf[8];
+ 
+   /* A pointer to the ucontext is passed as the fourth argument
+      to the signal handler, which is saved in rbx.  */
+   get_frame_register (this_frame, AMD64_RBX_REGNUM, buf);
+   rbx = extract_unsigned_integer (buf, 8);
+ 
+   /* The pointer to mcontext is at offset 48.  */
+   read_memory (rbx + 48, buf, 8);
+ 
+   /* First register (rax) is at offset 16.  */
+   return extract_unsigned_integer (buf, 8) + 16;
+ }
+ 
+ /* Return true if the PC of THIS_FRAME is in a signal trampoline which
+    may have DWARF-2 CFI.
+ 
+    On Darwin, signal trampolines have DWARF-2 CFI but it has only one FDE
+    that covers only the indirect call to the user handler.
+    Without this function, the frame is recognized as a normal frame which is
+    not expected.  With this function, the frame is not recognized (because
+    the pc is not adjusted and points to the next instruction).  As a
+    consequence we have to use the x86 sigtramp frame unwinders.  */
+ 
+ static int
+ darwin_dwarf_signal_frame_p (struct gdbarch *gdbarch,
+ 				  struct frame_info *this_frame)
+ {
+   return darwin_sigtramp_p (this_frame);
+ }
+ 
  static void
  i386_darwin_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  {
*************** i386_darwin_init_abi (struct gdbarch_inf
*** 107,117 ****
    tdep->num_xmm_regs = I386_NUM_XREGS - 1;
    set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
  
    tdep->struct_return = reg_struct_return;
  
!   tdep->sigcontext_addr = NULL;
    tdep->sc_reg_offset = i386_darwin_thread_state_reg_offset;
!   tdep->sc_num_regs = 16;
  
    tdep->jb_pc_offset = 20;
  }
--- 184,197 ----
    tdep->num_xmm_regs = I386_NUM_XREGS - 1;
    set_gdbarch_num_regs (gdbarch, I386_SSE_NUM_REGS);
  
+   dwarf2_frame_set_signal_frame_p (gdbarch, darwin_dwarf_signal_frame_p);
+ 
    tdep->struct_return = reg_struct_return;
  
!   tdep->sigtramp_p = darwin_sigtramp_p;
!   tdep->sigcontext_addr = i386_darwin_sigcontext_addr;
    tdep->sc_reg_offset = i386_darwin_thread_state_reg_offset;
!   tdep->sc_num_regs = i386_darwin_thread_state_num_regs;
  
    tdep->jb_pc_offset = 20;
  }
*************** x86_darwin_init_abi_64 (struct gdbarch_i
*** 125,134 ****
  
    tdep->struct_return = reg_struct_return;
  
!   /* We don't do signals yet.  */
!   tdep->sigcontext_addr = NULL;
    tdep->sc_reg_offset = amd64_darwin_thread_state_reg_offset;
!   tdep->sc_num_regs = ARRAY_SIZE (amd64_darwin_thread_state_reg_offset);
  
    tdep->jb_pc_offset = 148;
  }
--- 205,216 ----
  
    tdep->struct_return = reg_struct_return;
  
!   dwarf2_frame_set_signal_frame_p (gdbarch, darwin_dwarf_signal_frame_p);
! 
!   tdep->sigtramp_p = darwin_sigtramp_p;
!   tdep->sigcontext_addr = amd64_darwin_sigcontext_addr;
    tdep->sc_reg_offset = amd64_darwin_thread_state_reg_offset;
!   tdep->sc_num_regs = amd64_darwin_thread_state_num_regs;
  
    tdep->jb_pc_offset = 148;
  }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]