diff options
author | Mark Kettenis <kettenis@gnu.org> | 2005-07-26 20:02:55 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@gnu.org> | 2005-07-26 20:02:55 +0000 |
commit | 3ed852475710298f0ac4426e5e9494b0d6f37443 (patch) | |
tree | f8de600c5b68119d83d2622edce7743c5b292d55 /gdb/i386obsd-tdep.c | |
parent | 9cd969923762b28e8bbe82fff7b995e72fe3e5f9 (diff) | |
download | gdb-3ed852475710298f0ac4426e5e9494b0d6f37443.zip gdb-3ed852475710298f0ac4426e5e9494b0d6f37443.tar.gz gdb-3ed852475710298f0ac4426e5e9494b0d6f37443.tar.bz2 |
* 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.
Diffstat (limited to 'gdb/i386obsd-tdep.c')
-rw-r--r-- | gdb/i386obsd-tdep.c | 50 |
1 files changed, 31 insertions, 19 deletions
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 * |