Ian Lance Taylor wrote:
"Rodney M. Bates" <[EMAIL PROTECTED]> writes:


The following example  C code and disassembly is compiled by gcc 3.4.3,
for i686.  It uses two different invariants for what the value of
a static link is.  Everywhere inside P, static link values are consistently
the same as base pointer (%ebp) register values for the same activation
record.  A static link value is generated at 4c: in P, and used at
22: in PInner2 and c: in PInner1.

Everywhere inside similar function Q, static link values consistently point
8 bytes higher than where the base register points.  A value is generated at
d9: in Q and used at 7a: in Qinner2 and 64: in QInner1.

From the examples I have looked at, it looks like it is correct translation,
and, expect for seeming strangeness, is not a problem for execution.

However, I am working on an extended gdb-derived debugger that works,
in part, with code produced by a gcc-derived code generator for
Modula-3.  So far, I can't find out, in the debugger, which invariant
is in use.  I have the debugger correctly both generating and using
static links when evaluating user-typed expressions, using the first
invariant.  I could easily change it to use the second invariant, but
obviously, that would fix some cases and break others.

Is there a compelling reason for this difference?  If not, I would like to
make it all use invariant one.  Also, does anybody know where in gcc this
difference is happening?  I poked around in the source for a couple of hours,
but didn't see anything obvious.


The static link pointer points to a part of the stack frame which
includes the information required for the nested functions.  The
amount of information required changes depending on the code.
Therefore, the static link pointer will not be a constant offset from
the frame pointer.  I don't believe that it is possible to change this
while still handling calls between doubly nested functions, but maybe
I just haven't thought about it hard enough.

I don't understand this.  A pointer to anywhere in an activation record
(or even outside it, if outside by a fixed offset) allows access to
exactly the same set of things as any other, including the value the base
register holds when the activation record is current.  That set is everything
in the AR, using different but still fixed displacements, and nothing more,
since everything else is not necessarily at a fixed displacement from the
AR.

Signed displacements are already required anyway when using the normal base
pointer, so it must not be to keep them all the same sign.  Anyway, the
observed shift in where SLs point is the wrong way to get all displacements
to the same sign.

As for multiple levels of nested functions, that always requires one static
link for every level in the nesting, each to a different AR.  Either consistent
or varying SL target locations generalizes to multiple levels with equal ease.

I am curious about the local pointer to nonlocally-accessed 
variables/parameters.
In my examples, this always is located in the same AR as the field it points to,
thus is unnecessary, since its target field could be accessed directly, using 
the
right displacement.  Does it ever point across different ARs?  I wonder if this
mechanism interacts with the invariant about where the SL points, but I can't
imagine how it would.


BTW, this is using stabs.  I know that is not very complete, but it would be
a lot more work than I want to do to change it.


Stabs doesn't represent the static link pointer at all, so that is
your problem.  You should switch to DWARF.  If that is impossible as
you suggest, then I think your most profitable approach would be to
enhance stabs somehow.

Ian


--
Rodney M. Bates

Reply via email to