From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 3169 invoked by alias); 2 Jul 2003 18:33:14 -0000 Mailing-List: contact gdb-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-owner@sources.redhat.com Received: (qmail 3162 invoked from network); 2 Jul 2003 18:33:13 -0000 Received: from unknown (HELO localhost.redhat.com) (66.187.230.200) by sources.redhat.com with SMTP; 2 Jul 2003 18:33:13 -0000 Received: from redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 5B3A42B5F; Wed, 2 Jul 2003 14:33:12 -0400 (EDT) Message-ID: <3F032568.5060700@redhat.com> Date: Wed, 02 Jul 2003 18:33:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.2) Gecko/20030223 X-Accept-Language: en-us, en MIME-Version: 1.0 To: Jim Blandy Cc: gdb@sources.redhat.com Subject: Re: IBM S/390 prologue analysis revisited References: <3F00DC8C.5040908@redhat.com> <3F017E6B.90003@redhat.com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit X-SW-Source: 2003-07/txt/msg00045.txt.bz2 >> Editor note: It's missing the undefined state. I'll add it. > > > I'd say that 'struct trad_frame_saved_reg' and 'struct prologue_value' > are inverses of each other. They represent information at different > steps in the process: > - First you interpret your prologue to get a bunch of prologue values. > - Then you use those to compute a set of trad_frame_saved_reg values. > - Finally, those are what you'd use to find registers. > > Let me explain what I mean. Ah! Yes, in that case my suggestion doesn't make sense. Can I encourage you to add this to either the s390 to trad-frame code? Trad frame might be better as it then provides a pointer towards the ``new technique'' (but which ever). Andrew > The S/390 prologue analyzer creates a table of registers' current > values, expressed as simple expressions: > - "unknown", > - "the constant K", or > - "the original value of register R plus the constant K" > > To build this info, you just "interpret" the prologue, starting at the > entry point, using prologue values instead of actual integers. Here's > the code for the S/390 "add register" instruction when it appears in a > prologue: > > ... > /* AR r1, r2 -- add register */ > else if (is_rr (insn, op_ar, &r1, &r2)) > pv_add (&gpr[r1], &gpr[r1], &gpr[r2]); > ... > > That is, you just "add" the current values of r1 and r2, and store the > "result" in r1. (The "pv_*" functions do addition, subtraction, > etc. on prologue values, returning "unknown" whenever the answer can't > be expressed in one of the forms above.) When you stop, you've got > the information you need to unwind: a description of the machine's > resultant state after running the prologue. > > So, suppose your prologue moves the SP into the FP, and then subtracts > 100 from the SP. In that case, the S/390 prologue analyzer will end > up with the following "values" in those registers: > > SP: "the original value of SP plus the constant -100" > FP: "the original value of SP plus the constant 0" > > Given this it's easy to find the original SP, the frame size, and so > on. > > But here's what's cool: suppose your prologue is actually: > - save the SP in the FP > - move the constant "-100" into register R4 > - subtract R4 from SP > > That extra step, going through register R4, would break a traditional > prologue analyzer, even though it's equivalent to the original > sequence (as far as SP and FP are concerned), unless you add special > code to recognize that maneuver. But the S/390 prologue analyzer > handles this just fine, with no special cases, producing a final state > of: > > R4: "the constant -100" > SP: "the original value of SP plus the constant -100" > FP: "the original value of SP plus the constant 0" > > So you still get the information you wanted. > > This is the point where trad_frame_saved_reg comes in: that final > state information there is not exactly what you need for register > unwinding. To find the original SP, say, you need to search the > register set for a register whose current value is "the original value > of SP plus the constant Q". In the above case, we could recover the > original SP from either the current SP or the current FP. (The FP is > a little easier, but if you make sure you can handle either case, then > you've got support for FP-less functions, too.) But if you simply > make a pass over the entire register set, and record where one can > find the original values of registers, then you've produced a complete > set of 'struct trad_frame_saved_reg' values in one pass. > > So as things stand, prologue values and trad_frame_saved_reg > structures are inverses of each other: they play different roles. A > trad_frame_saved_reg points to one of the values your prologue > "interpreter" tracks: a register, stack slot, or whatever. >