From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 12379 invoked by alias); 19 Sep 2002 16:00:34 -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 12297 invoked from network); 19 Sep 2002 16:00:31 -0000 Received: from unknown (HELO localhost.redhat.com) (66.30.197.194) by sources.redhat.com with SMTP; 19 Sep 2002 16:00:31 -0000 Received: by localhost.redhat.com (Postfix, from userid 469) id 0727B106CC; Thu, 19 Sep 2002 11:58:35 -0400 (EDT) From: Elena Zannoni MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15753.62506.951316.119928@localhost.redhat.com> Date: Thu, 19 Sep 2002 09:00:00 -0000 To: Michal Ludvig Cc: GDB Patches Subject: Re: [RFA] sighandler backtrace on x86-64 In-Reply-To: <3D8877EE.4090203@suse.cz> References: <3D8877EE.4090203@suse.cz> X-SW-Source: 2002-09/txt/msg00489.txt.bz2 Michal Ludvig writes: > 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 > 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. I don't see any uses of the structures and functions you are exporting. Could you postpone these changes until they are actually used? I have some comments anyway, see below. > * 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; > +}; > + Do you need to make the whole structure accessible? would it be enough for your purposes to just add struct context; struct context_reg; to the .h file? > /* 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 (); 'extern' keyword? Elena > #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