Fix OpenBSD/i386 sigtramp recognition.
authorMark Kettenis <kettenis@gnu.org>
Sun, 22 Feb 2004 11:19:15 +0000 (11:19 +0000)
committerMark Kettenis <kettenis@gnu.org>
Sun, 22 Feb 2004 11:19:15 +0000 (11:19 +0000)
* i386-tdep.h: Update copyright year.
(i386bsd_pc_in_sigtramp, i386bsd_sigtramp_start)
(i386bsd_sigtramp_end): New prototypes.
(i386fbsd_sigtramp_start_addr): Renamed from
i386fbsd_sigtramp_start.
(i386fbsd_sigtramp_end_addr): Renamed from i386fbsd_sigtramp_end.
(i386obsd_sigtramp_start_addr): Renamed from
i386obsd_sigtramp_start.
(i386obsd_sigtramp_end_addr): Renamed from i386obsd_sigtramp_end.
* i386bsd-tdep.c: Update copyright year.
(i386bsd_pc_in_sigtramp): Make public.
* i386fbsd-nat.c: Update copyright year.
(_initialize_i386fbsd_nat): Adjust for renamed variables.
* i386fbsd-tdep.c: Update copyright year.
(i386fbsd_sigtramp_start_addr): Renamed from
i386fbsd_sigtramp_start.
(i386fbsd_sigtramp_end_addr): Renamed from i386fbsd_sigtramp_end.
(i386fbsdaout_init_abi): Adjust for renamed variables.
* i386obsd-nat.c: Update copyright year.
(_initialize_i386obsd_nat): Adjust for renamed variables.
* i386obsd-tdep.c: Include "target.h".
(i386obsd_page_size): New variable.
(i386obsd_pc_in_sigtramp, i386obsd_sigtramp_start)
(i386obsd_sigtramp_end): New functions.
(i386obsd_sigtramp_start_addr): Renamed from
i386obsd_sigtramp_start.
(i386obsd_sigtramp_end_addr): Renamed from i386obsd_sigtramp_end.
(i386obsd_init_abi): Adjust for renamed variables.  Set
pc_in_sigtramp, sigtramp_start and sigtramp_end.
* Makefile.in (i386obsd-tdep.o): Update dependencies.

gdb/ChangeLog
gdb/Makefile.in
gdb/i386-tdep.h
gdb/i386bsd-tdep.c
gdb/i386fbsd-nat.c
gdb/i386fbsd-tdep.c
gdb/i386obsd-nat.c
gdb/i386obsd-tdep.c

index 826deba07e2145e0fb7d1dc8576d6d0fb792f6c2..d077e074e95b08c41d4642338d0097139530a7b7 100644 (file)
@@ -1,5 +1,37 @@
 2004-02-22  Mark Kettenis  <kettenis@gnu.org>
 
+       Fix OpenBSD/i386 sigtramp recognition.
+       * i386-tdep.h: Update copyright year.
+       (i386bsd_pc_in_sigtramp, i386bsd_sigtramp_start)
+       (i386bsd_sigtramp_end): New prototypes.
+       (i386fbsd_sigtramp_start_addr): Renamed from
+       i386fbsd_sigtramp_start.
+       (i386fbsd_sigtramp_end_addr): Renamed from i386fbsd_sigtramp_end.
+       (i386obsd_sigtramp_start_addr): Renamed from
+       i386obsd_sigtramp_start.
+       (i386obsd_sigtramp_end_addr): Renamed from i386obsd_sigtramp_end.
+       * i386bsd-tdep.c: Update copyright year.
+       (i386bsd_pc_in_sigtramp): Make public.
+       * i386fbsd-nat.c: Update copyright year.
+       (_initialize_i386fbsd_nat): Adjust for renamed variables.
+       * i386fbsd-tdep.c: Update copyright year.
+       (i386fbsd_sigtramp_start_addr): Renamed from
+       i386fbsd_sigtramp_start.
+       (i386fbsd_sigtramp_end_addr): Renamed from i386fbsd_sigtramp_end.
+       (i386fbsdaout_init_abi): Adjust for renamed variables.
+       * i386obsd-nat.c: Update copyright year.
+       (_initialize_i386obsd_nat): Adjust for renamed variables.
+       * i386obsd-tdep.c: Include "target.h".
+       (i386obsd_page_size): New variable.
+       (i386obsd_pc_in_sigtramp, i386obsd_sigtramp_start)
+       (i386obsd_sigtramp_end): New functions.
+       (i386obsd_sigtramp_start_addr): Renamed from
+       i386obsd_sigtramp_start.
+       (i386obsd_sigtramp_end_addr): Renamed from i386obsd_sigtramp_end.
+       (i386obsd_init_abi): Adjust for renamed variables.  Set
+       pc_in_sigtramp, sigtramp_start and sigtramp_end.
+       * Makefile.in (i386obsd-tdep.o): Update dependencies.
+
        * amd64obsd-tdep.c (amd64obsd_pc_in_sigtramp): Adjust for signal
        trampoline change in OpenBSD kernel.
 
index 7e179a83d5e7b168df29b8d830089640c50d31cb..b1e4e4c4a12c2afe01c81a9b2cd32ab021bc4775 100644 (file)
@@ -1849,8 +1849,8 @@ i386-nto-tdep.o: i386-nto-tdep.c $(gdb_string_h) $(gdb_assert_h) $(defs_h) \
        $(nto_tdep_h) $(osabi_h) $(i387_tdep_h)
 i386obsd-nat.o: i386obsd-nat.c $(defs_h) $(i386_tdep_h)
 i386obsd-tdep.o: i386obsd-tdep.c $(defs_h) $(arch_utils_h) $(gdbcore_h) \
-       $(regcache_h) $(regset_h) $(osabi_h) $(gdb_assert_h) $(gdb_string_h) \
-       $(i386_tdep_h) $(i387_tdep_h) $(solib_svr4_h)
+       $(regcache_h) $(regset_h) $(osabi_h) $(target_h) $(gdb_assert_h) \
+       $(gdb_string_h) $(i386_tdep_h) $(i387_tdep_h) $(solib_svr4_h)
 i386-sol2-tdep.o: i386-sol2-tdep.c $(defs_h) $(value_h) $(osabi_h) \
        $(i386_tdep_h)
 i386-stub.o: i386-stub.c
index 70f6b8fec2426fcf582987baf750d049004a6f7d..f164e9d849a10e582f45a0e11a1de062b50f51e0 100644 (file)
@@ -1,7 +1,6 @@
 /* Target-dependent code for the i386.
 
-   Copyright 2001, 2002, 2003
-   Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -214,10 +213,13 @@ extern void i386_svr4_init_abi (struct gdbarch_info, struct gdbarch *);
 /* Functions and variables exported from i386bsd-tdep.c.  */
 
 extern void i386bsd_init_abi (struct gdbarch_info, struct gdbarch *);
-extern CORE_ADDR i386fbsd_sigtramp_start;
-extern CORE_ADDR i386fbsd_sigtramp_end;
-extern CORE_ADDR i386obsd_sigtramp_start;
-extern CORE_ADDR i386obsd_sigtramp_end;
+extern int i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name);
+extern CORE_ADDR i386bsd_sigtramp_start (CORE_ADDR pc);
+extern CORE_ADDR i386bsd_sigtramp_end (CORE_ADDR pc);
+extern CORE_ADDR i386fbsd_sigtramp_start_addr;
+extern CORE_ADDR i386fbsd_sigtramp_end_addr;
+extern CORE_ADDR i386obsd_sigtramp_start_addr;
+extern CORE_ADDR i386obsd_sigtramp_end_addr;
 extern int i386fbsd4_sc_reg_offset[];
 extern int i386fbsd_sc_reg_offset[];
 extern int i386nbsd_sc_reg_offset[];
index 67d09ee14d74aa207d13038da628fb72ac767c41..9276c32b3f78325db4d7a69028ec24c4c229c70d 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for i386 BSD's.
 
-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -34,7 +34,7 @@
 
 /* Return whether PC is in a BSD sigtramp routine.  */
 
-static int
+int
 i386bsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
 {
   struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
index 7feb7b053e6b1d0821ef9cce1675a1038b2ca004..efc61b6cbbb8e4b360ee0541e1292fd243464e45 100644 (file)
@@ -1,5 +1,6 @@
 /* Native-dependent code for FreeBSD/i386.
-   Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+
+   Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -98,8 +99,8 @@ _initialize_i386fbsd_nat (void)
     len = sizeof (ps_strings);
     if (sysctl (mib, 2, &ps_strings, &len, NULL, 0) == 0)
       {
-       i386fbsd_sigtramp_start = ps_strings - 128;
-       i386fbsd_sigtramp_end = ps_strings;
+       i386fbsd_sigtramp_start_addr = ps_strings - 128;
+       i386fbsd_sigtramp_end_addr = ps_strings;
       }
   }
 #endif
index 786de7d1fc2e7cb9c37bd015d3e2b0ce51270ec9..4cf8de8b45e46de40d4c64cd37768553c24b9993 100644 (file)
@@ -1,6 +1,6 @@
 /* Target-dependent code for FreeBSD/i386.
 
-   Copyright 2003 Free Software Foundation, Inc.
+   Copyright 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -39,8 +39,9 @@ static int i386fbsd_r_reg_offset[] =
   1 * 4, 0 * 4, -1, -1         /* %ds, %es, %fs, %gs */
 };
 
-CORE_ADDR i386fbsd_sigtramp_start = 0xbfbfdf20;
-CORE_ADDR i386fbsd_sigtramp_end = 0xbfbfdff0;
+/* Sigtramp routine location.  */
+CORE_ADDR i386fbsd_sigtramp_start_addr = 0xbfbfdf20;
+CORE_ADDR i386fbsd_sigtramp_end_addr = 0xbfbfdff0;
 
 /* From <machine/signal.h>.  */
 static int i386fbsd_sc_reg_offset[] =
@@ -82,8 +83,8 @@ i386fbsdaout_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->struct_return = reg_struct_return;
 
   /* FreeBSD uses a different memory layout.  */
-  tdep->sigtramp_start = i386fbsd_sigtramp_start;
-  tdep->sigtramp_end = i386fbsd_sigtramp_end;
+  tdep->sigtramp_start = i386fbsd_sigtramp_start_addr;
+  tdep->sigtramp_end = i386fbsd_sigtramp_end_addr;
 
   /* FreeBSD has a more complete `struct sigcontext'.  */
   tdep->sc_reg_offset = i386fbsd_sc_reg_offset;
index b0d4e033b8dec92a8147ac3f5a9cedf56118cf60..68cc79044ecdb41a07c0a021e8982073e03144ec 100644 (file)
@@ -1,5 +1,6 @@
 /* Native-dependent code for OpenBSD/i386.
-   Copyright 2002, 2003 Free Software Foundation, Inc.
+
+   Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -51,8 +52,8 @@ _initialize_i386obsd_nat (void)
     len = sizeof (_ps);
     if (sysctl (mib, 2, &_ps, &len, NULL, 0) == 0)
       {
-       i386obsd_sigtramp_start = (CORE_ADDR)_ps.val - 128;
-       i386obsd_sigtramp_end = (CORE_ADDR)_ps.val;
+       i386obsd_sigtramp_start_addr = (CORE_ADDR)_ps.val - 128;
+       i386obsd_sigtramp_end_addr = (CORE_ADDR)_ps.val;
       }
   }
 #endif
index be9e735cb3c0d0a9982bf5cb28b3797e0772cffd..d8556ea460acf6cd579d8359f107ed10582901b5 100644 (file)
@@ -27,6 +27,7 @@
 #include "regcache.h"
 #include "regset.h"
 #include "osabi.h"
+#include "target.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
 #include "i387-tdep.h"
 #include "solib-svr4.h"
 
+/* Support for signal handlers.  */
+
+/* Since OpenBSD 3.2, the sigtramp routine is mapped at a random page
+   in virtual memory.  The randomness makes it somewhat tricky to
+   detect it, but fortunately we can rely on the fact that the start
+   of the sigtramp routine is page-aligned.  By the way, the mapping
+   is read-only, so you cannot place a breakpoint in the signal
+   trampoline.  */
+
+/* Default page size.  */
+static const int i386obsd_page_size = 4096;
+
+/* Return whether PC is in an OpenBSD sigtramp routine.  */
+
+static int
+i386obsd_pc_in_sigtramp (CORE_ADDR pc, char *name)
+{
+  CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
+  const char sigreturn[] =
+  {
+    0xb8,
+    0x67, 0x00, 0x00, 0x00,    /* movl $SYS_sigreturn, %eax */
+    0xcd, 0x80                 /* int $0x80 */
+  };
+  char *buf;
+
+  /* Avoid reading memory from the target if possible.  If we're in a
+     named function, we're certainly not in a sigtramp routine
+     provided by the kernel.  Take synthetic function names into
+     account though.  */
+  if (name && name[0] != '<')
+    return 0;
+
+  /* If we can't read the instructions at START_PC, return zero.  */
+  buf = alloca (sizeof sigreturn);
+  if (target_read_memory (start_pc + 0x14, buf, sizeof sigreturn))
+    return 0;
+
+  /* Check for sigreturn(2).  */
+  if (memcmp (buf, sigreturn, sizeof sigreturn) == 0)
+    return 1;
+
+  /* Check for a traditional BSD sigtramp routine.  */
+  return i386bsd_pc_in_sigtramp (pc, name);
+}
+
+/* Return the start address of the sigtramp routine.  */
+
+static CORE_ADDR
+i386obsd_sigtramp_start (CORE_ADDR pc)
+{
+  CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
+
+  if (i386bsd_pc_in_sigtramp (pc, NULL))
+    return i386bsd_sigtramp_start (pc);
+
+  return start_pc;
+}
+
+/* Return the end address of the sigtramp routine.  */
+
+static CORE_ADDR
+i386obsd_sigtramp_end (CORE_ADDR pc)
+{
+  CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
+
+  if (i386bsd_pc_in_sigtramp (pc, NULL))
+    return i386bsd_sigtramp_end (pc);
+
+  return start_pc + 0x22;
+}
+\f
+/* Mapping between the general-purpose registers in `struct reg'
+   format and GDB's register cache layout.  */
+
 /* From <machine/reg.h>.  */
 static int i386obsd_r_reg_offset[] =
 {
@@ -95,8 +171,9 @@ i386obsd_aout_regset_from_core_section (struct gdbarch *gdbarch,
 }
 \f
 
-CORE_ADDR i386obsd_sigtramp_start = 0xbfbfdf20;
-CORE_ADDR i386obsd_sigtramp_end = 0xbfbfdff0;
+/* Sigtramp routine location for OpenBSD 3.1 and earlier releases.  */
+CORE_ADDR i386obsd_sigtramp_start_addr = 0xbfbfdf20;
+CORE_ADDR i386obsd_sigtramp_end_addr = 0xbfbfdff0;
 
 /* From <machine/signal.h>.  */
 int i386obsd_sc_reg_offset[I386_NUM_GREGS] =
@@ -136,8 +213,11 @@ i386obsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
   tdep->struct_return = reg_struct_return;
 
   /* OpenBSD uses a different memory layout.  */
-  tdep->sigtramp_start = i386obsd_sigtramp_start;
-  tdep->sigtramp_end = i386obsd_sigtramp_end;
+  tdep->sigtramp_start = i386obsd_sigtramp_start_addr;
+  tdep->sigtramp_end = i386obsd_sigtramp_end_addr;
+  set_gdbarch_pc_in_sigtramp (gdbarch, i386obsd_pc_in_sigtramp);
+  set_gdbarch_sigtramp_start (gdbarch, i386obsd_sigtramp_start);
+  set_gdbarch_sigtramp_end (gdbarch, i386obsd_sigtramp_end);
 
   /* OpenBSD has a `struct sigcontext' that's different from the
      origional 4.3 BSD.  */