From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 468 invoked by alias); 29 May 2003 13:03:14 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 32763 invoked from network); 29 May 2003 13:03:12 -0000 Received: from unknown (HELO kerberos.suse.cz) (195.47.106.10) by sources.redhat.com with SMTP; 29 May 2003 13:03:12 -0000 Received: from chimera.suse.cz (chimera.suse.cz [10.20.0.2]) by kerberos.suse.cz (SuSE SMTP server) with ESMTP id C6B6459DED1; Thu, 29 May 2003 15:03:11 +0200 (CEST) Received: from suse.cz (naga.suse.cz [10.20.1.16]) by chimera.suse.cz (Postfix) with ESMTP id 4B03A4D59; Thu, 29 May 2003 15:03:11 +0200 (CEST) Message-ID: <3ED6050F.9010908@suse.cz> Date: Thu, 29 May 2003 13:03:00 -0000 From: Michal Ludvig Organization: SuSE CR, s.r.o. User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4b) Gecko/20030507 X-Accept-Language: cs, cz, en MIME-Version: 1.0 To: Mark Kettenis Cc: GDB Patches Subject: [RFC/i386newframe] Restore all registers from sigframe Content-Type: multipart/mixed; boundary="------------060302020907040206070300" X-SW-Source: 2003-05/txt/msg00532.txt.bz2 This is a multi-part message in MIME format. --------------060302020907040206070300 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 634 Hi, the attachd patch enables restoration of all registers when unwinding from a signal handler. Currenty only PC and SP were restored and it's a loss since all GPRs are there on the stack. It's even more important for AMD64 because there parameters are usually passed in regs and not on the stack. I did it for amd64-linux and i386-linux as I don't know appropriate offsets for other i386-targets. For this reason I kept a fallback to sc_pc_offset/sc_sp_offset. Do you like the idea? Or would you choose a different approach? Michal Ludvig -- * SuSE CR, s.r.o * mludvig@suse.cz * (+420) 296.545.373 * http://www.suse.cz --------------060302020907040206070300 Content-Type: text/plain; name="sc-restore-all-regs-2.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline; filename="sc-restore-all-regs-2.diff" Content-length: 11058 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=20 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 *); =20 + /* Max number of registers saved for each frame. */ + int num_saved_registers; +=20=20 + /* Offsets of all registers in `struct sigcontext'. */ + int *sc_reg_offset; +=20=20 /* Offset of saved PC and SP in `struct sigcontext'. */ int sc_pc_offset; int sc_sp_offset; }; =20 +/* 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. */ =20 #define FPU_REG_RAW_SIZE 10 Index: i386-linux-tdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D gdbarch_tdep (gdbarch); =20 + /* These offsets come from . */ + static int reg_offset[] =3D { + 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 */ +=20=20 /* GNU/Linux uses ELF. */ i386_elf_init_abi (info, gdbarch); =20 @@ -462,9 +468,14 @@ i386_linux_init_abi (struct gdbarch_info tdep->jb_pc_offset =3D 20; /* From . */ =20 tdep->sigcontext_addr =3D i386_linux_sigcontext_addr; - tdep->sc_pc_offset =3D 14 * 4; /* From . */ - tdep->sc_sp_offset =3D 7 * 4; =20 + /* Offsets of registers saved in a struct sigcontext. */ + tdep->sc_reg_offset =3D reg_offset; + tdep->num_saved_registers =3D sizeof (reg_offset) / sizeof (reg_offset[0= ]); + + tdep->sc_pc_offset =3D tdep->sc_reg_offset[I386_EIP_REGNUM]; + tdep->sc_sp_offset =3D tdep->sc_reg_offset[I386_ESP_REGNUM]; +=20=20 /* 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =3D gdbarch_tdep (gdbarch); + + /* These offsets come from . */ + static int reg_offset[] =3D { + 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); =20 set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_pc_in_sigtramp); =20 tdep->sigcontext_addr =3D x86_64_linux_sigcontext_addr; - tdep->sc_pc_offset =3D 16 * 8; /* From . */ - tdep->sc_sp_offset =3D 15 * 8; +=20=20 + /* Offsets of registers saved in a struct sigcontext. */ + tdep->sc_reg_offset =3D reg_offset; + tdep->num_saved_registers =3D sizeof (reg_offset) / sizeof (reg_offset[0= ]); + + tdep->sc_pc_offset =3D tdep->sc_reg_offset[X86_64_RIP_REGNUM]; + tdep->sc_sp_offset =3D tdep->sc_reg_offset[X86_64_RSP_REGNUM]; } =0C =20 Index: i386-tdep.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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" =20 -/* 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. */ =20 @@ -879,6 +869,7 @@ i386_sigtramp_frame_cache (struct frame_ struct gdbarch_tdep *tdep =3D gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[4]; + int i; =20 if (*this_cache) return *this_cache; @@ -889,8 +880,16 @@ i386_sigtramp_frame_cache (struct frame_ cache->base =3D extract_unsigned_integer (buf, 4) - 4; =20 addr =3D tdep->sigcontext_addr (next_frame); - cache->saved_regs[I386_EIP_REGNUM] =3D addr + tdep->sc_pc_offset; - cache->saved_regs[I386_ESP_REGNUM] =3D addr + tdep->sc_sp_offset; + if (tdep->sc_reg_offset) + /* If we have offsets for all registers use them. */ + for (i =3D 0; i < tdep->num_saved_registers; i++) + cache->saved_regs[i] =3D addr + tdep->sc_reg_offset[i]; + else + { + /* If not, use only %eip and %esp offsets. */ + cache->saved_regs[I386_EIP_REGNUM] =3D addr + tdep->sc_pc_offset; + cache->saved_regs[I386_ESP_REGNUM] =3D addr + tdep->sc_sp_offset; + } =20 *this_cache =3D cache; return cache; @@ -1627,6 +1626,8 @@ i386_gdbarch_init (struct gdbarch_info i tdep->sigcontext_addr =3D NULL; tdep->sc_pc_offset =3D -1; tdep->sc_sp_offset =3D -1; + tdep->sc_reg_offset =3D NULL; + tdep->num_saved_registers =3D 0; =20 /* 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 =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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" =20 -/* 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 =3D gdbarch_tdep (current_gdbarch); CORE_ADDR addr; char buf[8]; + int i; =20 if (*this_cache) return *this_cache; @@ -1050,8 +1038,16 @@ x86_64_sigtramp_frame_cache (struct fram cache->base =3D extract_unsigned_integer (buf, 8) - 8; =20 addr =3D tdep->sigcontext_addr (next_frame); - cache->saved_regs[X86_64_RIP_REGNUM] =3D addr + tdep->sc_pc_offset; - cache->saved_regs[X86_64_RSP_REGNUM] =3D addr + tdep->sc_sp_offset; + if (tdep->sc_reg_offset) + /* If we have offsets for all registers use them. */ + for (i =3D 0; i < tdep->num_saved_registers; i++) + cache->saved_regs[i] =3D addr + tdep->sc_reg_offset[i]; + else + { + /* If not, use only %rip and %rsp offsets. */ + cache->saved_regs[X86_64_RIP_REGNUM] =3D addr + tdep->sc_pc_offset; + cache->saved_regs[X86_64_RSP_REGNUM] =3D addr + tdep->sc_sp_offset; + } =20 *this_cache =3D cache; return cache; Index: x86-64-tdep.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D 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 =20 +/* 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); =20 /* Fill GDB's register array with the floating-point and SSE register --------------060302020907040206070300--