diff options
-rw-r--r-- | gdb/ChangeLog | 9 | ||||
-rw-r--r-- | gdb/x86-64-linux-tdep.c | 36 | ||||
-rw-r--r-- | gdb/x86-64-tdep.c | 10 |
3 files changed, 50 insertions, 5 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 11eaae9..e4404c4 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,14 @@ 2003-05-31 Mark Kettenis <kettenis@gnu.org> + * x86-64-tdep.c (X86_64_NUM_SAVED_REGS): Set to X86_64_NUM_GREGS. + (x86_64_sigtramp_frame_cache): Use `sc_reg_offset' to find saved + registers. + + * x86-64-linux-tdep.c (x86_64_linux_sc_reg_offset): New variable. + (x86_64_linux_init_abi): Initialize TDEP->sc_reg_offset and + TDEP->sc_num_regs instead of TDEP->sc_pc_offset and + TDEP->sc_sp_offset. + From Michal Ludvig <mludvig@suse.cz>: * i386-tdep.h (struct gdbarch_tdep): Add members `sc_reg_offset' and `sc_num_regs'. diff --git a/gdb/x86-64-linux-tdep.c b/gdb/x86-64-linux-tdep.c index 5615ebd..8532685 100644 --- a/gdb/x86-64-linux-tdep.c +++ b/gdb/x86-64-linux-tdep.c @@ -123,6 +123,38 @@ x86_64_linux_sigcontext_addr (struct frame_info *next_frame) } +/* From <asm/sigcontext.h>. */ +static int x86_64_linux_sc_reg_offset[X86_64_NUM_GREGS] = +{ + 13 * 8, /* %rax */ + 11 * 8, /* %rbx */ + 14 * 8, /* %rcx */ + 12 * 8, /* %rdx */ + 9 * 8, /* %rsi */ + 8 * 8, /* %rdi */ + 10 * 8, /* %rbp */ + 15 * 8, /* %rsp */ + 0 * 8, /* %r8 */ + 1 * 8, /* %r9 */ + 2 * 8, /* %r10 */ + 3 * 8, /* %r11 */ + 4 * 8, /* %r12 */ + 5 * 8, /* %r13 */ + 6 * 8, /* %r14 */ + 7 * 8, /* %r15 */ + 16 * 8, /* %rip */ + 17 * 8, /* %eflags */ + -1, /* %ds */ + -1, /* %es */ + + /* FIXME: kettenis/2002030531: The registers %fs and %gs are + available in `struct sigcontext'. However, they only occupy two + bytes instead of four, which makes using them here rather + difficult. Leave them out for now. */ + -1, /* %fs */ + -1 /* %gs */ +}; + static void x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { @@ -132,8 +164,8 @@ x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_pc_in_sigtramp); tdep->sigcontext_addr = x86_64_linux_sigcontext_addr; - tdep->sc_pc_offset = 16 * 8; /* From <asm/sigcontext.h>. */ - tdep->sc_sp_offset = 15 * 8; + tdep->sc_reg_offset = x86_64_linux_sc_reg_offset; + tdep->sc_num_regs = X86_64_NUM_GREGS; } diff --git a/gdb/x86-64-tdep.c b/gdb/x86-64-tdep.c index 560fe98..7bcabfd 100644 --- a/gdb/x86-64-tdep.c +++ b/gdb/x86-64-tdep.c @@ -787,7 +787,7 @@ x86_64_push_dummy_call (struct gdbarch *gdbarch, struct regcache *regcache, /* The maximum number of saved registers. This should include %rip. */ -#define X86_64_NUM_SAVED_REGS 17 +#define X86_64_NUM_SAVED_REGS X86_64_NUM_GREGS struct x86_64_frame_cache { @@ -1035,6 +1035,7 @@ x86_64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[8]; + int i; if (*this_cache) return *this_cache; @@ -1045,8 +1046,11 @@ x86_64_sigtramp_frame_cache (struct frame_info *next_frame, void **this_cache) cache->base = extract_unsigned_integer (buf, 8) - 8; addr = tdep->sigcontext_addr (next_frame); - cache->saved_regs[X86_64_RIP_REGNUM] = addr + tdep->sc_pc_offset; - cache->saved_regs[X86_64_RSP_REGNUM] = addr + tdep->sc_sp_offset; + gdb_assert (tdep->sc_reg_offset); + gdb_assert (tdep->sc_num_regs <= X86_64_NUM_SAVED_REGS); + for (i = 0; i < tdep->sc_num_regs; i++) + if (tdep->sc_reg_offset[i] != -1) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; *this_cache = cache; return cache; |