summaryrefslogtreecommitdiff
path: root/gdb
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@gnu.org>2007-12-29 17:01:41 +0000
committerMark Kettenis <kettenis@gnu.org>2007-12-29 17:01:41 +0000
commitbd856ff1849dae1e142d896502045e44d5dc316c (patch)
tree4806d371313a8abad93b4dddf2abf3ec12dadc06 /gdb
parentd7134fb6d3f1819ba3d25deeaaac176eb9c220b2 (diff)
downloadgdb-bd856ff1849dae1e142d896502045e44d5dc316c.tar.gz
* i386nbsd-tdep.c: Include "trad-frame.h" and "tramp-frame.h"
(sigtramp_retcode, i386nbsd_sigtramp_offset, i386nbsd_sigtramp_p): Remove (i386nbsd_mc_reg_offset): New array. (i386nbsd_sigtramp_cache_init): New function. (i386nbsd_sigtramp_sc16, i386nbsd_sigtramp_sc2, i386nbsd_sigtramp_si2) (i386nbsd_sigtramp_si31, i386nbsd_sigtramp_si4): New signal trampoline frame descriptions. (i386nbsd_init_abi): Override ABI sigcontext defaults and register new signal frame unwinders * Makefile.in (i386nbsd-tdep.o): Update dependencies. * tramp-frame.h (struct tramp_frame): Allow for 48 instructions
Diffstat (limited to 'gdb')
-rw-r--r--gdb/ChangeLog15
-rw-r--r--gdb/Makefile.in2
-rw-r--r--gdb/i386nbsd-tdep.c316
-rw-r--r--gdb/tramp-frame.h2
4 files changed, 221 insertions, 114 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index af088213de6..4b98da9415d 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,18 @@
+2007-12-29 Nick Hudson <nick.hudson@dsl.pipex.com>
+
+ * i386nbsd-tdep.c: Include "trad-frame.h" and "tramp-frame.h"
+ (sigtramp_retcode, i386nbsd_sigtramp_offset, i386nbsd_sigtramp_p):
+ Remove
+ (i386nbsd_mc_reg_offset): New array.
+ (i386nbsd_sigtramp_cache_init): New function.
+ (i386nbsd_sigtramp_sc16, i386nbsd_sigtramp_sc2, i386nbsd_sigtramp_si2)
+ (i386nbsd_sigtramp_si31, i386nbsd_sigtramp_si4): New signal trampoline
+ frame descriptions.
+ (i386nbsd_init_abi): Override ABI sigcontext defaults and register
+ new signal frame unwinders
+ * Makefile.in (i386nbsd-tdep.o): Update dependencies.
+ * tramp-frame.h (struct tramp_frame): Allow for 48 instructions
+
2007-12-29 Joel Brobecker <brobecker@adacore.com>
* ada-lang.c (_initialize_ada_language): Attach executable_changed
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 114333cff97..ede72270687 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -2226,7 +2226,7 @@ i386nbsd-nat.o: i386nbsd-nat.c $(defs_h) $(gdbcore_h) $(regcache_h) \
i386nbsd-tdep.o: i386nbsd-tdep.c $(defs_h) $(arch_utils_h) $(frame_h) \
$(gdbcore_h) $(regcache_h) $(regset_h) $(osabi_h) $(symtab_h) \
$(gdb_assert_h) $(gdb_string_h) $(i386_tdep_h) $(i387_tdep_h) \
- $(nbsd_tdep_h) $(solib_svr4_h)
+ $(nbsd_tdep_h) $(solib_svr4_h) $(trad_frame_h) $(tramp_frame_h)
i386-nto-tdep.o: i386-nto-tdep.c $(defs_h) $(frame_h) $(osabi_h) \
$(regcache_h) $(target_h) $(gdb_assert_h) $(gdb_string_h) \
$(i386_tdep_h) $(i387_tdep_h) $(nto_tdep_h) $(solib_h) \
diff --git a/gdb/i386nbsd-tdep.c b/gdb/i386nbsd-tdep.c
index 6772639c930..ea9b8665596 100644
--- a/gdb/i386nbsd-tdep.c
+++ b/gdb/i386nbsd-tdep.c
@@ -26,6 +26,8 @@
#include "regset.h"
#include "osabi.h"
#include "symtab.h"
+#include "trad-frame.h"
+#include "tramp-frame.h"
#include "gdb_assert.h"
#include "gdb_string.h"
@@ -56,109 +58,6 @@ static int i386nbsd_r_reg_offset[] =
15 * 4 /* %gs */
};
-/* Under NetBSD/i386, signal handler invocations can be identified by the
- designated code sequence that is used to return from a signal handler.
- In particular, the return address of a signal handler points to the
- following code sequence:
-
- leal 0x10(%esp), %eax
- pushl %eax
- pushl %eax
- movl $0x127, %eax # __sigreturn14
- int $0x80
-
- Each instruction has a unique encoding, so we simply attempt to match
- the instruction the PC is pointing to with any of the above instructions.
- If there is a hit, we know the offset to the start of the designated
- sequence and can then check whether we really are executing in the
- signal trampoline. If not, -1 is returned, otherwise the offset from the
- start of the return sequence is returned. */
-#define RETCODE_INSN1 0x8d
-#define RETCODE_INSN2 0x50
-#define RETCODE_INSN3 0x50
-#define RETCODE_INSN4 0xb8
-#define RETCODE_INSN5 0xcd
-
-#define RETCODE_INSN2_OFF 4
-#define RETCODE_INSN3_OFF 5
-#define RETCODE_INSN4_OFF 6
-#define RETCODE_INSN5_OFF 11
-
-static const unsigned char sigtramp_retcode[] =
-{
- RETCODE_INSN1, 0x44, 0x24, 0x10,
- RETCODE_INSN2,
- RETCODE_INSN3,
- RETCODE_INSN4, 0x27, 0x01, 0x00, 0x00,
- RETCODE_INSN5, 0x80,
-};
-
-static LONGEST
-i386nbsd_sigtramp_offset (struct frame_info *next_frame)
-{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- unsigned char ret[sizeof(sigtramp_retcode)], insn;
- LONGEST off;
- int i;
-
- if (!safe_frame_unwind_memory (next_frame, pc, &insn, 1))
- return -1;
-
- switch (insn)
- {
- case RETCODE_INSN1:
- off = 0;
- break;
-
- case RETCODE_INSN2:
- /* INSN2 and INSN3 are the same. Read at the location of PC+1
- to determine if we're actually looking at INSN2 or INSN3. */
- if (!safe_frame_unwind_memory (next_frame, pc + 1, &insn, 1))
- return -1;
-
- if (insn == RETCODE_INSN3)
- off = RETCODE_INSN2_OFF;
- else
- off = RETCODE_INSN3_OFF;
- break;
-
- case RETCODE_INSN4:
- off = RETCODE_INSN4_OFF;
- break;
-
- case RETCODE_INSN5:
- off = RETCODE_INSN5_OFF;
- break;
-
- default:
- return -1;
- }
-
- pc -= off;
-
- if (!safe_frame_unwind_memory (next_frame, pc, ret, sizeof (ret)))
- return -1;
-
- if (memcmp (ret, sigtramp_retcode, sizeof (ret)) == 0)
- return off;
-
- return -1;
-}
-
-/* Return whether the frame preceding NEXT_FRAME corresponds to a
- NetBSD sigtramp routine. */
-
-static int
-i386nbsd_sigtramp_p (struct frame_info *next_frame)
-{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- char *name;
-
- find_pc_partial_function (pc, &name, NULL, NULL);
- return (nbsd_pc_in_sigtramp (pc, name)
- || i386nbsd_sigtramp_offset (next_frame) >= 0);
-}
-
/* From <machine/signal.h>. */
int i386nbsd_sc_reg_offset[] =
{
@@ -180,6 +79,195 @@ int i386nbsd_sc_reg_offset[] =
0 * 4 /* %gs */
};
+/* From <machine/mcontext.h>. */
+int i386nbsd_mc_reg_offset[] =
+{
+ 11 * 4, /* %eax */
+ 10 * 4, /* %ecx */
+ 9 * 4, /* %edx */
+ 8 * 4, /* %ebx */
+ 7 * 4, /* %esp */
+ 6 * 4, /* %ebp */
+ 5 * 4, /* %esi */
+ 4 * 4, /* %edi */
+ 14 * 4, /* %eip */
+ 16 * 4, /* %eflags */
+ 15 * 4, /* %cs */
+ 18 * 4, /* %ss */
+ 3 * 4, /* %ds */
+ 2 * 4, /* %es */
+ 1 * 4, /* %fs */
+ 0 * 4 /* %gs */
+};
+
+static void i386nbsd_sigtramp_cache_init (const struct tramp_frame *,
+ struct frame_info *,
+ struct trad_frame_cache *,
+ CORE_ADDR);
+
+static const struct tramp_frame i386nbsd_sigtramp_sc16 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x10, -1 },
+ /* leal 0x10(%esp), %eax */
+ { 0x50, -1 }, /* pushl %eax */
+ { 0x50, -1 }, /* pushl %eax */
+ { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax # exit */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_sc2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x0c, -1 },
+ /* leal 0x0c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x27, -1 }, {0x01, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x127, %eax # __sigreturn14 */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si2 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8b, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x08, -1 },
+ /* movl 8(%esp),%eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1 },
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1 },
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si31 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+ { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* leal 0x8c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static const struct tramp_frame i386nbsd_sigtramp_si4 =
+{
+ SIGTRAMP_FRAME,
+ 1,
+ {
+ { 0x8d, -1 }, { 0x84, -1 }, { 0x24, -1 },
+ { 0x8c, -1 }, { 0x00, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* leal 0x8c(%esp), %eax */
+ { 0x89, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ /* movl %eax, 0x4(%esp) */
+ { 0xb8, -1 }, { 0x34, -1 }, { 0x01, -1 }, { 0x00, -1 }, { 0x00, -1 },
+ /* movl $0x134, %eax # setcontext */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { 0xc7, -1 }, { 0x44, -1 }, { 0x24, -1 }, { 0x04, -1 },
+ { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 }, { 0xff, -1 },
+ /* movl $0xffffffff,0x4(%esp) */
+ { 0xb8, -1 }, { 0x01, -1 }, {0x00, -1 }, {0x00, -1 }, {0x00, -1 },
+ /* movl $0x1, %eax */
+ { 0xcd, -1 }, { 0x80, -1},
+ /* int $0x80 */
+ { TRAMP_SENTINEL_INSN, -1 }
+ },
+ i386nbsd_sigtramp_cache_init
+};
+
+static void
+i386nbsd_sigtramp_cache_init (const struct tramp_frame *self,
+ struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+ CORE_ADDR sp = frame_unwind_register_unsigned (next_frame, I386_ESP_REGNUM);
+ CORE_ADDR base;
+ int *reg_offset;
+ int num_regs;
+ int i;
+
+ if (self == &i386nbsd_sigtramp_sc16 || self == &i386nbsd_sigtramp_sc2)
+ {
+ reg_offset = i386nbsd_sc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+
+ /* Read in the sigcontext address */
+ base = read_memory_unsigned_integer (sp + 8, 4);
+ }
+ else
+ {
+ reg_offset = i386nbsd_mc_reg_offset;
+ num_regs = ARRAY_SIZE (i386nbsd_mc_reg_offset);
+
+ /* Read in the ucontext address */
+ base = read_memory_unsigned_integer (sp + 8, 4);
+ /* offsetof(ucontext_t, uc_mcontext) == 36 */
+ base += 36;
+ }
+
+ for (i = 0; i < num_regs; i++)
+ if (reg_offset[i] != -1)
+ trad_frame_set_reg_addr (this_cache, i, base + reg_offset[i]);
+
+ /* Construct the frame ID using the function start. */
+ trad_frame_set_id (this_cache, frame_id_build (sp, func));
+}
+
+
static void
i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
{
@@ -193,18 +281,22 @@ i386nbsd_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
tdep->gregset_num_regs = ARRAY_SIZE (i386nbsd_r_reg_offset);
tdep->sizeof_gregset = 16 * 4;
- /* NetBSD has different signal trampoline conventions. */
- tdep->sigtramp_start = 0;
- tdep->sigtramp_end = 0;
- tdep->sigtramp_p = i386nbsd_sigtramp_p;
-
/* NetBSD uses -freg-struct-return by default. */
tdep->struct_return = reg_struct_return;
- /* NetBSD has a `struct sigcontext' that's different from the
- original 4.3 BSD. */
- tdep->sc_reg_offset = i386nbsd_sc_reg_offset;
- tdep->sc_num_regs = ARRAY_SIZE (i386nbsd_sc_reg_offset);
+ /* NetBSD uses tramp_frame sniffers for signal trampolines. */
+ tdep->sigcontext_addr= 0;
+ tdep->sigtramp_start = 0;
+ tdep->sigtramp_end = 0;
+ tdep->sigtramp_p = 0;
+ tdep->sc_reg_offset = 0;
+ tdep->sc_num_regs = 0;
+
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc16);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_sc2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si2);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si31);
+ tramp_frame_prepend_unwinder (gdbarch, &i386nbsd_sigtramp_si4);
}
/* NetBSD ELF. */
diff --git a/gdb/tramp-frame.h b/gdb/tramp-frame.h
index 67a39f87e18..886f94d32fb 100644
--- a/gdb/tramp-frame.h
+++ b/gdb/tramp-frame.h
@@ -62,7 +62,7 @@ struct tramp_frame
{
ULONGEST bytes;
ULONGEST mask;
- } insn[16];
+ } insn[48];
/* Initialize a trad-frame cache corresponding to the tramp-frame.
FUNC is the address of the instruction TRAMP[0] in memory. */
void (*init) (const struct tramp_frame *self,