2003-05-29 Michal Ludvig * i386-tdep.h (struct gdbarch_tdep): num_saved_registers, sc_reg_offset - new records. (I386_*_REGNUM): Moved from i386-tdep.c. * i386-linux-tdep.c (i386_linux_init_abi): Initialize offsets in tdep->sc_reg_offset[]. * x86-64-linux-tdep.c (x86_64_linux_init_abi): Ditto. * i386-tdep.c (I386_*_REGNUM): Moved to i386-tdep.h. (i386_sigtramp_frame_cache): Use tdep->sc_reg_offset if initialized. (i386_gdbarch_init): Set tdep->num_saved_registers. * x86-64-tdep.c: Ditto for AMD64. * x86-64-tdep.h (X86_64_*_REGNUM): Moved from x86-64-tdep.c. Index: i386-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.h,v retrieving revision 1.21.2.2 diff -u -p -r1.21.2.2 i386-tdep.h --- i386-tdep.h 18 May 2003 09:44:12 -0000 1.21.2.2 +++ i386-tdep.h 29 May 2003 12:57:45 -0000 @@ -71,11 +71,30 @@ struct gdbarch_tdep /* Get address of sigcontext for sigtramp. */ CORE_ADDR (*sigcontext_addr) (struct frame_info *); + /* Max number of registers saved for each frame. */ + int num_saved_registers; + + /* Offsets of all registers in `struct sigcontext'. */ + int *sc_reg_offset; + /* Offset of saved PC and SP in `struct sigcontext'. */ int sc_pc_offset; int sc_sp_offset; }; +/* Register numbers of various important registers. */ + +#define I386_EAX_REGNUM 0 /* %eax */ +#define I386_ECX_REGNUM 1 /* %ecx */ +#define I386_EDX_REGNUM 2 /* %edx */ +#define I386_EBX_REGNUM 3 /* %ebx */ +#define I386_ESP_REGNUM 4 /* %esp */ +#define I386_EBP_REGNUM 5 /* %ebp */ +#define I386_ESI_REGNUM 6 /* %esi */ +#define I386_EDI_REGNUM 7 /* %edi */ +#define I386_EIP_REGNUM 8 /* %eip */ +#define I386_EFLAGS_REGNUM 9 /* %eflags */ +#define I386_ST0_REGNUM 16 /* %st(0) */ /* Floating-point registers. */ #define FPU_REG_RAW_SIZE 10 Index: i386-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-linux-tdep.c,v retrieving revision 1.26.2.5 diff -u -p -r1.26.2.5 i386-linux-tdep.c --- i386-linux-tdep.c 18 May 2003 09:44:12 -0000 1.26.2.5 +++ i386-linux-tdep.c 29 May 2003 12:57:43 -0000 @@ -444,6 +444,12 @@ i386_linux_init_abi (struct gdbarch_info { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + /* These offsets come from . */ + static int reg_offset[] = { + 11 * 4, 10 * 4, 9 * 4, 8 * 4, /* %eax, %ecx, %edx, %ebx */ + 17 * 4, 6 * 4, 5 * 4, 4 * 4, /* %esp, %ebp, %esi, %edi */ + 14 * 4 }; /* %eip */ + /* GNU/Linux uses ELF. */ i386_elf_init_abi (info, gdbarch); @@ -462,9 +468,14 @@ i386_linux_init_abi (struct gdbarch_info tdep->jb_pc_offset = 20; /* From . */ tdep->sigcontext_addr = i386_linux_sigcontext_addr; - tdep->sc_pc_offset = 14 * 4; /* From . */ - tdep->sc_sp_offset = 7 * 4; + /* Offsets of registers saved in a struct sigcontext. */ + tdep->sc_reg_offset = reg_offset; + tdep->num_saved_registers = sizeof (reg_offset) / sizeof (reg_offset[0]); + + tdep->sc_pc_offset = tdep->sc_reg_offset[I386_EIP_REGNUM]; + tdep->sc_sp_offset = tdep->sc_reg_offset[I386_ESP_REGNUM]; + /* When the i386 Linux kernel calls a signal handler, the return address points to a bit of code on the stack. This function is used to identify this bit of code as a signal trampoline in order Index: x86-64-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v retrieving revision 1.17.18.2 diff -u -p -r1.17.18.2 x86-64-linux-tdep.c --- x86-64-linux-tdep.c 28 May 2003 20:52:03 -0000 1.17.18.2 +++ x86-64-linux-tdep.c 29 May 2003 12:57:45 -0000 @@ -127,13 +127,27 @@ static void x86_64_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch) { struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch); + + /* These offsets come from . */ + static int reg_offset[] = { + 13 * 8, 11 * 8, 14 * 8, 12 * 8, /* %rax, %rbx, %rcx, %rdx */ + 9 * 8, 8 * 8, 10 * 8, 15 * 8, /* %rsi, %rdi, %rbp, %rsp */ + 0 * 8, 1 * 8, 2 * 8, 3 * 8, /* %r8 - %r11 */ + 4 * 8, 5 * 8, 6 * 8, 7 * 8, /* %r12 - %r15 */ + 16 * 8 }; /* %rip */ + x86_64_init_abi (info, 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 . */ - tdep->sc_sp_offset = 15 * 8; + + /* Offsets of registers saved in a struct sigcontext. */ + tdep->sc_reg_offset = reg_offset; + tdep->num_saved_registers = sizeof (reg_offset) / sizeof (reg_offset[0]); + + tdep->sc_pc_offset = tdep->sc_reg_offset[X86_64_RIP_REGNUM]; + tdep->sc_sp_offset = tdep->sc_reg_offset[X86_64_RSP_REGNUM]; } Index: i386-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/i386-tdep.c,v retrieving revision 1.138.2.15 diff -u -p -r1.138.2.15 i386-tdep.c --- i386-tdep.c 23 May 2003 20:18:32 -0000 1.138.2.15 +++ i386-tdep.c 29 May 2003 12:57:45 -0000 @@ -48,16 +48,6 @@ #include "i386-tdep.h" #include "i387-tdep.h" -/* Register numbers of various important registers. */ - -#define I386_EAX_REGNUM 0 /* %eax */ -#define I386_EDX_REGNUM 2 /* %edx */ -#define I386_ESP_REGNUM 4 /* %esp */ -#define I386_EBP_REGNUM 5 /* %ebp */ -#define I386_EIP_REGNUM 8 /* %eip */ -#define I386_EFLAGS_REGNUM 9 /* %eflags */ -#define I386_ST0_REGNUM 16 /* %st(0) */ - /* Names of the registers. The first 10 registers match the register numbering scheme used by GCC for stabs and DWARF. */ @@ -879,6 +869,7 @@ i386_sigtramp_frame_cache (struct frame_ struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[4]; + int i; if (*this_cache) return *this_cache; @@ -889,8 +880,16 @@ i386_sigtramp_frame_cache (struct frame_ cache->base = extract_unsigned_integer (buf, 4) - 4; addr = tdep->sigcontext_addr (next_frame); - cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; - cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + if (tdep->sc_reg_offset) + /* If we have offsets for all registers use them. */ + for (i = 0; i < tdep->num_saved_registers; i++) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + else + { + /* If not, use only %eip and %esp offsets. */ + cache->saved_regs[I386_EIP_REGNUM] = addr + tdep->sc_pc_offset; + cache->saved_regs[I386_ESP_REGNUM] = addr + tdep->sc_sp_offset; + } *this_cache = cache; return cache; @@ -1627,6 +1626,8 @@ i386_gdbarch_init (struct gdbarch_info i tdep->sigcontext_addr = NULL; tdep->sc_pc_offset = -1; tdep->sc_sp_offset = -1; + tdep->sc_reg_offset = NULL; + tdep->num_saved_registers = 0; /* The format used for `long double' on almost all i386 targets is the i387 extended floating-point format. In fact, of all targets Index: x86-64-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v retrieving revision 1.67.2.5 diff -u -p -r1.67.2.5 x86-64-tdep.c --- x86-64-tdep.c 19 May 2003 16:58:19 -0000 1.67.2.5 +++ x86-64-tdep.c 29 May 2003 12:57:45 -0000 @@ -40,19 +40,6 @@ #include "x86-64-tdep.h" #include "i387-tdep.h" -/* Register numbers of various important registers. */ - -#define X86_64_RAX_REGNUM 0 /* %rax */ -#define X86_64_RDX_REGNUM 3 /* %rdx */ -#define X86_64_RDI_REGNUM 5 /* %rdi */ -#define X86_64_RBP_REGNUM 6 /* %rbp */ -#define X86_64_RSP_REGNUM 7 /* %rsp */ -#define X86_64_RIP_REGNUM 16 /* %rip */ -#define X86_64_EFLAGS_REGNUM 17 /* %eflags */ -#define X86_64_ST0_REGNUM 22 /* %st0 */ -#define X86_64_XMM0_REGNUM 38 /* %xmm0 */ -#define X86_64_XMM1_REGNUM 39 /* %xmm1 */ - struct x86_64_register_info { char *name; @@ -1040,6 +1027,7 @@ x86_64_sigtramp_frame_cache (struct fram struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[8]; + int i; if (*this_cache) return *this_cache; @@ -1050,8 +1038,16 @@ x86_64_sigtramp_frame_cache (struct fram 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; + if (tdep->sc_reg_offset) + /* If we have offsets for all registers use them. */ + for (i = 0; i < tdep->num_saved_registers; i++) + cache->saved_regs[i] = addr + tdep->sc_reg_offset[i]; + else + { + /* If not, use only %rip and %rsp offsets. */ + cache->saved_regs[X86_64_RIP_REGNUM] = addr + tdep->sc_pc_offset; + cache->saved_regs[X86_64_RSP_REGNUM] = addr + tdep->sc_sp_offset; + } *this_cache = cache; return cache; Index: x86-64-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v retrieving revision 1.14.2.1 diff -u -p -r1.14.2.1 x86-64-tdep.h --- x86-64-tdep.h 17 May 2003 15:09:15 -0000 1.14.2.1 +++ x86-64-tdep.h 29 May 2003 12:57:45 -0000 @@ -33,6 +33,23 @@ struct frame_info; /* Number of general purpose registers. */ #define X86_64_NUM_GREGS 22 +/* Register numbers of various important registers. */ + +#define X86_64_RAX_REGNUM 0 /* %rax */ +#define X86_64_RBX_REGNUM 1 /* %rbx */ +#define X86_64_RCX_REGNUM 2 /* %rcx */ +#define X86_64_RDX_REGNUM 3 /* %rdx */ +#define X86_64_RSI_REGNUM 4 /* %rsi */ +#define X86_64_RDI_REGNUM 5 /* %rdi */ +#define X86_64_RBP_REGNUM 6 /* %rbp */ +#define X86_64_RSP_REGNUM 7 /* %rsp */ +#define X86_64_R8_REGNUM 8 /* %rsp */ +#define X86_64_RIP_REGNUM 16 /* %rip */ +#define X86_64_EFLAGS_REGNUM 17 /* %eflags */ +#define X86_64_ST0_REGNUM 22 /* %st0 */ +#define X86_64_XMM0_REGNUM 38 /* %xmm0 */ +#define X86_64_XMM1_REGNUM 39 /* %xmm1 */ + void x86_64_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch); /* Fill GDB's register array with the floating-point and SSE register