This is the mail archive of the
gdb-patches@sources.redhat.com
mailing list for the GDB project.
[PATCH] Fix OpenBSD/i386 sigtramp recognition
- From: Mark Kettenis <kettenis at chello dot nl>
- To: gdb-patches at sources dot redhat dot com
- Date: Sun, 22 Feb 2004 12:19:39 +0100 (CET)
- Subject: [PATCH] Fix OpenBSD/i386 sigtramp recognition
This makes GDB recognize sigtramps on modern OpenBSD/i386. I had to
rename some variables, so I changed FreeBSD/i386 accordingly for
consistency. I also added a bunch of comments.
Committed,
Mark
Index: ChangeLog
from 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.
Index: Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.512
diff -u -p -r1.512 Makefile.in
--- Makefile.in 21 Feb 2004 19:11:37 -0000 1.512
+++ Makefile.in 22 Feb 2004 11:16:45 -0000
@@ -1849,8 +1849,8 @@ i386-nto-tdep.o: i386-nto-tdep.c $(gdb_s
$(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: i386-tdep.h
===================================================================
RCS file: /cvs/src/src/gdb/i386-tdep.h,v
retrieving revision 1.35
diff -u -p -r1.35 i386-tdep.h
--- i386-tdep.h 5 Jan 2004 19:53:06 -0000 1.35
+++ i386-tdep.h 22 Feb 2004 11:16:45 -0000
@@ -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 g
/* 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: i386bsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386bsd-tdep.c,v
retrieving revision 1.19
diff -u -p -r1.19 i386bsd-tdep.c
--- i386bsd-tdep.c 26 Dec 2003 17:59:48 -0000 1.19
+++ i386bsd-tdep.c 22 Feb 2004 11:16:45 -0000
@@ -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: i386fbsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386fbsd-nat.c,v
retrieving revision 1.4
diff -u -p -r1.4 i386fbsd-nat.c
--- i386fbsd-nat.c 10 Aug 2003 18:32:09 -0000 1.4
+++ i386fbsd-nat.c 22 Feb 2004 11:16:45 -0000
@@ -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: i386fbsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386fbsd-tdep.c,v
retrieving revision 1.1
diff -u -p -r1.1 i386fbsd-tdep.c
--- i386fbsd-tdep.c 11 Oct 2003 15:22:39 -0000 1.1
+++ i386fbsd-tdep.c 22 Feb 2004 11:16:45 -0000
@@ -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_in
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: i386obsd-nat.c
===================================================================
RCS file: /cvs/src/src/gdb/i386obsd-nat.c,v
retrieving revision 1.4
diff -u -p -r1.4 i386obsd-nat.c
--- i386obsd-nat.c 10 Aug 2003 18:32:09 -0000 1.4
+++ i386obsd-nat.c 22 Feb 2004 11:16:45 -0000
@@ -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: i386obsd-tdep.c
===================================================================
RCS file: /cvs/src/src/gdb/i386obsd-tdep.c,v
retrieving revision 1.9
diff -u -p -r1.9 i386obsd-tdep.c
--- i386obsd-tdep.c 21 Feb 2004 19:11:37 -0000 1.9
+++ i386obsd-tdep.c 22 Feb 2004 11:16:45 -0000
@@ -27,6 +27,7 @@
#include "regcache.h"
#include "regset.h"
#include "osabi.h"
+#include "target.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -35,6 +36,81 @@
#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;
+}
+
+/* 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 (
}
-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 i
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. */