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