aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog7
-rw-r--r--gdb/i386obsd-tdep.c50
2 files changed, 38 insertions, 19 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 77d4be8..0ce42ae 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,10 @@
+2005-07-26 Mark Kettenis <kettenis@gnu.org>
+
+ * i386obsd-tdep.c (i386obsd_sigreturn_offset): New variable.
+ (i386obsd_sigtramp_p): Deal with an arbitrary number of possible
+ offsets.
+ (i386obsd_aout_supply_regset): Avoid bogus cast.
+
2005-07-25 Mark Kettenis <kettenis@gnu.org>
* inf-ptrace.c [PT_GET_PROCESS_STATE] (inf_ptrace_follow_fork):
diff --git a/gdb/i386obsd-tdep.c b/gdb/i386obsd-tdep.c
index 7a381bc..f2b25ef 100644
--- a/gdb/i386obsd-tdep.c
+++ b/gdb/i386obsd-tdep.c
@@ -45,13 +45,25 @@
/* 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. */
+ of the sigtramp routine is page-aligned. We recognize the
+ trampoline by looking for the code that invokes the sigreturn
+ system call. The offset where we can find that code varies from
+ release to release.
+
+ By the way, the mapping mentioned above is read-only, so you cannot
+ place a breakpoint in the signal trampoline. */
/* Default page size. */
static const int i386obsd_page_size = 4096;
+/* Offset for sigreturn(2). */
+static const int i386obsd_sigreturn_offset[] = {
+ 0x0a, /* OpenBSD 3.2 */
+ 0x14, /* OpenBSD 3.6 */
+ 0x3a, /* OpenBSD 3.8 */
+ -1
+};
+
/* Return whether the frame preceding NEXT_FRAME corresponds to an
OpenBSD sigtramp routine. */
@@ -60,6 +72,7 @@ i386obsd_sigtramp_p (struct frame_info *next_frame)
{
CORE_ADDR pc = frame_pc_unwind (next_frame);
CORE_ADDR start_pc = (pc & ~(i386obsd_page_size - 1));
+ /* The call sequence invoking sigreturn(2). */
const gdb_byte sigreturn[] =
{
0xb8,
@@ -67,6 +80,7 @@ i386obsd_sigtramp_p (struct frame_info *next_frame)
0xcd, 0x80 /* int $0x80 */
};
size_t buflen = sizeof sigreturn;
+ const int *offset;
gdb_byte *buf;
char *name;
@@ -84,21 +98,18 @@ i386obsd_sigtramp_p (struct frame_info *next_frame)
/* Allocate buffer. */
buf = alloca (buflen);
- /* If we can't read the instructions at START_PC, return zero. */
- if (!safe_frame_unwind_memory (next_frame, start_pc + 0x0a, buf, buflen))
- return 0;
-
- /* Check for sigreturn(2). */
- if (memcmp (buf, sigreturn, buflen) == 0)
- return 1;
-
- /* If we can't read the instructions at START_PC, return zero. */
- if (!safe_frame_unwind_memory (next_frame, start_pc + 0x14, buf, buflen))
- return 0;
-
- /* Check for sigreturn(2) (again). */
- if (memcmp (buf, sigreturn, buflen) == 0)
- return 1;
+ /* Loop over all offsets. */
+ for (offset = i386obsd_sigreturn_offset; *offset != -1; offset++)
+ {
+ /* If we can't read the instructions, return zero. */
+ if (!safe_frame_unwind_memory (next_frame, start_pc + *offset,
+ buf, buflen))
+ return 0;
+
+ /* Check for sigreturn(2). */
+ if (memcmp (buf, sigreturn, buflen) == 0)
+ return 1;
+ }
return 0;
}
@@ -133,11 +144,12 @@ i386obsd_aout_supply_regset (const struct regset *regset,
const void *regs, size_t len)
{
const struct gdbarch_tdep *tdep = gdbarch_tdep (regset->arch);
+ const gdb_byte *gregs = regs;
gdb_assert (len >= tdep->sizeof_gregset + I387_SIZEOF_FSAVE);
i386_supply_gregset (regset, regcache, regnum, regs, tdep->sizeof_gregset);
- i387_supply_fsave (regcache, regnum, (char *) regs + tdep->sizeof_gregset);
+ i387_supply_fsave (regcache, regnum, gregs + tdep->sizeof_gregset);
}
static const struct regset *