Issue 221105.1: Add a mechanism for specifying subprogram return value locations

Author: Kyle Huey
Champion: Andrew Cagney
Date submitted: 2022-11-05
Date revised: 2024-01-08
Date closed:
Type: Enhancement
Status: Open
DWARF version: 6

Comparing 2023-11-27 with 2024-01-08. [ View this version ] [ Return to the latest version ]

Section 3.3.2, pg 78

## Background

A debug feature is to print the result of a subroutine at exit.

One way this is implemented is:

- run the called subroutine until it exits

  i.e., the return instruction has been completed and the program is
    i.e., the return instruction has been completed and the program is
  in the calling subprogram
    in the calling subprogram

- extract the result from the calling subprogram's frame

While DWARF makes available the type of the return value (`DW_AT_type`
attached to `DW_TAG_subprogram`, as detailed in Section 3.3.2.) it
does not provide any information about the return value's location.
Debuggers instead use the platform's calling convention to determine
the return value's location.

However, for subprograms that do not follow the standard calling
convention (i.e., (hopefully) have `DW_AT_calling_convention`
`DW_CC_nocall` attached to `DW_TAG_subprogram`), locating the return
value may not be possible.

Inline functions are similar (using `DW_TAG_inlined_subroutine` via
`DW_AT_abstract_origin`).  Run the code block until the inlined
function has "exited", and then extract the returned value.  However,
here things are even more challenging.  It is very unlikely that the
inlined and optimized code ever follows anything approaching an ABI.

## Proposal

Attach a location description to the subprogram's debug information
describing the location of the return value immediately after the
subprogram has returned.

### Why not describe the value at the return instruction?
_Why not describe the value at the return instruction?_

- this is addressing the above existing pratice
- this is addressing the above existing practice

- informally, the completion of the return instruction acts as a
  synchronization point

- for delayed branch and VLIW architectures, it is often only after
  the completion of the return instruction (bundle) that the
  subprogram result is in a known location

## Further work

I suspect Call Site Entries may provide a better way of describing
inlined function call return values.  I recommend investigating that
separately.

## Change Details

### In 3.3.2 Subroutine and Entry Point Return Types
### Called Subprograms

In 3.3.2 Subroutine and Entry Point Return Types,
Change the section heading to:
change the section heading to:

> 3.3.2 Subroutine and Entry Point Return Type and Value

At the end of the section, which currently reads:

> If the subroutine or entry point is a function that returns a
> value, then its debugging information entry has a `DW_AT_type`
> attribute to denote the type returned by that function.
> 
> [non-normative text]

append the text:

> A subroutine or entry point that is a function that returns a
> value and has a `DW_AT_type` attribute may also have a
> `DW_AT_location` attribute.  This attribute describes the
> `DW_AT_location` attribute.  This attribute specifies the
> location of the return value after the called function has
> returned and the calling subprogram is about to be resumed.  If
> a producer emits no machine code for this subprogram then this
> attribute is is not specified.
> 
> [begin non-normative]
> 
> Since the called subprogram has returned, the location
> description is relative to the calling subprogram.  For
> instance, for a sliding window architecture such as SPARC, the
> location description will refer to the output registers of the
> caller, and not the input registers of the callee.
> 
> Since the called subprogram is expected to return the value in
> a specific location, the `DW_AT_location` should be a Single
> Location Description.
> 
> [end non-normative]

**Questions:**
_Notes:_

- "If a producer emits no machine code for this subprogram then this
  attribute is is not specified" is based on `DW_AT_high_pc`?
  attribute is is not specified" is based on `DW_AT_high_pc`

- should this attribute get a new name other than `DW_AT_location` or
  stick with that since it goes with `DW_AT_type`?

- `DW_AT_location` is useless with out `DW_AT_type`; I made
- Since `DW_AT_location` is useless with out `DW_AT_type` I made
  `DW_AT_type` a predicate should it instead be non-normative text?
  `DW_AT_type` a predicate.  Should it instead be non-normative text?

### In 3.3.8.1 Abstract Instances
- Is my assumption that the `DW_AT_location` can only be for a Single
  Location (i.e., not a location list) correct?

- If a subprogram were to be included in multiple objects then,
  presumably, each would define its own `DW_AT_location`.

- This is a technical violation of:

    _Single location descriptions_, [...]. They are sufficient for
    describing the location of any object as long as its lifetime is
    either static or the same as the lexical block that owns it, [...]

### Inlined Subprograms

In 3.3.8.1 Abstract Instances,
In the non-normative text:
in the non-normative text:

> For example, the `DW_AT_low_pc`, [...] attributes typically
> should be omitted;

add `DW_AT_location`.

### In 3.3.8.2 Concrete Instances
In 3.3.8.2 Concrete Instances,

Following the paragraph:
following the paragraph:

> An inlined subroutine entry may have a `DW_AT_const_expr`
> attribute, [...], represented as it would be on the target
> architecture.

Add the paragraph:
Add the paragraph and non-normative text:

> An inlined subroutine entry that is a function that returns a
> value and and has `DW_AT_type` defined in the Abstract Instance
> value may have a `DW_AT_location` attribute.  This attribute
> may have a `DW_AT_location` attribute.  This attribute
> describes the location of the return value immediately after
> the concrete instance has completed execution of the contiguous
> or non-contiguous machine instructions generated for the
> inlined subroutine.
> 
> [begin non-normative]
> 
> Since the concrete instance may consist of non-contiguous
> instructions, `DW_AT_location` may defined using a Location
> List.  Within that list, each bounded entry identifies an
> instruction immediately after the concrete instance has
> completed execution.  That list of locations may not be
> exhaustive.
> 
> [end non-normative]

**Questions:**
_Notes:_

- see comment above about `DW_AT_type`
- Since `DW_AT_location` is useless with out `DW_AT_type` I made
  `DW_AT_type` a predicate.  Should it instead be non-normative text?

### In Appendix A. Attributes by Tag (Informative)
### Appendix A. Attributes by Tag (Informative)

Under TAG name `DW_TAG_subprogram` add `DW_AT_location` to the
Under TAG name `DW_TAG_subprogram`, add `DW_AT_location` to the
Applicable attributes.
applicable attributes.

### In Appendix D.
### Appendix D

**Questions:**
_Questions:_

- do we want to attempt an example?

---

2023-11-05: Rewrote.

2024-01-08: Revised with more non-normative text.