2008-04-09 Pedro Alves * 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 . */ 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. */