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]

[RFC 3/4] - Adjust all archs/targets to new interface


This updates all targets to also extract the SP out of the
jmp_buf.

I peeked into glibc's, netbsd's, openbsd's and freebsd's sources
to get the SP offsets.  I also google.com/codesearch'ed quite a bit.
I looked manually for the offsets in cygwin, mingw32, and WinCE.

There are a couple I couldn't find any reference or sources to
look at, these were: 

- alpha-OSF1, I infered from the alpha BSD targets.
- QNX NTO, I guessed based on the other i386 ports that used
the same JB_PC.

- arm-linux: either we have currently the wrong jb_pc, or there must
  be some switch that changes the jmp_buf format I'm not aware of.  I
  took the values in the patch from glibc, and tested it with a
  qemu in several multilibs configurations, including -mthumb.
  Inspecting manually revealed that indeed the these are the
  correct values, and running the new longjmp.exp test passed cleanly.

- go32/djgpp claims jb_pc == 36, but, that's not what I see
  in the sources:
http://www.delorie.com/bin/cvsweb.cgi/djgpp/src/libc/ansi/setjmp/setjmp.S?rev=1.3
  Patch updates jb_pc to 32 as per that link.

Of course, I may have gotten a few wrong.

-- 
Pedro Alves
2008-04-09  Pedro Alves  <pedro@codesourcery.com>

	* alpha-tdep.c (alplha_get_longjmp_target): Add SP parameter.
	Extract the SP out of the jmp_buf.
	(alpha_gdbarch_init): Initialize tdep->jb_sp as -1.  Adjust check
	for longjmp support.

	* arm-linux-tdep.c (ARM_LINUX_JB_PC): Set to 9.
	(ARM_LINUX_JB_SP): New.
	(arm_linux_init_abi): Also set tdep->jb_sp.

	* arm-tdep.c (arm_get_longjmp_target): Add SP parameter.  Extract
	the SP out of the jmp_buf.
	(arm_gdbarch_init): Initialize tdep->jb_sp as -1.  Adjust check
	for longjmp support.

	* arm-wince-tdep.c (ARM_WINCE_JB_SP): New.
	(arm_wince_init_abi): Set tdep->jb_sp.

	* m68k-tdep.c (m68k_get_longjmp_target): Add DESP_SP parameter.
	Adjust check for longjmp support.  Extract the SP out of the
	jmp_buf and store it in *DEST_SP.
	(m68k_gdbarch_init): Set tdep->jb_sp.  Adjust check for longjmp support.

	* m68k-tdep.h (struct gdbarch_tdep): Add jb_sp field.

	* m68kbsd-tdep.c (m68kbsd_init_abi): Set tdep->jb_sp.

	* m68klinux-tdep.c (M68K_LINUX_JB_SP): New.
	(m68k_linux_init_abi): Set tdep->jb_sp.

	* mips-linux-tdep.c (MIPS_LINUX_JB_SP): New.
	(mips_linux_get_longjmp_target): Add SP parameter.  Extract the SP
	out of the jmp_buf.
	(MIPS64_LINUX_JB_SP): New.
	(mips64_linux_get_longjmp_target): Add SP parameter.  Extract the
	SP out of the jmp_buf.

	* mipsnbsd-tdep.c (NBSD_MIPS_JB_ELEMENT_SIZE): Replace
	current_gdbarch by gdbarch.
	(NBSD_MIPS_JB_OFFSET): Rename to ...
	(NBSD_MIPS_JB_OFFSET_PC): ... this.
	(mipsnbsd_get_longjmp_target): Add DEST_SP parameter.  Extract the SP
	out of the jmp_buf and store it in *DEST_SP.

	* alpha-linux-tdep.c (alpha_linux_init_abi): Correct tdep->jb_pc,
	and set tdep->jb_sp.

	* alpha-osf1-tdep.c (alpha_osf1_init_abi): Set tdep->jb_sp.

	* alphafbsd-tdep.c (alphafbsd_init_abi): Set tdep->jb_sp.

	* alphanbsd-tdep.c (alphanbsd_init_abi): Set tdep->jb_sp.

	* alphaobsd-tdep.c (alphaobsd_init_abi): Set tdep->jb_sp.
	
	* amd64fbsd-tdep.c (amd64fbsd_init_abi): Set tdep->jb_pc_offset
	and tdep->jb_sp_offset.

	* amd64nbsd-tdep.c (amd64nbsd_init_abi): Set tdep->jb_sp_offset.

	* armnbsd-tdep.c (ARM_NBSD_JB_SP): New.
	(arm_netbsd_init_abi_common): Set tdep->jb_sp.

	* armobsd-tdep.c (armobsd_init_abi): Set tdep->jb_sp.
	* i386-nto-tdep.c (i386nto_init_abi): Set tdep->jb_sp_offset.

	* i386bsd-tdep.c (i386bsd_init_abi): Set tdep->jb_pc_offset.

	* alpha-tdep.h (struct gdbarch_tdep): Add jb_sp member.

	* arm-tdep.h (struct gdbarch_tdep): Add jb_sp member.

	* i386-tdep.c (i386_get_longjmp_target): Add DEST_SP
	member. Extract the SP out of the jmp_buf and store it in
	*DEST_SP.
	(i386_svr4_init_abi): Set tdep->jb_sp_offset.
	(i386_go32_init_abi): Fix tdep->jb_pc_offset and set
	tdep->jb_sp_offset.
	(i386_gdbarch_init): Initialize tdep->jb_sp_offset as -1.

	* i386-tdep.h (struct gdbarch_tdep): Add jb_sp_offset member.
	(i386_get_longjmp_target): Declare.

	* i386-cygwin-tdep.c (i386_cygwin_init_abi): Set
	tdep->jb_sp_offset and tdep->jb_pc_offset.

	* i386-linux-tdep.c (i386_linux_init_abi): Set tdep->jb_sp_offset.

	* amd64-tdep.c (amd64_get_longjmp_target): Add SP parameter.
	Extract the SP out of the jmp_buf.  Adjust longjmp support check.

	* amd64-tdep.h (amd64_get_longjmp_target): Add SP parameter.

---
 gdb/alpha-linux-tdep.c |    5 ++++-
 gdb/alpha-osf1-tdep.c  |    1 +
 gdb/alpha-tdep.c       |   14 +++++++++++---
 gdb/alpha-tdep.h       |    7 ++++---
 gdb/alphafbsd-tdep.c   |    1 +
 gdb/alphanbsd-tdep.c   |    1 +
 gdb/alphaobsd-tdep.c   |    1 +
 gdb/amd64-tdep.c       |   17 ++++++++++++-----
 gdb/amd64-tdep.h       |    3 ++-
 gdb/amd64fbsd-tdep.c   |    3 +++
 gdb/amd64nbsd-tdep.c   |    1 +
 gdb/arm-linux-tdep.c   |    4 +++-
 gdb/arm-tdep.c         |   14 ++++++++++----
 gdb/arm-tdep.h         |    7 ++++---
 gdb/arm-wince-tdep.c   |    2 ++
 gdb/armnbsd-tdep.c     |    2 ++
 gdb/armobsd-tdep.c     |    1 +
 gdb/i386-cygwin-tdep.c |    9 +++++++++
 gdb/i386-linux-tdep.c  |    1 +
 gdb/i386-nto-tdep.c    |    1 +
 gdb/i386-tdep.c        |   17 +++++++++++++----
 gdb/i386-tdep.h        |    5 ++++-
 gdb/i386bsd-tdep.c     |    1 +
 gdb/m68k-tdep.c        |   19 +++++++++++++++----
 gdb/m68k-tdep.h        |    5 +++--
 gdb/m68kbsd-tdep.c     |    1 +
 gdb/m68klinux-tdep.c   |    2 ++
 gdb/mips-linux-tdep.c  |   24 ++++++++++++++++++++++--
 gdb/mipsnbsd-tdep.c    |   24 +++++++++++++++++++-----
 29 files changed, 154 insertions(+), 39 deletions(-)

Index: src/gdb/alpha-tdep.c
===================================================================
--- src.orig/gdb/alpha-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alpha-tdep.c	2008-04-09 13:29:36.000000000 +0100
@@ -718,7 +718,8 @@ alpha_skip_prologue (struct gdbarch *gdb
    into the "pc".  This routine returns true on success.  */
 
 static int
-alpha_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+alpha_get_longjmp_target (struct frame_info *frame,
+			  CORE_ADDR *pc, CORE_ADDR *sp)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
   CORE_ADDR jb_addr;
@@ -731,6 +732,12 @@ alpha_get_longjmp_target (struct frame_i
     return 0;
 
   *pc = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size);
+
+  if (target_read_memory (jb_addr + (tdep->jb_sp * tdep->jb_elt_size),
+			  raw_buffer, tdep->jb_elt_size))
+    return 0;
+
+  *sp = extract_unsigned_integer (raw_buffer, tdep->jb_elt_size);
   return 1;
 }
 
@@ -1537,7 +1544,8 @@ alpha_gdbarch_init (struct gdbarch_info 
   tdep->sc_regs_offset = 4 * 8;
   tdep->sc_fpregs_offset = tdep->sc_regs_offset + 32 * 8 + 8;
 
-  tdep->jb_pc = -1;	/* longjmp support not enabled by default  */
+  /* longjmp support not enabled by default  */
+  tdep->jb_pc = tdep->jb_sp = -1;
 
   tdep->return_in_memory = alpha_return_in_memory_always;
 
@@ -1601,7 +1609,7 @@ alpha_gdbarch_init (struct gdbarch_info 
   /* Now that we have tuned the configuration, set a few final things
      based on what the OS ABI has told us.  */
 
-  if (tdep->jb_pc >= 0)
+  if (tdep->jb_pc >= 0 && tdep->jb_sp >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, alpha_get_longjmp_target);
 
   frame_unwind_append_sniffer (gdbarch, alpha_sigtramp_frame_sniffer);
Index: src/gdb/arm-linux-tdep.c
===================================================================
--- src.orig/gdb/arm-linux-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/arm-linux-tdep.c	2008-04-09 01:24:43.000000000 +0100
@@ -71,7 +71,8 @@ static const char arm_linux_thumb_le_bre
 
 /* Description of the longjmp buffer.  */
 #define ARM_LINUX_JB_ELEMENT_SIZE	INT_REGISTER_SIZE
-#define ARM_LINUX_JB_PC			21
+#define ARM_LINUX_JB_PC			9
+#define ARM_LINUX_JB_SP			8
 
 /*
    Dynamic Linking on ARM GNU/Linux
@@ -619,6 +620,7 @@ arm_linux_init_abi (struct gdbarch_info 
     tdep->fp_model = ARM_FLOAT_FPA;
 
   tdep->jb_pc = ARM_LINUX_JB_PC;
+  tdep->jb_sp = ARM_LINUX_JB_SP;
   tdep->jb_elt_size = ARM_LINUX_JB_ELEMENT_SIZE;
 
   set_solib_svr4_fetch_link_map_offsets
Index: src/gdb/arm-tdep.c
===================================================================
--- src.orig/gdb/arm-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/arm-tdep.c	2008-04-09 13:33:26.000000000 +0100
@@ -2399,7 +2399,8 @@ arm_return_value (struct gdbarch *gdbarc
 
 
 static int
-arm_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+arm_get_longjmp_target (struct frame_info *frame,
+			CORE_ADDR *pc, CORE_ADDR *sp)
 {
   CORE_ADDR jb_addr;
   char buf[INT_REGISTER_SIZE];
@@ -2410,8 +2411,13 @@ arm_get_longjmp_target (struct frame_inf
   if (target_read_memory (jb_addr + tdep->jb_pc * tdep->jb_elt_size, buf,
 			  INT_REGISTER_SIZE))
     return 0;
-
   *pc = extract_unsigned_integer (buf, INT_REGISTER_SIZE);
+
+  if (target_read_memory (jb_addr + tdep->jb_sp * tdep->jb_elt_size, buf,
+			  INT_REGISTER_SIZE))
+    return 0;
+  *sp = extract_unsigned_integer (buf, INT_REGISTER_SIZE);
+
   return 1;
 }
 
@@ -2975,7 +2981,7 @@ arm_gdbarch_init (struct gdbarch_info in
 
   /* This should be low enough for everything.  */
   tdep->lowest_pc = 0x20;
-  tdep->jb_pc = -1;	/* Longjump support not enabled by default.  */
+  tdep->jb_pc = tdep->jb_sp = -1; /* Longjump support not enabled by default.  */
 
   /* The default, for both APCS and AAPCS, is to return small
      structures in registers.  */
@@ -3064,7 +3070,7 @@ arm_gdbarch_init (struct gdbarch_info in
   if (tdep->fp_model == ARM_FLOAT_AUTO)
     tdep->fp_model = ARM_FLOAT_SOFT_FPA;
 
-  if (tdep->jb_pc >= 0)
+  if (tdep->jb_pc >= 0 && tdep->jb_sp >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, arm_get_longjmp_target);
 
   /* Floating point sizes and format.  */
Index: src/gdb/arm-wince-tdep.c
===================================================================
--- src.orig/gdb/arm-wince-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/arm-wince-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -35,6 +35,7 @@ static const char arm_wince_thumb_le_bre
 /* Description of the longjmp buffer.  */
 #define ARM_WINCE_JB_ELEMENT_SIZE	INT_REGISTER_SIZE
 #define ARM_WINCE_JB_PC			10
+#define ARM_WINCE_JB_SP			9
 
 static CORE_ADDR
 arm_pe_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc)
@@ -88,6 +89,7 @@ arm_wince_init_abi (struct gdbarch_info 
   tdep->fp_model = ARM_FLOAT_SOFT_VFP;
 
   tdep->jb_pc = ARM_WINCE_JB_PC;
+  tdep->jb_sp = ARM_WINCE_JB_SP;
   tdep->jb_elt_size = ARM_WINCE_JB_ELEMENT_SIZE;
 
   /* On ARM WinCE char defaults to signed.  */
Index: src/gdb/m68k-tdep.c
===================================================================
--- src.orig/gdb/m68k-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/m68k-tdep.c	2008-04-09 13:51:32.000000000 +0100
@@ -1009,14 +1009,15 @@ m68k_unwind_dummy_id (struct gdbarch *gd
    This routine returns true on success. */
 
 static int
-m68k_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+m68k_get_longjmp_target (struct frame_info *frame,
+			 CORE_ADDR *pc, CORE_ADDR *dest_sp)
 {
   gdb_byte *buf;
   CORE_ADDR sp, jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct gdbarch_tdep *tdep = gdbarch_tdep (get_frame_arch (frame));
 
-  if (tdep->jb_pc < 0)
+  if (tdep->jb_pc < 0 || tdep->jb_sp < 0)
     {
       internal_error (__FILE__, __LINE__,
 		      _("m68k_get_longjmp_target: not implemented"));
@@ -1039,6 +1040,14 @@ m68k_get_longjmp_target (struct frame_in
 
   *pc = extract_unsigned_integer (buf, gdbarch_ptr_bit (gdbarch)
 					 / TARGET_CHAR_BIT);
+
+  if (target_read_memory (jb_addr + tdep->jb_sp * tdep->jb_elt_size, buf,
+			  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
+    return 0;
+
+  *dest_sp = extract_unsigned_integer (buf, gdbarch_ptr_bit (gdbarch)
+				       / TARGET_CHAR_BIT);
+
   return 1;
 }
 
@@ -1228,11 +1237,13 @@ m68k_gdbarch_init (struct gdbarch_info i
   /* Disassembler.  */
   set_gdbarch_print_insn (gdbarch, print_insn_m68k);
 
-#if defined JB_PC && defined JB_ELEMENT_SIZE
+#if defined JB_PC && defined JB_SP && defined JB_ELEMENT_SIZE
   tdep->jb_pc = JB_PC;
+  tdep->jb_sp = JB_SP;
   tdep->jb_elt_size = JB_ELEMENT_SIZE;
 #else
   tdep->jb_pc = -1;
+  tdep->jb_sp = -1;
 #endif
   tdep->struct_value_regnum = M68K_A1_REGNUM;
   tdep->struct_return = reg_struct_return;
@@ -1252,7 +1263,7 @@ m68k_gdbarch_init (struct gdbarch_info i
   /* Now we have tuned the configuration, set a few final things,
      based on what the OS ABI has told us.  */
 
-  if (tdep->jb_pc >= 0)
+  if (tdep->jb_pc >= 0 && tdep->jb_sp >= 0)
     set_gdbarch_get_longjmp_target (gdbarch, m68k_get_longjmp_target);
 
   frame_unwind_append_sniffer (gdbarch, m68k_frame_sniffer);
Index: src/gdb/m68k-tdep.h
===================================================================
--- src.orig/gdb/m68k-tdep.h	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/m68k-tdep.h	2008-04-09 13:52:56.000000000 +0100
@@ -70,9 +70,10 @@ enum m68k_flavour
 
 struct gdbarch_tdep
 {
-  /* Offset to PC value in the jump buffer.  If this is negative,
-     longjmp support will be disabled.  */
+  /* Offsets to PC and SP values in the jump buffer.  If any of these
+     is negative, longjmp support will be disabled.  */
   int jb_pc;
+  int jb_sp;
   /* The size of each entry in the jump buffer.  */
   size_t jb_elt_size;
 
Index: src/gdb/m68kbsd-tdep.c
===================================================================
--- src.orig/gdb/m68kbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/m68kbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -192,6 +192,7 @@ m68kbsd_init_abi (struct gdbarch_info in
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   tdep->jb_pc = 5;
+  tdep->jb_sp = 4;
   tdep->jb_elt_size = 4;
 
   set_gdbarch_decr_pc_after_break (gdbarch, 2);
Index: src/gdb/m68klinux-tdep.c
===================================================================
--- src.orig/gdb/m68klinux-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/m68klinux-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -43,6 +43,7 @@
 
 #define M68K_LINUX_JB_ELEMENT_SIZE 4
 #define M68K_LINUX_JB_PC 7
+#define M68K_LINUX_JB_SP 14
 
 /* Check whether insn1 and insn2 are parts of a signal trampoline.  */
 
@@ -342,6 +343,7 @@ m68k_linux_init_abi (struct gdbarch_info
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   tdep->jb_pc = M68K_LINUX_JB_PC;
+  tdep->jb_sp = M68K_LINUX_JB_SP;
   tdep->jb_elt_size = M68K_LINUX_JB_ELEMENT_SIZE;
 
   /* GNU/Linux uses a calling convention that's similar to SVR4.  It
Index: src/gdb/mips-linux-tdep.c
===================================================================
--- src.orig/gdb/mips-linux-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/mips-linux-tdep.c	2008-04-09 14:03:57.000000000 +0100
@@ -48,9 +48,11 @@ static struct target_so_ops mips_svr4_so
 
 #define MIPS_LINUX_JB_ELEMENT_SIZE 4
 #define MIPS_LINUX_JB_PC 0
+#define MIPS_LINUX_JB_SP 1
 
 static int
-mips_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mips_linux_get_longjmp_target (struct frame_info *frame,
+			       CORE_ADDR *pc, CORE_ADDR *sp)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -66,6 +68,14 @@ mips_linux_get_longjmp_target (struct fr
   *pc = extract_unsigned_integer (buf,
 				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
 
+  if (target_read_memory (jb_addr
+			  + MIPS_LINUX_JB_SP * MIPS_LINUX_JB_ELEMENT_SIZE,
+			  buf, gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
+    return 0;
+
+  *sp = extract_unsigned_integer (buf,
+				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+
   return 1;
 }
 
@@ -251,9 +261,11 @@ mips_fill_fpregset (const struct regcach
 /* Details about jmp_buf.  */
 
 #define MIPS64_LINUX_JB_PC 0
+#define MIPS64_LINUX_JB_SP 1
 
 static int
-mips64_linux_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mips64_linux_get_longjmp_target (struct frame_info *frame,
+				 CORE_ADDR *pc, CORE_ADDR *sp)
 {
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
@@ -270,6 +282,14 @@ mips64_linux_get_longjmp_target (struct 
   *pc = extract_unsigned_integer (buf,
 				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
 
+  if (target_read_memory (jb_addr + MIPS64_LINUX_JB_SP * element_size,
+			  buf,
+			  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT))
+    return 0;
+
+  *sp = extract_unsigned_integer (buf,
+				  gdbarch_ptr_bit (gdbarch) / TARGET_CHAR_BIT);
+
   return 1;
 }
 
Index: src/gdb/mipsnbsd-tdep.c
===================================================================
--- src.orig/gdb/mipsnbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/mipsnbsd-tdep.c	2008-04-09 14:06:02.000000000 +0100
@@ -286,26 +286,40 @@ mipsnbsd_sigtramp_offset (struct frame_i
    success.  */
 
 #define NBSD_MIPS_JB_PC			(2 * 4)
-#define NBSD_MIPS_JB_ELEMENT_SIZE	mips_isa_regsize (current_gdbarch)
-#define NBSD_MIPS_JB_OFFSET		(NBSD_MIPS_JB_PC * \
+#define NBSD_MIPS_JB_ELEMENT_SIZE	mips_isa_regsize (gdbarch)
+#define NBSD_MIPS_JB_OFFSET_PC		(NBSD_MIPS_JB_PC * \
 					 NBSD_MIPS_JB_ELEMENT_SIZE)
-
 static int
-mipsnbsd_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+mipsnbsd_get_longjmp_target (struct frame_info *frame,
+			     CORE_ADDR *pc, CORE_ADDR *sp)
 {
   CORE_ADDR jb_addr;
   char *buf;
+  int jb_sp_offset;
+  struct gdbarch *gdbarch = get_frame_arch (frame);
+
+  /* _OFFSETOF_SC_REGS + SZREG * SP */
+  if (gdbarch_ptr_bit (gdbarch) == 32)
+    jb_sp_offset = 12 + NBSD_MIPS_JB_ELEMENT_SIZE * 29;
+  else
+    jb_sp_offset = 16 + NBSD_MIPS_JB_ELEMENT_SIZE * 29;
 
   buf = alloca (NBSD_MIPS_JB_ELEMENT_SIZE);
 
   jb_addr = get_frame_register_unsigned (frame, MIPS_A0_REGNUM);
 
-  if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET, buf,
+  if (target_read_memory (jb_addr + NBSD_MIPS_JB_OFFSET_PC, buf,
   			  NBSD_MIPS_JB_ELEMENT_SIZE))
     return 0;
 
   *pc = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE);
 
+  if (target_read_memory (jb_addr + jb_sp_offset, buf,
+  			  NBSD_MIPS_JB_ELEMENT_SIZE))
+    return 0;
+
+  *sp = extract_unsigned_integer (buf, NBSD_MIPS_JB_ELEMENT_SIZE);
+
   return 1;
 }
 
Index: src/gdb/alpha-linux-tdep.c
===================================================================
--- src.orig/gdb/alpha-linux-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alpha-linux-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -219,7 +219,10 @@ alpha_linux_init_abi (struct gdbarch_inf
   tdep->dynamic_sigtramp_offset = alpha_linux_sigtramp_offset;
   tdep->sigcontext_addr = alpha_linux_sigcontext_addr;
   tdep->pc_in_sigtramp = alpha_linux_pc_in_sigtramp;
-  tdep->jb_pc = 2;
+
+  /* from jmpbuf-offsets.h  */
+  tdep->jb_pc = 6;
+  tdep->jb_sp = 8;
   tdep->jb_elt_size = 8;
 
   set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
Index: src/gdb/alpha-osf1-tdep.c
===================================================================
--- src.orig/gdb/alpha-osf1-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alpha-osf1-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -58,6 +58,7 @@ alpha_osf1_init_abi (struct gdbarch_info
   tdep->pc_in_sigtramp = alpha_osf1_pc_in_sigtramp;
 
   tdep->jb_pc = 2;
+  tdep->jb_sp = 34;
   tdep->jb_elt_size = 8;
 }
 
Index: src/gdb/alphafbsd-tdep.c
===================================================================
--- src.orig/gdb/alphafbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alphafbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -112,6 +112,7 @@ alphafbsd_init_abi (struct gdbarch_info 
   tdep->sc_fpregs_offset = 320;
 
   tdep->jb_pc = 2;
+  tdep->jb_sp = 34;
   tdep->jb_elt_size = 8;
 }
 
Index: src/gdb/alphanbsd-tdep.c
===================================================================
--- src.orig/gdb/alphanbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alphanbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -282,6 +282,7 @@ alphanbsd_init_abi (struct gdbarch_info 
   tdep->sigcontext_addr = alphanbsd_sigcontext_addr;
 
   tdep->jb_pc = 2;
+  tdep->jb_sp = 34;
   tdep->jb_elt_size = 8;
 
   set_gdbarch_regset_from_core_section
Index: src/gdb/alphaobsd-tdep.c
===================================================================
--- src.orig/gdb/alphaobsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alphaobsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -117,6 +117,7 @@ alphaobsd_init_abi(struct gdbarch_info i
   tdep->sigcontext_addr = alphaobsd_sigcontext_addr;
 
   tdep->jb_pc = 2;
+  tdep->jb_sp = 34;
   tdep->jb_elt_size = 8;
 
   set_gdbarch_regset_from_core_section
Index: src/gdb/amd64fbsd-tdep.c
===================================================================
--- src.orig/gdb/amd64fbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/amd64fbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -192,6 +192,9 @@ amd64fbsd_init_abi (struct gdbarch_info 
   tdep->gregset_num_regs = ARRAY_SIZE (amd64fbsd_r_reg_offset);
   tdep->sizeof_gregset = 22 * 8;
 
+  tdep->jb_pc_offset = 0 * 8;
+  tdep->jb_sp_offset = 2 * 8;
+
   amd64_init_abi (info, gdbarch);
 
   tdep->sigtramp_start = amd64fbsd_sigtramp_start_addr;
Index: src/gdb/amd64nbsd-tdep.c
===================================================================
--- src.orig/gdb/amd64nbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/amd64nbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -109,6 +109,7 @@ amd64nbsd_init_abi (struct gdbarch_info 
   amd64_init_abi (info, gdbarch);
 
   tdep->jb_pc_offset = 7 * 8;
+  tdep->jb_sp_offset = 6 * 8;
 
   /* NetBSD has its own convention for signal trampolines.  */
   tdep->sigtramp_p = amd64nbsd_sigtramp_p;
Index: src/gdb/armnbsd-tdep.c
===================================================================
--- src.orig/gdb/armnbsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/armnbsd-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -28,6 +28,7 @@
 
 /* Description of the longjmp buffer.  */
 #define ARM_NBSD_JB_PC 24
+#define ARM_NBSD_JB_SP 23
 #define ARM_NBSD_JB_ELEMENT_SIZE INT_REGISTER_SIZE
 
 /* For compatibility with previous implemenations of GDB on arm/NetBSD,
@@ -66,6 +67,7 @@ arm_netbsd_init_abi_common (struct gdbar
     }
 
   tdep->jb_pc = ARM_NBSD_JB_PC;
+  tdep->jb_sp = ARM_NBSD_JB_SP;
   tdep->jb_elt_size = ARM_NBSD_JB_ELEMENT_SIZE;
 
   /* Single stepping.  */
Index: src/gdb/armobsd-tdep.c
===================================================================
--- src.orig/gdb/armobsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/armobsd-tdep.c	2008-04-09 14:28:04.000000000 +0100
@@ -91,6 +91,7 @@ armobsd_init_abi (struct gdbarch_info in
   set_gdbarch_skip_solib_resolver (gdbarch, obsd_skip_solib_resolver);
 
   tdep->jb_pc = 24;
+  tdep->jb_sp = 23;
   tdep->jb_elt_size = 4;
 
   set_gdbarch_regset_from_core_section
Index: src/gdb/i386-nto-tdep.c
===================================================================
--- src.orig/gdb/i386-nto-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/i386-nto-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -275,6 +275,7 @@ i386nto_init_abi (struct gdbarch_info in
 
   /* Setjmp()'s return PC saved in EDX (5).  */
   tdep->jb_pc_offset = 20;	/* 5x32 bit ints in.  */
+  tdep->jb_sp_offset = 16;
 
   set_solib_svr4_fetch_link_map_offsets
     (gdbarch, svr4_ilp32_fetch_link_map_offsets);
Index: src/gdb/i386bsd-tdep.c
===================================================================
--- src.orig/gdb/i386bsd-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/i386bsd-tdep.c	2008-04-09 14:29:13.000000000 +0100
@@ -78,6 +78,7 @@ i386bsd_init_abi (struct gdbarch_info in
   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
 
   tdep->jb_pc_offset = 0;
+  tdep->jb_sp_offset = 2;
 
   tdep->sigtramp_start = 0xfdbfdfc0;
   tdep->sigtramp_end = 0xfdbfe000;
Index: src/gdb/alpha-tdep.h
===================================================================
--- src.orig/gdb/alpha-tdep.h	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/alpha-tdep.h	2008-04-08 11:00:00.000000000 +0100
@@ -100,9 +100,10 @@ struct gdbarch_tdep
   int sc_regs_offset;
   int sc_fpregs_offset;
 
-  int jb_pc;			/* Offset to PC value in jump buffer.
-				   If htis is negative, longjmp support
-				   will be disabled.  */
+  /* Offsets to PC and SP values in jump buffer.  If any of these is
+     negative, longjmp support will be disabled.  */
+  int jb_pc;
+  int jb_sp;
   size_t jb_elt_size;		/* And the size of each entry in the buf. */
 };
 
Index: src/gdb/arm-tdep.h
===================================================================
--- src.orig/gdb/arm-tdep.h	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/arm-tdep.h	2008-04-09 14:31:13.000000000 +0100
@@ -163,9 +163,10 @@ struct gdbarch_tdep
   const char *thumb_breakpoint;	/* Breakpoint pattern for an ARM insn.  */
   int thumb_breakpoint_size;	/* And its size.  */
 
-  int jb_pc;			/* Offset to PC value in jump buffer. 
-				   If this is negative, longjmp support
-				   will be disabled.  */
+  /* Offsets to PC and SP values in jump buffer. If any of these is
+     negative, longjmp support will be disabled.  */
+  int jb_pc;
+  int jb_sp;
   size_t jb_elt_size;		/* And the size of each entry in the buf.  */
 
   /* Convention for returning structures.  */
Index: src/gdb/i386-tdep.c
===================================================================
--- src.orig/gdb/i386-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/i386-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -1298,12 +1298,14 @@ i386_unwind_dummy_id (struct gdbarch *gd
    success.  */
 
 int
-i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+i386_get_longjmp_target (struct frame_info *frame,
+			 CORE_ADDR *pc, CORE_ADDR *dest_sp)
 {
   gdb_byte buf[4];
   CORE_ADDR sp, jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
   int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
+  int jb_sp_offset = gdbarch_tdep (gdbarch)->jb_sp_offset;
 
   /* If JB_PC_OFFSET is -1, we have no way to find out where the
      longjmp will land.  */
@@ -1314,12 +1316,16 @@ i386_get_longjmp_target (struct frame_in
   sp = extract_unsigned_integer (buf, 4);
   if (target_read_memory (sp + 4, buf, 4))
     return 0;
-
   jb_addr = extract_unsigned_integer (buf, 4);
+
   if (target_read_memory (jb_addr + jb_pc_offset, buf, 4))
     return 0;
-
   *pc = extract_unsigned_integer (buf, 4);
+
+  if (target_read_memory (jb_addr + jb_sp_offset, buf, 4))
+    return 0;
+  *dest_sp = extract_unsigned_integer (buf, 4);
+
   return 1;
 }
 
@@ -2206,6 +2212,7 @@ i386_svr4_init_abi (struct gdbarch_info 
   tdep->sc_pc_offset = 36 + 14 * 4;
   tdep->sc_sp_offset = 36 + 17 * 4;
 
+  tdep->jb_sp_offset = 16;
   tdep->jb_pc_offset = 20;
 }
 
@@ -2219,7 +2226,8 @@ i386_go32_init_abi (struct gdbarch_info 
   /* DJGPP doesn't have any special frames for signal handlers.  */
   tdep->sigtramp_p = NULL;
 
-  tdep->jb_pc_offset = 36;
+  tdep->jb_sp_offset = 28;
+  tdep->jb_pc_offset = 32;
 }
 
 
@@ -2336,6 +2344,7 @@ i386_gdbarch_init (struct gdbarch_info i
   tdep->num_xmm_regs = I386_NUM_XREGS - 1;
 
   tdep->jb_pc_offset = -1;
+  tdep->jb_sp_offset = -1;
   tdep->struct_return = pcc_struct_return;
   tdep->sigtramp_start = 0;
   tdep->sigtramp_end = 0;
Index: src/gdb/i386-tdep.h
===================================================================
--- src.orig/gdb/i386-tdep.h	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/i386-tdep.h	2008-04-08 11:00:00.000000000 +0100
@@ -80,6 +80,8 @@ struct gdbarch_tdep
 
   /* Offset of saved PC in jmp_buf.  */
   int jb_pc_offset;
+  /* Offset of saved SP in jmp_buf.  */
+  int jb_sp_offset;
 
   /* Convention for returning structures.  */
   enum struct_return struct_return;
@@ -201,7 +203,8 @@ extern void i386_elf_init_abi (struct gd
 /* Initialize a SVR4 architecture variant.  */
 extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *);
 
-extern int i386_get_longjmp_target (struct frame_info *, CORE_ADDR *);
+extern int i386_get_longjmp_target (struct frame_info *,
+				    CORE_ADDR *, CORE_ADDR *);
 
 
 /* Functions and variables exported from i386bsd-tdep.c.  */
Index: src/gdb/i386-cygwin-tdep.c
===================================================================
--- src.orig/gdb/i386-cygwin-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/i386-cygwin-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -233,6 +233,15 @@ i386_cygwin_init_abi (struct gdbarch_inf
   tdep->gregset_num_regs = ARRAY_SIZE (i386_win32_gregset_reg_offset);
   tdep->sizeof_gregset = I386_WIN32_SIZEOF_GREGSET;
 
+  /* TODO: this seems to be 4 and 5 on mingw32.  I guess we came to a
+     point where we need to split cygwin vs mingw *-tdep.c support
+     somehow.  Maybe we should detect a cygwin binary by looking at
+     the imports for "cygwin1.dll", and have a GDB_OSABI_MINGW32 or
+     GDB_OSABI_WINDOWS afterall.  */
+
+  tdep->jb_sp_offset = 7 * 4;
+  tdep->jb_pc_offset = 8 * 4;
+
   set_solib_ops (gdbarch, &solib_target_so_ops);
 
   /* Core file support.  */
Index: src/gdb/i386-linux-tdep.c
===================================================================
--- src.orig/gdb/i386-linux-tdep.c	2008-04-07 23:19:23.000000000 +0100
+++ src/gdb/i386-linux-tdep.c	2008-04-09 13:27:17.000000000 +0100
@@ -465,6 +465,7 @@ i386_linux_init_abi (struct gdbarch_info
   tdep->gregset_num_regs = ARRAY_SIZE (i386_linux_gregset_reg_offset);
   tdep->sizeof_gregset = 17 * 4;
 
+  tdep->jb_sp_offset = 16;
   tdep->jb_pc_offset = 20;	/* From <bits/setjmp.h>.  */
   set_gdbarch_get_longjmp_target (gdbarch, i386_linux_get_longjmp_target);
 
Index: src/gdb/amd64-tdep.c
===================================================================
--- src.orig/gdb/amd64-tdep.c	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/amd64-tdep.c	2008-04-08 11:00:00.000000000 +0100
@@ -1108,26 +1108,33 @@ amd64_regset_from_core_section (struct g
    success.  */
 
 int
-amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+amd64_get_longjmp_target (struct frame_info *frame,
+			  CORE_ADDR *pc, CORE_ADDR *sp)
 {
   gdb_byte buf[8];
   CORE_ADDR jb_addr;
   struct gdbarch *gdbarch = get_frame_arch (frame);
   int jb_pc_offset = gdbarch_tdep (gdbarch)->jb_pc_offset;
-  int len = TYPE_LENGTH (builtin_type_void_func_ptr);
+  int jb_sp_offset = gdbarch_tdep (gdbarch)->jb_sp_offset;
+  int len_pc = TYPE_LENGTH (builtin_type_void_func_ptr);
+  int len_sp = TYPE_LENGTH (builtin_type_void_data_ptr);
 
   /* If JB_PC_OFFSET is -1, we have no way to find out where the
      longjmp will land.	 */
-  if (jb_pc_offset == -1)
+  if (jb_pc_offset == -1 || jb_sp_offset == -1)
     return 0;
 
   get_frame_register (frame, AMD64_RDI_REGNUM, buf);
   jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr);
-  if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
-    return 0;
 
+  if (target_read_memory (jb_addr + jb_pc_offset, buf, len_pc))
+    return 0;
   *pc = extract_typed_address (buf, builtin_type_void_func_ptr);
 
+  if (target_read_memory (jb_addr + jb_sp_offset, buf, len_sp))
+    return 0;
+  *sp = extract_typed_address (buf, builtin_type_void_data_ptr);
+
   return 1;
 }
 
Index: src/gdb/amd64-tdep.h
===================================================================
--- src.orig/gdb/amd64-tdep.h	2008-04-07 23:13:41.000000000 +0100
+++ src/gdb/amd64-tdep.h	2008-04-08 11:00:00.000000000 +0100
@@ -84,7 +84,8 @@ extern void amd64_supply_fxsave (struct 
 extern void amd64_collect_fxsave (const struct regcache *regcache, int regnum,
 				  void *fxsave);
 
-extern int amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc);
+extern int amd64_get_longjmp_target (struct frame_info *frame,
+				     CORE_ADDR *pc, CORE_ADDR *sp);
 
 
 /* Variables exported from amd64nbsd-tdep.c.  */

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