Issue 230412.1: Ambiguity in Static and Dynamic Values of Attributes (was DW_AT_string_length)
Author: | Cary Coutant |
---|---|
Champion: | Cary Coutant |
Date submitted: | 2023-04-12 |
Date revised: | 2024-01-30 |
Date closed: | 2024-02-05 |
Type: | Clarification |
Status: | Accepted |
DWARF Version: | 6 |
Background
In Issue 160811.1 for DWARF 5, we added the reference class as an
allowed attribute class for DW_AT_string_length
, and changed the text in
Section 2.19 (Static and Dynamic Values of Attributes) from:
The value of these attributes is determined based on the class as follows:
For a constant, the value of the constant is the value of the attribute.
For a reference, the value is a reference to another entity which specifies the value of the attribute.
For an exprloc, the value is interpreted as a DWARF expression; evaluation of the expression yields the value of the attribute.
to:
The value of these attributes is determined based on the class as follows:
For a constant, the value of the constant is the value of the attribute.
For a reference, the value is a reference to another debugging information entry. This entry may:
describe a constant which is the attribute value,
describe a variable which contains the attribute value, or
contain a
DW_AT_location
attribute whose value is a DWARF expression which computes the attribute value (for example, aDW_TAG_dwarf_procedure
entry).For an exprloc, the value is interpreted as a DWARF expression; evaluation of the expression yields the value of the attribute.
For the reference class bullet, I have several questions:
-
In case 1, what do we mean by "This entry may... describe a constant"? Is this referring to a
DW_TAG_constant
, or to any DIE that might have aDW_AT_const_value
attribute? Or either? -
In case 2, I read "a variable which contains the attribute value" to mean that we're looking at a
DW_TAG_variable
DIE (or perhapsDW_TAG_formal_parameter
orDW_TAG_member
) where the value we're looking for is either: (a) the value given byDW_AT_const_value
or (b) stored at the location specified byDW_AT_location
. Does this need clarification? -
Case 3 seems to overlap with case 2. If the entry contains a
DW_AT_location
attribute, and is a variable, then we have case 2. But if it's a dwarf procedure, then we say theDW_AT_location
attribute "computes the attribute value," which could be interpreted to mean the DWARF expression there computes a value rather than a location where the value is stored. I think that's obviously wrong, but isn't that the implication?
For the exprloc class bullet, it seems to say that the DWARF expression
evaluates directly to a value, not a location description. So does that
mean DW_OP_reg5
, for example, is invalid? I take this to mean that for
these attributes, an exprloc form is meant to evaluate to a value, not a
location, so the only way to provide a location is via a reference.
Sound right?
In Section 4.1, under DW_AT_default_value
, the third bullet for references
to a DWARF procedure is also unclear as to whether the evaluation of the
DWARF procedure should be interpreted as a value or a location. It's clear
that a reference to a variable (which is, by definition, a DWARF procedure,
if it has a DW_AT_location
attribute) refers to the value of that variable.
When referring to a DWARF procedure, are we referring to any DWARF procedure
other than a variable, or only to DW_TAG_dwarf_procedure
entries?
In Section 5.11 (String Type Entries), the DWARF 5 wording is:
The string type entry may also have a
DW_AT_string_length
attribute whose value is either a reference (see Section 2.19) yielding the length of the string or a location description yielding the location where the length of the string is stored in the program....
I think the phrasing here, "a reference ... yielding the length of the string" is confusing, even with the cross-reference to Section 2.19.
History of Section 2.19
In DWARF 4, the relevant text was simply:
The value of these attributes is determined based on the class as follows:
For a constant, the value of the constant is the value of the attribute.
For a reference, the value is a reference to another entity which specifies the value of the attribute.
For an exprloc, the value is interpreted as a DWARF expression; evaluation of the expression yields the value of the attribute.
In Issue 100805.1, the question was raised of how a reference to another "entity" actually specified the value, and the following replacement text was proposed for the second bullet:
For a reference, the value is a reference to another DIE. This DIE may
describe a variable which contains the attribute value
describes a constant which is the attribute value
contain a DWARF expression which computes the attribute value
The minutes from the 6/9/12 meeting have this question: "Should the
last clause (the DWARF expression reference) be dropped given that none of us
are sure what it means?" Further discussion suggested the possibility that
a DWARF procedure could be used for an expression that is used in several
places, as a space-savings measure. Another comment mentioned:
"Maybe we should make it clear that if we're pointing to a DWARF
Procedure that contains an expression to compute the value, it can
use the DW_OP_stack_value
."
In the 9/18/12 meeting, that sub-bullet was revised to:
- contain a DWARF expression which computes the attribute value or is a dwarf procedure which computes the attribute value
The final wording in the DWARF 5 document appears to have been editorial:
- contain a
DW_AT_location
attribute whose value is a DWARF expression which computes the attribute value (for example, aDW_TAG_dwarf_procedure
entry).
This suggests that it was intended that references to variables (or to
any "data object") were intended to reference the value of the variable
whose location is given, but that references to other entries with a
DW_AT_location
attribute (e.g., DWARF procedures) were intended to
reference the value of the DWARF expression (disregarding the use of the
DW_AT_location
attribute for the purpose).
In the 1/22/24 meeting, we questioned whether a reference to a DWARF
procedure was necessary or ever used by a producer. It was noted that
in every case where a reference class form was allowed, an exprval
class form was also allowed (subject to verification). Thus, there
should be no need to use a reference to a DWARF procedure, when a
direct expression could be used, even if that expression is nothing
but a DW_OP_call_ref
to a DWARF procedure.
References to Section 2.19
Here are the locations in the document where Section 2.19 is explicitly referenced, and the attributes that may have a reference class:
-
Section 2.21, Byte and Bit Sizes:
DW_AT_byte_size
,DW_AT_bit_size
(both reference and exprval allowed) -
Section 5.1, Base Type Entries:
DW_AT_bit_size
(both allowed),DW_AT_data_bit_offset
(constant only, neither reference nor exprval) -
Section 5.5, Array Type Entries:
DW_AT_byte_stride
,DW_AT_bit_stride
(both reference and exprval allowed) -
Section 5.7.6, Data Member Entries:
DW_AT_data_bit_offset
(constant only),DW_AT_byte_size
,DW_AT_bit_size
(both reference and exprval allowed) -
Section 5.9, Enumeration Type Entries:
DW_AT_byte_stride
,DW_AT_bit_stride
(both reference and exprval allowed) -
Section 5.11, String Type Entries:
DW_AT_string_length
(locdesc, loclist, reference allowed, not exprval) -
Section 5.13, Subrange Type Entries:
DW_AT_byte_size
,DW_AT_bit_size
,DW_AT_lower_bound
,DW_AT_upper_bound
,DW_AT_count
(both reference and exprval allowed) -
Section 5.15, File Type Entries:
DW_AT_byte_size
,DW_AT_bit_size
(both reference and exprval allowed) -
Section 5.18.2, Allocation and Association Status:
DW_AT_allocated
,DW_AT_associated
(both reference and exprval allowed)
Only DW_AT_string_length
allows reference class forms but not
exprval. For this attribute a DW_FORM_exprloc
is interpreted
as locdesc instead. But that still allows an expression that
computes the actual value in the form of an implicit location
description, and that expression could use DW_OP_call_ref
.
Therefore, I propose to drop the wording allowing the use of a reference to a DWARF procedure (that is not a data object or common block).
Proposal
[Section and page numbers refer to the 12/5/23 working draft.]
Section 2.19 Static and Dynamic Values of Attributes, page 57
The second bullet about reference class should be rewritten as:
For a reference, the value of the attribute is determined indirectly via a reference to another debugging information entry.
If the referenced entry describes a constant (e.g., has a
DW_AT_const_value
attribute), the attribute value is the value of that constant.If the referenced entry describes a data object (see 4.1) or common block (see 4.2), the attribute value is the value of the data object or common block.
If the referenced entry represents a data member (e.g. has either a
DW_AT_data_member_location
or aDW_AT_data_bit_offset
attribute), the attribute value is the value of the data member.[non-normative] In previous versions of DWARF, a reference to a DWARF procedure (see 2.16) that is not a data object or common block was allowed. This type of reference was removed in DWARF 6. Instead, a producer may use an exprval or locdesc class form with a
DW_OP_call_ref
operator to call the DWARF procedure.
For the exprloc class bullet, see issue 230616.1.
Section 4.1 Data Object Entries, page 101
Remove the third bullet under item 9 (about DW_AT_default_value
), which reads:
- If the attribute form is of class reference, and the referenced entry is a DWARF procedure, the default value of the parameter is the value returned by calling that DWARF procedure (using
DW_OP_call_ref
), interpreted as a value of the type of the formal parameter.
Section 5.11 String Type Entries, page 132
Change:
The string type entry may also have a
DW_AT_string_length
attribute whose value is either a reference (see Section 2.19) yielding the length of the string or a location description yielding the location where the length of the string is stored in the program.
to:
The string type entry may also have a
DW_AT_string_length
attribute whose value is either (a) a reference (see Section 2.19) to another debugging information entry that provides the value of or the location of the length of the string, or (b) a location description...
2023-08-01: Revised. Added rules governing size and signedness of attribute values.
2023-11-24: Revised to add data members; added "unless specified otherwise" when talking about attributes giving a size, count, or enumerated value.
2024-01-04: Revised to clarify the use of other attributes of a referenced entry.
2024-01-30: Revised to drop wording allowing a reference to a DWARF procedure.
2024-02-05: Accepted.