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]

4/5 - fix/implement x86_64 gdbarch_get_longjmp_target


The i386_get_longjmp_target is really not suitable for amd64/x86_64.
It tries to read the jmp_buf out of the stack, which is suitable
for x86, but on all x86_64 implementations I looked at, jmp_buf
is passed on %rdi as normal.  The only am64 targets that currently
sets tdep->jb_pc_offset are netbsd, and openbsd in amd64nbsd-tdep.c
and amd64obsd-tdep.c respectivelly.

But, peeking at the sources, reveals that all use %rdi too.

netbsd:
http://cvsweb.netbsd.org/bsdweb.cgi/src/lib/libc/arch/x86_64/gen/_setjmp.S?rev=1.1&content-type=text/x-cvsweb-markup

openbsd:
http://www.openbsd.org/cgi-bin/cvsweb/src/lib/libc/arch/amd64/gen/setjmp.S?rev=1.2&content-type=text/x-cvsweb-markup

As I don't have access to NetBSD or OpenBSD, I tested this in combination
with patch 5/5 that makes x86_64-unknown-linux-gnu use this too.

-- 
Pedro Alves
2008-04-07  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.

---
 gdb/amd64-tdep.c |   32 ++++++++++++++++++++++++++++++++
 gdb/i386-tdep.c  |   21 ++++++++-------------
 2 files changed, 40 insertions(+), 13 deletions(-)

Index: src/gdb/amd64-tdep.c
===================================================================
--- src.orig/gdb/amd64-tdep.c	2008-04-07 00:56:23.000000000 +0100
+++ src/gdb/amd64-tdep.c	2008-04-07 01:33:29.000000000 +0100
@@ -1101,6 +1101,36 @@ amd64_regset_from_core_section (struct g
 }
 
 
+/* 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
   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);
 }
 
 
Index: src/gdb/i386-tdep.c
===================================================================
--- src.orig/gdb/i386-tdep.c	2008-04-07 00:56:23.000000000 +0100
+++ src/gdb/i386-tdep.c	2008-04-07 01:33:29.000000000 +0100
@@ -1295,36 +1295,31 @@ i386_unwind_dummy_id (struct gdbarch *gd
    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;
 }
 

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