From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 983 invoked by alias); 10 Jan 2013 16:24:46 -0000 Received: (qmail 967 invoked by uid 22791); 10 Jan 2013 16:24:43 -0000 X-SWARE-Spam-Status: No, hits=-7.7 required=5.0 tests=AWL,BAYES_00,KHOP_RCVD_UNTRUST,KHOP_THREADED,RCVD_IN_DNSWL_HI,RCVD_IN_HOSTKARMA_W,RP_MATCHES_RCVD,SPF_HELO_PASS X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 10 Jan 2013 16:24:33 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r0AGOVgT004433 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 10 Jan 2013 11:24:31 -0500 Received: from [127.0.0.1] (ovpn01.gateway.prod.ext.ams2.redhat.com [10.39.146.11]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r0AGOSkC003972; Thu, 10 Jan 2013 11:24:29 -0500 Message-ID: <50EEEB3C.9050202@redhat.com> Date: Thu, 10 Jan 2013 16:24:00 -0000 From: Pedro Alves User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:17.0) Gecko/17.0 Thunderbird/17.0 MIME-Version: 1.0 To: Tristan Gingold CC: Joel Brobecker , gdb-patches@sourceware.org Subject: Re: [RFA/commit+doco 2/2] Windows x64 SEH unwinder. References: <1357728781-15073-1-git-send-email-brobecker@adacore.com> <1357728781-15073-3-git-send-email-brobecker@adacore.com> <50ED9221.1050504@redhat.com> <9E84DF2D-7AF8-4AA1-A5DF-171EF189A6E7@adacore.com> <50EDA48E.2030406@redhat.com> <66611BA9-4536-42B2-A65C-4EA5DA219E22@adacore.com> In-Reply-To: <66611BA9-4536-42B2-A65C-4EA5DA219E22@adacore.com> Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 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: 2013-01/txt/msg00199.txt.bz2 On 01/09/2013 08:07 PM, Tristan Gingold wrote: >>> This is in fact an optimization. If we found a pop, followed by >>> an epilog marker, there is not need to decode unwind info. >> >> I don't understand. pops will always be followed by a marker. >> How can that be an optimization? > > If pop weren't in this list, then if pc points to a pop the unwinder > will consider that the pc is in the body and need to decode unwind > infos. Now, if pop is in the list, the unwinder will continue to decode > until a ret and if a ret is found, it will consider that the pc is in > the epilogue, avoiding decoding unwind infos. (and again for quotability:) > If pop weren't in this list, I think you meant, that if pops were not handled in the while loop. While I'm saying that the comment implies that pop is an epilog marker, and claiming it's not, therefore the comment is wrong and misleading. It should be clarified/extended. But let me see if I understood, by trying to rewrite and extend your reply into something that I'd find clearer: We want to detect if the PC points to an epilogue (entry or midway). If so, the following epilogue detection+decoding below is sufficient. Otherwise, the unwinder will consider that the PC is in the body of the function and will need to decode unwind info. According to MSDN, an epilogue "must consist of either an add RSP,constant or lea RSP,constant[FPReg], followed by a series of zero or more 8-byte register pops and a return or a jmp". It confuses me to call this an optimization though, because MSDN says: "This reduces the amount of unwind data required, because no extra data is needed to describe each epilog. Instead, the unwind code can determine that an epilog is being executed by scanning forward through a code stream to identify an epilog." That reads to me that prologue decoding is not really something we can forgo, but something that is _required_, because the unwind data describing the epilog will simply not be there. >> The jump to an epilogue would not be part of the epilogue. > > Doesn't really matter. The point is that if the current instruction > is a jump to the epilogue, there is no need to decode unwind infs. Okay, that one makes sense to me. Please expand the comments in that direction. > >>> But I may miss your point. >> >> My point is that the docs say the epilogue has this rigid >> format that always ends in a marker, and that a marker is >> a ret or a jmp (therefore calling "pop" a marker as in the >> "I would add" comment seems to me misleading). The code >> continues following the jmp, so it makes me believe the code >> is erroneously decoding something after the jmp that is >> not an epilogue (the caller or perhaps a tailcall). > > No, it doesn't say that it ends in a marker. The epilogue > ends by a ret. Not by my reading: http://msdn.microsoft.com/en-us/library/tawsa7cb.aspx "It must consist of either an add RSP,constant or lea RSP,constant[FPReg], followed by a series of zero or more 8-byte register pops and a return or a jmp" ^^^^^^^^^^^^^^^^^ IOW, I read that as (in pseudo-bnf): add|lea (pop)* ret|jmp This http://blogs.msdn.com/b/freik/archive/2006/01/04/509372.aspx confirms my reading. Hence all this confusion and the asking for an example (a disassembly) where jmp appears in the middle of an epilogue, and my fear that this prologue detection might be following jmps when it should not, and therefore not detecting prologue ends correctly. "All function epilogues must look like this: (optional) lea rsp, [frame ptr + frame size] or add rsp, frame size pop reg (zero or more) ret (or jmp) (...) No other instructions may occur betwen the first lea/add and the final jmp or ret. (...) One other note: if the final jmp isn't an ip-relative jmp, but an indirect jmp, it must be preceded by the REX prefix, to indicate to the OS unwind routines that the jump is headed outside of the function, otherwise, the OS assumes it's a jump to a different location inside the same function." So it looks to me that even if you follow jumps to the epilogue as an optimization, the current "rex jmp reg" handling is wrong - it should not follow the PC, but instead by handling like ret and return 1. Reading the patch in more detail, I now see that all the other jmps handling in the patch's epilogue decoding are relative jumps, and those are _not_ considered epilog markers (so it's your optimization applying), per RtlVirtualUnwind's docs. But, as can be seen in the comment in the patch, immediate jmps _are_ epilogue markers, so I do believe they should be handled, and terminate the epilog decoding, just like ret. -- Pedro Alves