aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/amd64-tdep.c32
-rw-r--r--gdb/i386-tdep.c21
3 files changed, 47 insertions, 13 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 31a9b70..ce3f532 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,5 +1,12 @@
2008-04-25 Pedro Alves <pedro@codesourcery.com>
+ * amd64-tdep.c (amd64_get_longjmp_target): New.
+ (amd64_init_abi): Register amd64_get_longjmp_target as
+ gdbarch_get_longjmp_target callback.
+ * i386-tdep.c (i386_get_longjmp_target): Remove 64-bit handling.
+
+2008-04-25 Pedro Alves <pedro@codesourcery.com>
+
* breakpoint.h (enum bpstat_what_main_action): Delete
BPSTAT_WHAT_CLEAR_LONGJMP_RESUME_SINGLE.
diff --git a/gdb/amd64-tdep.c b/gdb/amd64-tdep.c
index a9a29b3..33338b6 100644
--- a/gdb/amd64-tdep.c
+++ b/gdb/amd64-tdep.c
@@ -1101,6 +1101,36 @@ amd64_regset_from_core_section (struct gdbarch *gdbarch,
}
+/* Figure out where the longjmp will land. Slurp the jmp_buf out of
+ %rdi. We expect its value to be a pointer to the jmp_buf structure
+ from which we extract the address that we will land at. This
+ address is copied into PC. This routine returns non-zero on
+ success. */
+
+static int
+amd64_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
+{
+ 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);
+
+ /* If JB_PC_OFFSET is -1, we have no way to find out where the
+ longjmp will land. */
+ if (jb_pc_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;
+
+ *pc = extract_typed_address (buf, builtin_type_void_func_ptr);
+
+ return 1;
+}
+
void
amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -1174,6 +1204,8 @@ amd64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
if (tdep->gregset_reg_offset)
set_gdbarch_regset_from_core_section (gdbarch,
amd64_regset_from_core_section);
+
+ set_gdbarch_get_longjmp_target (gdbarch, amd64_get_longjmp_target);
}
diff --git a/gdb/i386-tdep.c b/gdb/i386-tdep.c
index ee7ed51..765f1ca 100644
--- a/gdb/i386-tdep.c
+++ b/gdb/i386-tdep.c
@@ -1295,36 +1295,31 @@ i386_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
stack. We expect the first arg to be a pointer to the jmp_buf
structure from which we extract the address that we will land at.
This address is copied into PC. This routine returns non-zero on
- success.
-
- This function is 64-bit safe. */
+ success. */
static int
i386_get_longjmp_target (struct frame_info *frame, CORE_ADDR *pc)
{
- gdb_byte buf[8];
+ 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 len = TYPE_LENGTH (builtin_type_void_func_ptr);
/* If JB_PC_OFFSET is -1, we have no way to find out where the
longjmp will land. */
if (jb_pc_offset == -1)
return 0;
- /* Don't use I386_ESP_REGNUM here, since this function is also used
- for AMD64. */
- get_frame_register (frame, gdbarch_sp_regnum (gdbarch), buf);
- sp = extract_typed_address (buf, builtin_type_void_data_ptr);
- if (target_read_memory (sp + len, buf, len))
+ get_frame_register (frame, I386_ESP_REGNUM, buf);
+ sp = extract_unsigned_integer (buf, 4);
+ if (target_read_memory (sp + 4, buf, 4))
return 0;
- jb_addr = extract_typed_address (buf, builtin_type_void_data_ptr);
- if (target_read_memory (jb_addr + jb_pc_offset, buf, len))
+ jb_addr = extract_unsigned_integer (buf, 4);
+ if (target_read_memory (jb_addr + jb_pc_offset, buf, 4))
return 0;
- *pc = extract_typed_address (buf, builtin_type_void_func_ptr);
+ *pc = extract_unsigned_integer (buf, 4);
return 1;
}