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