From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 22216 invoked by alias); 17 Aug 2009 14:37:26 -0000 Received: (qmail 22196 invoked by uid 22791); 17 Aug 2009 14:37:23 -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 mail-px0-f193.google.com (HELO mail-px0-f193.google.com) (209.85.216.193) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 17 Aug 2009 14:37:17 +0000 Received: by pxi31 with SMTP id 31so1424349pxi.24 for ; Mon, 17 Aug 2009 07:37:15 -0700 (PDT) MIME-Version: 1.0 Received: by 10.142.121.3 with SMTP id t3mr684942wfc.6.1250519835232; Mon, 17 Aug 2009 07:37:15 -0700 (PDT) In-Reply-To: <4A88A1EA.8010705@vmware.com> References: <4A88A1EA.8010705@vmware.com> From: Hui Zhu Date: Mon, 17 Aug 2009 14:39:00 -0000 Message-ID: Subject: Re: [RFA] Add epilogue unwinder for AMD64 To: Michael Snyder Cc: "gdb-patches@sourceware.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-08/txt/msg00236.txt.bz2 With this patch and amd64-1.txt, all the reverse testsuite pass. It's so great! Thanks for you keep work in this part. Thank you very much. Hui On Mon, Aug 17, 2009 at 08:18, Michael Snyder wrote: > This patch corresponds to the similar one in i386-tdep.c, and > corrects for a gcc issue with elf/dwarf debug info in function > epilogues. =A0It is needed in order to make reverse-step and next > work properly for stepping backward through a return. > > No testsuite regressions. > > OK to commit? > > > 2009-08-16 =A0Michael Snyder =A0 > > =A0 =A0 =A0 =A0* amd64-tdep.c: Add a frame unwinder for function epilogue= s. > =A0 =A0 =A0 =A0(amd64_in_function_epilogue_p): New function. > =A0 =A0 =A0 =A0(amd64_epilogue_frame_sniffer): New function. > =A0 =A0 =A0 =A0(amd64_epilogue_frame_cache): New function. > =A0 =A0 =A0 =A0(amd64_epilogue_frame_this_id): New function. > =A0 =A0 =A0 =A0(amd64_epilogue_frame_unwind): New struct frame_unwind. > =A0 =A0 =A0 =A0(amd64_init_abi): Hook the new unwinder. > > Index: amd64-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/amd64-tdep.c,v > retrieving revision 1.64 > diff -u -p -r1.64 amd64-tdep.c > --- amd64-tdep.c =A0 =A0 =A0 =A010 Aug 2009 03:02:39 -0000 =A0 =A0 =A01.64 > +++ amd64-tdep.c =A0 =A0 =A0 =A016 Aug 2009 23:12:25 -0000 > @@ -1887,6 +1887,89 @@ static const struct frame_base amd64_fra > =A0 amd64_frame_base_address > =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 > + =A0 the function's stack frame. =A0*/ > + > +static int > +amd64_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) > +{ > + =A0gdb_byte insn; > + > + =A0if (target_read_memory (pc, &insn, 1)) > + =A0 =A0return 0; =A0 /* Can't read memory at pc. =A0*/ > + > + =A0if (insn !=3D 0xc3) =A0 =A0 /* 'ret' instruction. =A0*/ > + =A0 =A0return 0; > + > + =A0return 1; > +} > + > +static int > +amd64_epilogue_frame_sniffer (const struct frame_unwind *self, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct frame_in= fo *this_frame, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void **this_pro= logue_cache) > +{ > + =A0if (frame_relative_level (this_frame) =3D=3D 0) > + =A0 =A0return amd64_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 =A0get_frame_pc (this_frame)); > + =A0else > + =A0 =A0return 0; > +} > + > +static struct amd64_frame_cache * > +amd64_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 amd64_frame_cache *cache; > + =A0gdb_byte buf[4]; > + > + =A0if (*this_cache) > + =A0 =A0return *this_cache; > + > + =A0cache =3D amd64_alloc_frame_cache (); > + =A0*this_cache =3D cache; > + > + =A0/* Cache base will be %esp plus cache->sp_offset (-8). =A0*/ > + =A0get_frame_register (this_frame, AMD64_RSP_REGNUM, buf); > + =A0cache->base =3D extract_unsigned_integer (buf, 8, > + =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 16. =A0*/ > + =A0cache->saved_sp =3D cache->base + 16; > + > + =A0/* The saved %eip will be at cache->base plus 8. =A0*/ > + =A0cache->saved_regs[AMD64_RIP_REGNUM] =3D cache->base + 8; > + > + =A0return cache; > +} > + > +static void > +amd64_epilogue_frame_this_id (struct frame_info *this_frame, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 void **this_cac= he, > + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 struct frame_id= *this_id) > +{ > + =A0struct amd64_frame_cache *cache =3D amd64_epilogue_frame_cache (this= _frame, > + =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 =A0this_cache); > + > + =A0(*this_id) =3D frame_id_build (cache->base + 8, cache->pc); > +} > + > +static const struct frame_unwind amd64_epilogue_frame_unwind =3D > +{ > + =A0NORMAL_FRAME, > + =A0amd64_epilogue_frame_this_id, > + =A0amd64_frame_prev_register, > + =A0NULL, > + =A0amd64_epilogue_frame_sniffer > +}; > + > =A0static struct frame_id > =A0amd64_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) > =A0{ > @@ -2065,6 +2148,12 @@ amd64_init_abi (struct gdbarch_info info > > =A0 set_gdbarch_dummy_id (gdbarch, amd64_dummy_id); > > + =A0/* Hook the function epilogue frame unwinder. =A0This unwinder is > + =A0 =A0 appended to the list first, so that it supercedes the other > + =A0 =A0 unwinders in function epilogues. =A0*/ > + =A0frame_unwind_prepend_unwinder (gdbarch, &amd64_epilogue_frame_unwind= ); > + > + =A0/* Hook the prologue-based frame unwinders. =A0*/ > =A0 frame_unwind_append_unwinder (gdbarch, &amd64_sigtramp_frame_unwind); > =A0 frame_unwind_append_unwinder (gdbarch, &amd64_frame_unwind); > =A0 frame_base_set_default (gdbarch, &amd64_frame_base); > >