From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 17627 invoked by alias); 18 Sep 2002 12:56:17 -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 17619 invoked from network); 18 Sep 2002 12:56:15 -0000 Received: from unknown (HELO kerberos.suse.cz) (195.47.106.10) by sources.redhat.com with SMTP; 18 Sep 2002 12:56:15 -0000 Received: from chimera.suse.cz (chimera.suse.cz [10.20.0.2]) by kerberos.suse.cz (SuSE SMTP server) with ESMTP id 0C71059D348 for ; Wed, 18 Sep 2002 14:56:15 +0200 (CEST) Received: from suse.cz (naga.suse.cz [10.20.1.16]) by chimera.suse.cz (8.11.0/8.11.0/SuSE Linux 8.11.0-0.4) with ESMTP id g8ICuF325984 for ; Wed, 18 Sep 2002 14:56:15 +0200 X-Authentication-Warning: chimera.suse.cz: Host naga.suse.cz [10.20.1.16] claimed to be suse.cz Message-ID: <3D8877EE.4090203@suse.cz> Date: Wed, 18 Sep 2002 05:56:00 -0000 From: Michal Ludvig Organization: SuSE CR User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.0) Gecko/20020529 X-Accept-Language: cs, cz, en MIME-Version: 1.0 To: GDB Patches Subject: [RFA] sighandler backtrace on x86-64 Content-Type: multipart/mixed; boundary="------------060204060706030102030309" X-SW-Source: 2002-09/txt/msg00384.txt.bz2 This is a multi-part message in MIME format. --------------060204060706030102030309 Content-Type: text/plain; charset=ISO-8859-2; format=flowed Content-Transfer-Encoding: 7bit Content-length: 268 Hi all, the attached patch enables backtrace through signal handlers on x86-64. It isn't yet complete, but this is the part that works. Can someone approve it please? Michal Ludvig -- * SuSE CR, s.r.o * mludvig@suse.cz * +420 2 9654 5373 * http://www.suse.cz --------------060204060706030102030309 Content-Type: text/plain; name="sig3.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="sig3.diff" Content-length: 10654 2002-09-18 Michal Ludvig * dwarf2cfi.c (struct context) (struct context_reg): Moved to dwarf2cfi.h (context_alloc, frame_state_alloc, context_cpy): Made extern instead of static, removed prototypes. * dwarf2cfi.h (struct context) (struct context_reg): New, moved from dwarf2cfi.c (context_alloc, frame_state_alloc, context_cpy): New prototypes. * x86-64-linux-tdep.c (x86_64_linux_sigtramp_saved_pc): Changed from static to extern. (LINUX_SIGINFO_SIZE, LINUX_SIGCONTEXT_PC_OFFSET) (LINUX_SIGCONTEXT_FP_OFFSET) (LINUX_UCONTEXT_SIGCONTEXT_OFFSET): Adjusted. (x86_64_linux_in_sigtramp, x86_64_linux_frame_chain) (x86_64_init_frame_pc, x86_64_init_extra_frame_info): New. * x86-64-tdep.c (x86_64_gdbarch_init): Several set_gdbarch_*() calls now use x86-64 specific functions instead of DWARF2 CFI ones. * x86-64-tdep.h (x86_64_linux_in_sigtramp) (x86_64_linux_frame_chain, x86_64_init_frame_pc) (x86_64_init_extra_frame_info): New prototypes. Index: dwarf2cfi.c =================================================================== RCS file: /cvs/src/src/gdb/dwarf2cfi.c,v retrieving revision 1.16 diff -u -p -r1.16 dwarf2cfi.c --- dwarf2cfi.c 19 Jul 2002 09:40:51 -0000 1.16 +++ dwarf2cfi.c 18 Sep 2002 11:11:02 -0000 @@ -90,37 +90,6 @@ struct fde_array int array_size; }; -struct context_reg -{ - union - { - unsigned int reg; - long offset; - CORE_ADDR addr; - } - loc; - enum - { - REG_CTX_UNSAVED, - REG_CTX_SAVED_OFFSET, - REG_CTX_SAVED_REG, - REG_CTX_SAVED_ADDR, - REG_CTX_VALUE, - } - how; -}; - -/* This is the register and unwind state for a particular frame. */ -struct context -{ - struct context_reg *reg; - - CORE_ADDR cfa; - CORE_ADDR ra; - void *lsda; - int args_size; -}; - struct frame_state_reg { union @@ -208,11 +177,8 @@ static struct fde_unit *fde_unit_alloc ( static struct cie_unit *cie_unit_alloc (void); static void fde_chunks_need_space (); -static struct context *context_alloc (); -static struct frame_state *frame_state_alloc (); static void unwind_tmp_obstack_init (); static void unwind_tmp_obstack_free (); -static void context_cpy (struct context *dst, struct context *src); static unsigned int read_1u (bfd * abfd, char **p); static int read_1s (bfd * abfd, char **p); @@ -286,7 +252,7 @@ fde_chunks_need_space (void) } /* Alocate a new `struct context' on temporary obstack. */ -static struct context * +struct context * context_alloc (void) { struct context *context; @@ -303,7 +269,7 @@ context_alloc (void) } /* Alocate a new `struct frame_state' on temporary obstack. */ -static struct frame_state * +struct frame_state * frame_state_alloc (void) { struct frame_state *fs; @@ -332,7 +298,7 @@ unwind_tmp_obstack_free (void) unwind_tmp_obstack_init (); } -static void +void context_cpy (struct context *dst, struct context *src) { int regs_size = sizeof (struct context_reg) * NUM_REGS; Index: dwarf2cfi.h =================================================================== RCS file: /cvs/src/src/gdb/dwarf2cfi.h,v retrieving revision 1.1 diff -u -p -r1.1 dwarf2cfi.h --- dwarf2cfi.h 7 Dec 2001 12:10:15 -0000 1.1 +++ dwarf2cfi.h 18 Sep 2002 11:11:02 -0000 @@ -22,6 +22,37 @@ #ifndef DWARF2CFI_H #define DWARF2CFI_H +struct context_reg +{ + union + { + unsigned int reg; + long offset; + CORE_ADDR addr; + } + loc; + enum + { + REG_CTX_UNSAVED, + REG_CTX_SAVED_OFFSET, + REG_CTX_SAVED_REG, + REG_CTX_SAVED_ADDR, + REG_CTX_VALUE, + } + how; +}; + +/* This is the register and unwind state for a particular frame. */ +struct context +{ + struct context_reg *reg; + + CORE_ADDR cfa; + CORE_ADDR ra; + void *lsda; + int args_size; +}; + /* Return the frame address. */ CORE_ADDR cfi_read_fp (); @@ -63,4 +94,7 @@ void cfi_get_saved_register (char *raw_b void cfi_virtual_frame_pointer (CORE_ADDR pc, int *frame_regnum, LONGEST * frame_offset); +struct context *context_alloc (); +void context_cpy (struct context *dst, struct context *src); +struct frame_state *frame_state_alloc (); #endif Index: x86-64-linux-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-linux-tdep.c,v retrieving revision 1.5 diff -u -p -r1.5 x86-64-linux-tdep.c --- x86-64-linux-tdep.c 3 Sep 2002 13:06:33 -0000 1.5 +++ x86-64-linux-tdep.c 18 Sep 2002 11:11:02 -0000 @@ -35,8 +35,10 @@ #define LINUX_SIGTRAMP_OFFSET1 (7) static const unsigned char linux_sigtramp_code[] = { - LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x89, 0x00, 0x00, 0x00, /* mov $0x89,%rax */ - LINUX_SIGTRAMP_INSN1, 0x05 /* syscall */ + /* mov $__NR_rt_sigreturn,%rax */ + LINUX_SIGTRAMP_INSN0, 0xc7, 0xc0, 0x0f, 0x00, 0x00, 0x00, + /* syscall */ + LINUX_SIGTRAMP_INSN1, 0x05 }; #define LINUX_SIGTRAMP_LEN (sizeof linux_sigtramp_code) @@ -68,17 +70,22 @@ x86_64_linux_sigtramp_start (CORE_ADDR p return pc; } -#define LINUX_SIGINFO_SIZE 128 +#define LINUX_SIGINFO_SIZE 0 /* Offset to struct sigcontext in ucontext, from . */ -#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET (36) +#define LINUX_UCONTEXT_SIGCONTEXT_OFFSET 40 + +/* Offset to saved PC in sigcontext, from . */ +#define LINUX_SIGCONTEXT_PC_OFFSET 128 +#define LINUX_SIGCONTEXT_FP_OFFSET 120 /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the address of the associated sigcontext structure. */ -CORE_ADDR +static CORE_ADDR x86_64_linux_sigcontext_addr (struct frame_info *frame) { CORE_ADDR pc; + ULONGEST rsp; pc = x86_64_linux_sigtramp_start (frame->pc); if (pc) @@ -92,7 +99,8 @@ x86_64_linux_sigcontext_addr (struct fra /* This is the top frame. */ - return read_register (SP_REGNUM) + LINUX_SIGINFO_SIZE + + rsp = read_register (SP_REGNUM); + return rsp + LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; } @@ -101,13 +109,10 @@ x86_64_linux_sigcontext_addr (struct fra return 0; } -/* Offset to saved PC in sigcontext, from . */ -#define LINUX_SIGCONTEXT_PC_OFFSET (136) - /* Assuming FRAME is for a GNU/Linux sigtramp routine, return the saved program counter. */ -CORE_ADDR +static CORE_ADDR x86_64_linux_sigtramp_saved_pc (struct frame_info *frame) { CORE_ADDR addr; @@ -134,4 +139,62 @@ x86_64_linux_frame_saved_pc (struct fram if (frame->signal_handler_caller) return x86_64_linux_sigtramp_saved_pc (frame); return cfi_get_ra (frame); +} + +/* Return whether PC is in a GNU/Linux sigtramp routine. */ + +int +x86_64_linux_in_sigtramp (CORE_ADDR pc, char *name) +{ + if (name) + return STREQ ("__restore_rt", name); + + return (x86_64_linux_sigtramp_start (pc) != 0); +} + +CORE_ADDR +x86_64_linux_frame_chain (struct frame_info *fi) +{ + ULONGEST addr; + CORE_ADDR fp, pc; + + if (! fi->signal_handler_caller) + { + fp = cfi_frame_chain (fi); + if(fp) + return fp; + else + addr = fi->frame; + } + else + addr = fi->next->frame; + + addr += LINUX_SIGINFO_SIZE + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; + + fp = read_memory_integer (addr + LINUX_SIGCONTEXT_FP_OFFSET, 8)+8; + + return fp; +} + +void +x86_64_init_frame_pc (int fromleaf, struct frame_info *fi) +{ + CORE_ADDR addr; + + if(fi->next && fi->next->signal_handler_caller) + { + addr = fi->next->next->frame + + LINUX_SIGINFO_SIZE + + LINUX_UCONTEXT_SIGCONTEXT_OFFSET; + fi->pc = read_memory_integer (addr + + LINUX_SIGCONTEXT_PC_OFFSET, 8); + } + else + cfi_init_frame_pc (fromleaf, fi); +} + +void +x86_64_init_extra_frame_info (int fromleaf, struct frame_info *fi) +{ + cfi_init_extra_frame_info (fromleaf, fi); } Index: x86-64-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/x86-64-tdep.c,v retrieving revision 1.27 diff -u -p -r1.27 x86-64-tdep.c --- x86-64-tdep.c 12 Sep 2002 08:39:26 -0000 1.27 +++ x86-64-tdep.c 18 Sep 2002 11:11:03 -0000 @@ -1026,7 +1026,7 @@ x86_64_gdbarch_init (struct gdbarch_info /* FRAME_CHAIN takes a frame's nominal address and produces the frame's chain-pointer. */ - set_gdbarch_frame_chain (gdbarch, cfi_frame_chain); + set_gdbarch_frame_chain (gdbarch, x86_64_linux_frame_chain); set_gdbarch_frameless_function_invocation (gdbarch, x86_64_frameless_function_invocation); @@ -1041,10 +1041,10 @@ x86_64_gdbarch_init (struct gdbarch_info set_gdbarch_frame_init_saved_regs (gdbarch, x86_64_frame_init_saved_regs); /* Frame pc initialization is handled by unwind informations. */ - set_gdbarch_init_frame_pc (gdbarch, cfi_init_frame_pc); + set_gdbarch_init_frame_pc (gdbarch, x86_64_init_frame_pc); /* Initialization of unwind informations. */ - set_gdbarch_init_extra_frame_info (gdbarch, cfi_init_extra_frame_info); + set_gdbarch_init_extra_frame_info (gdbarch, x86_64_init_extra_frame_info); /* Getting saved registers is handled by unwind informations. */ set_gdbarch_get_saved_register (gdbarch, cfi_get_saved_register); @@ -1054,8 +1054,7 @@ x86_64_gdbarch_init (struct gdbarch_info /* Cons up virtual frame pointer for trace */ set_gdbarch_virtual_frame_pointer (gdbarch, cfi_virtual_frame_pointer); - - set_gdbarch_frame_chain_valid (gdbarch, generic_file_frame_chain_valid); + set_gdbarch_frame_chain_valid (gdbarch, file_frame_chain_valid); set_gdbarch_use_generic_dummy_frames (gdbarch, 1); set_gdbarch_call_dummy_location (gdbarch, AT_ENTRY_POINT); @@ -1121,6 +1120,8 @@ x86_64_gdbarch_init (struct gdbarch_info /* Use dwarf2 debug frame informations. */ set_gdbarch_dwarf2_build_frame_info (gdbarch, dwarf2_build_frame_info); set_gdbarch_dwarf2_reg_to_regnum (gdbarch, x86_64_dwarf2_reg_to_regnum); + + set_gdbarch_pc_in_sigtramp (gdbarch, x86_64_linux_in_sigtramp); return gdbarch; } Index: x86-64-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/x86-64-tdep.h,v retrieving revision 1.5 diff -u -p -r1.5 x86-64-tdep.h --- x86-64-tdep.h 20 Jun 2002 13:08:12 -0000 1.5 +++ x86-64-tdep.h 18 Sep 2002 11:11:03 -0000 @@ -31,8 +31,12 @@ extern int x86_64_num_gregs; int x86_64_register_number (const char *name); const char *x86_64_register_name (int reg_nr); - gdbarch_frame_saved_pc_ftype x86_64_linux_frame_saved_pc; gdbarch_saved_pc_after_call_ftype x86_64_linux_saved_pc_after_call; +gdbarch_pc_in_sigtramp_ftype x86_64_linux_in_sigtramp; +CORE_ADDR x86_64_linux_frame_chain (struct frame_info *fi); +void x86_64_init_frame_pc (int fromleaf, struct frame_info *fi); +void x86_64_init_extra_frame_info (int fromleaf, struct frame_info *fi); + #endif --------------060204060706030102030309--