IBM S/390 prologue analysis revisited

Andrew Cagney ac131313@redhat.com
Wed Jul 2 18:33:00 GMT 2003


>> 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.
> 




More information about the Gdb mailing list