010301.4 W T. Allen Ada Calling nested subroutines


The DWARF 2.0.0 standard has support for determining the static link to be
used from a particular subroutine to perform up-level references of variables
in outer subroutines. That's a good thing, and provides a lot of

But, it's incomplete. It doesn't provide any mechanism for calling a nested
subroutine and providing it with a static link.

I propose adding a DW_AT_static_link_parameter attribute. It will be
associated with any subroutine which contains a directly nested subroutine
which could need to perform up-level references. Its value is a DWARF
expression which evaluates to the value to used be as the static link
parameter to be passed to the nested subroutine.

The static link parameter value isn't always obvious, because it can change
from implementation to implementation. One implementation might pass the
frame base to the nested subroutine. Ours, though, passes the location of
the "static link cell" in the appropriate parent frame. This allows for fast
multilevel up-level references in deeply nested subroutines by just
dereferencing an appropriate number of times without any arithmetic until
after the final dereference.

DWARF provides no means of describing how _any_ parameters are passed to a
subroutine. We keep to that convention and consider the mechanism for
passing the static link to be part of the calling convention for each



        [New attribute must be added to the Figure 2:]

  |         DW_AT_call_column Column position of inline call
  |         DW_AT_call_file File containing inline call
  |         DW_AT_call_line Line number of inline call

    3.3.5 Low-Level Information


    Some languages support nested subroutines. In such languages, it is
    possible to reference the local variables of an outer subroutine from
    within an inner subroutine. The DW_AT_static_link and DW_AT_frame_base
  | attributes allow debuggers to support this same kind of referencing. The
  | DW_AT_static_link_parameter attribute allows debuggers to call these inner
  | subroutines, ensuring that they will be able to perform proper up-level
  | referencing.


    If a debugger is attempting to resolve an up-level reference to a
    variable, it uses the nesting structure of DWARF to determine which
    subroutine is the lexical parent and the DW_AT_static_link to identify the
    appropriate active frame of the parent. It can then attempt to find the
    reference within the context of the parent.

  | If a subroutine or entry point contains nested subroutines or entry points,
  | it may have a DW_AT_static_link_parameter attribute, whose value is a DWARF
  | expression that computes the value to be passed to those subroutines or
  | entry points as their static link parameter. The mechanism for passing
  | a static link parameter to a nested subroutine is an attribute of the
  | calling convention of the architecture, and is not described here.
  | If a debugger is attempting to call a nested subroutine, it uses the
  | nesting structure of DWARF to determine which subroutine is the lexical
  | parent of the subroutine to be called. It then evaluates the
  | DW_AT_static_link_parameter, using the appropriate active frame of the
  | parent subroutine. If that parent is not the current frame, an up-level
  | reference may be necessary to find the appropriate active frame of the
  | parent before evaluating the DW_AT_static_link_parameter attribute.


        [New attribute must be added to Figure 21:]

  |         DW_AT_static_link_parameter 0x??

    Appendix A:

        [New attribute should be added for DW_TAG_entry_point and

  |         DW_AT_static_link_parameter