From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22820 invoked by alias); 5 Jul 2009 10:54:25 -0000 Received: (qmail 22809 invoked by uid 22791); 5 Jul 2009 10:54:25 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL,BAYES_00,SARE_MSGID_LONG40,SPF_PASS X-Spam-Check-By: sourceware.org Received: from wf-out-1314.google.com (HELO wf-out-1314.google.com) (209.85.200.170) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 05 Jul 2009 10:54:18 +0000 Received: by wf-out-1314.google.com with SMTP id 23so1346412wfg.24 for ; Sun, 05 Jul 2009 03:54:16 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.105.10 with SMTP id d10mr1021888wfc.91.1246791256680; Sun, 05 Jul 2009 03:54:16 -0700 (PDT) In-Reply-To: <4A4EA3B3.9030107@vmware.com> References: <4A4EA0F7.1040004@vmware.com> <4A4EA3B3.9030107@vmware.com> Date: Sun, 05 Jul 2009 10:54:00 -0000 Message-ID: Subject: Re: [RFA] epilogue unwinder for i386 (reverse 1/2) From: Hui Zhu To: Michael Snyder Cc: "gdb-patches@sourceware.org" , "drow@false.org" , "kettenis@gnu.org" Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2009-07/txt/msg00109.txt.bz2 I tried this patch with ubuntu i386. Everything is OK. Thanks, Hui On Sat, Jul 4, 2009 at 08:34, Michael Snyder wrote: > Michael Snyder wrote: >> >> This comes out of a discussion with Daniel, about how gcc >> does not generate the right dwarf info to allow correct >> frame unwinding in function epilogues, causing frame_unwind >> to return bad results. >> >> It's necessary for reverse-step, which will frequently step >> backward to the return instruction of a function. =A0But it also >> provides an improvement for forward debugging, in that now, >> without this change, if you STEPI until you are at the return >> instruction, you will get a bad backtrace. >> >> The infrun changes that take advantage of this patch will follow >> separately. >> >> Michael > > Oops, the patch wasn't meant to have that "#if 0" in it... > corrected patch below. > > > > 2009-07-03 =A0Michael Snyder =A0 > > =A0 =A0 =A0 =A0* i386-tdep.c: Add a frame unwinder for function epilogues. > =A0 =A0 =A0 =A0(i386_in_function_epilogue_p): New function. > =A0 =A0 =A0 =A0(i386_epilogue_frame_sniffer): New function. > =A0 =A0 =A0 =A0(i386_epilogue_frame_cache): New function. > =A0 =A0 =A0 =A0(i386_epilogue_frame_this_id): New function. > =A0 =A0 =A0 =A0(i386_epilogue_frame_unwind): New struct frame_unwind. > =A0 =A0 =A0 =A0(i386_gdbarch_init): Hook the new unwinder. > > 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.280 > diff -u -p -r1.280 i386-tdep.c > --- i386-tdep.c 2 Jul 2009 17:25:54 -0000 =A0 =A0 =A0 1.280 > +++ i386-tdep.c 4 Jul 2009 00:37:12 -0000 > @@ -1487,6 +1487,89 @@ static const struct frame_unwind i386_fr > =A0 NULL, > =A0 default_frame_sniffer > =A0}; > + > +/* Normal frames, but in a function epilogue. =A0*/ > + > +/* The epilogue is defined here as the RET instruction, which will > + =A0 follow any instruction such as LEAVE or POP EBP that destroys the > + =A0 function's stack frame. =A0*/ > + > +static int > +i386_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + =A0gdb_byte insn; > + > + =A0if (target_read_memory (pc, &insn, 1) !=3D 0) > + =A0 =A0return 0; =A0/* Can't read memory at pc. =A0*/ > + > + =A0if (insn !=3D 0xc3) =A0 =A0/* RET */ > + =A0 =A0return 0; > + > + =A0return 1; > +} > + > +static int > +i386_epilogue_frame_sniffer (const struct frame_unwind *self, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct frame_inf= o *this_frame, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void **this_prol= ogue_cache) > +{ > + =A0if (frame_relative_level (this_frame) =3D=3D 0) > + =A0 =A0return i386_in_function_epilogue_p (get_frame_arch (this_frame), > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 get_frame_pc (this_frame)); > + =A0else > + =A0 =A0return 0; > +} > + > +static struct i386_frame_cache * > +i386_epilogue_frame_cache (struct frame_info *this_frame, void > **this_cache) > +{ > + =A0struct gdbarch *gdbarch =3D get_frame_arch (this_frame); > + =A0enum bfd_endian byte_order =3D gdbarch_byte_order (gdbarch); > + =A0struct i386_frame_cache *cache; > + =A0gdb_byte buf[4]; > + > + =A0if (*this_cache) > + =A0 =A0return *this_cache; > + > + =A0cache =3D i386_alloc_frame_cache (); > + =A0*this_cache =3D cache; > + > + =A0/* Cache base will be ESP plus cache->sp_offset (-4). =A0*/ > + =A0get_frame_register (this_frame, I386_ESP_REGNUM, buf); > + =A0cache->base =3D extract_unsigned_integer (buf, 4, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 byte_order) + cache->sp_offset; > + > + =A0/* Cache pc will be the frame func. =A0*/ > + =A0cache->pc =3D get_frame_pc (this_frame); > + > + =A0/* The saved ESP will be at cache->base plus 8. =A0*/ > + =A0cache->saved_sp =3D cache->base + 8; > + > + =A0/* The saved EIP will be at cache->base plus 4. =A0*/ > + =A0cache->saved_regs[I386_EIP_REGNUM] =3D cache->base + 4; > + > + =A0return cache; > +} > + > +static void > +i386_epilogue_frame_this_id (struct frame_info *this_frame, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0void **this_cach= e, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0struct frame_id = *this_id) > +{ > + =A0struct i386_frame_cache *cache =3D i386_epilogue_frame_cache (this_f= rame, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 this_cache); > + > + =A0(*this_id) =3D frame_id_build (cache->base + 8, cache->pc); > +} > + > +static const struct frame_unwind i386_epilogue_frame_unwind =3D > +{ > + =A0NORMAL_FRAME, > + =A0i386_epilogue_frame_this_id, > + =A0i386_frame_prev_register, > + =A0NULL, > + =A0i386_epilogue_frame_sniffer > +}; > > > =A0/* Signal trampolines. =A0*/ > @@ -5328,7 +5411,10 @@ i386_gdbarch_init (struct gdbarch_info i > > =A0 /* Helper for function argument information. =A0*/ > =A0 set_gdbarch_fetch_pointer_argument (gdbarch, i386_fetch_pointer_argum= ent); > - > +#if 0 > + =A0/* Hook the function epilogue frame unwinder. =A0*/ > + =A0frame_unwind_append_unwinder (gdbarch, &i386_epilogue_frame_unwind); > +#endif > =A0 /* Hook in the DWARF CFI frame unwinder. =A0*/ > =A0 dwarf2_append_unwinders (gdbarch); > > >