* amd64-tdep.c (amd64_get_longjmp_target): New.
authorPedro Alves <palves@redhat.com>
Fri, 25 Apr 2008 14:57:30 +0000 (14:57 +0000)
committerPedro Alves <palves@redhat.com>
Fri, 25 Apr 2008 14:57:30 +0000 (14:57 +0000)
(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.

gdb/ChangeLog
gdb/amd64-tdep.c
gdb/i386-tdep.c

index 31a9b70..ce3f532 100644 (file)
@@ -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.
 
index a9a29b3..33338b6 100644 (file)
@@ -1101,6 +1101,36 @@ amd64_regset_from_core_section (struct gdbarch *gdbarch,
 }
 \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)
 {
@@ -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);
 }
 \f
 
index ee7ed51..765f1ca 100644 (file)
@@ -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;
 }
 \f