Issue 250506.3: Replace DW_AT_vtable_elem_location Attribute with DW_AT_vtable_elem_index
| Author: | Cary Coutant |
|---|---|
| Champion: | Cary Coutant |
| Date submitted: | 2025-05-06 |
| Date revised: | 2025-09-24 |
| Date closed: | 2025-10-13 |
| Type: | Enhancement |
| Status: | Accepted |
| DWARF version: | 6 |
Comparing original with 2025-09-24. [ View this version ] [ Return to the latest version ]
This is the third part of a three-part proposal. The first part, [250506.1][250506.1], proposes a standard mechanism for locating the virtual function table (vtable) given an object of a polymorphic class.
This second part, [250506.2][250506.2], proposes a standard mechanism
The second part, [250506.2][250506.2], proposes a standard mechanism
for identifying the most-derived class of an object, given its vtable location, in order to support downcasting of pointers while debugging.
The third part, [250506.3][250506.3], proposes a fix to the
This third part, [250506.3][250506.3], proposes a fix to the
`DW_AT_vtable_elem_location` attribute,
which appears to be incorrectly implemented in compilers today.
## Background
See [250506.1][250506.1] for the full background and history.
## Problem
The third request in [PR 7081][pr7081] was to identify a
function's vtable entry, which was already supported in
DWARF at the time, but hadn't yet been implemented in GCC at
the time of the PR.
Looking at the DWARF generated by GCC (and I'm guessing LLVM
does the same), I see `DW_AT_vtable_elem_location` attributes that
look like this:
<1b8> DW_AT_vtable_elem_location: 2 byte block: 10 0 (DW_OP_constu: 0)
This is not correct DWARF! It's supposed to be a location
description, and this is merely a DWARF expression that
evaluates to the index of the vtable slot. The description
of the attribute says that address of an object of the
enclosing type is pushed onto the expression stack, so there
really ought to be a `DW_OP_deref` to get the vtable pointer
on the stack, followed by a `DW_OP_constu` with a byte
offset, and a `DW_OP_add` to compute the final location.
Now if we compare this to `DW_AT_data_member_location`, we see
that one valid form for that attribute is an integer
constant providing the offset of the data member. But even
there, if the attribute has a location expression, it should
compute an actual address, not just deliver the offset.
It would seem an obvious and useful extension to DWARF to
allow `DW_AT_vtable_elem_location` to take a "constant" class
form that provides the offset relative to the start of the
vtable, so an acceptable form of the attribute might be:
<1b8> DW_AT_vtable_elem_location: 0 # (using a constant class form)
## Proposal There's no clean way to legitimize what GCC and LLVM are generating,
but there is no reason why the `DW_AT_vtable_elem_location` attribute should not be able to take a constant class form, which would allow the compilers to generate a smaller DIE with just the vtable slot offset.
and there is no compelling reason to require a location expression for locating vtable slots when an index is sufficient. I propose to deprecate the misused attribute and replace it with a new one that provides the simple slot index.
In Section 2.2, "Attribute Types," in Table 2.2, add "(deprecated)" to the row for `DW_AT_vtable_elem_location`, and add a new row: > | Attribute | Usage | > | --------- | ----- | > | `DW_AT_vtable_elem_index` | Virtual function vtable slot index |
In Section 5.7.8, "Member Function Entries," change the sixth
In Section 5.7.8, "Member Function Entries," replace the sixth
paragraph from:
paragraph:
> An entry for a virtual function also has a > `DW_AT_vtable_elem_location` attribute whose value > contains a location description yielding the address of > the slot for the function within the virtual function > table for the enclosing class. The address of an object of > the enclosing type is pushed onto the expression stack > before the location description is evaluated.
to:
with:
> An entry for a virtual function also has a
> `DW_AT_vtable_elem_location` attribute whose value
> `DW_AT_vtable_elem_index` attribute whose value contains a > constant, which is the zero-based index of the slot for > the function within the virtual table for the enclosing > class.
> contains either a constant offset or a location > description. If the value is a constant offset, it is the > offset of the slot for the function within the virtual > function table for the enclosing class. If the value is a > location description, the address of an object of the > enclosing type is pushed onto the expression stack before > the location description is evaluated, and the result is > the location of the slot within the virtual function > table.
In Section 7.5.4, "Attribute Encodings," Table 7.5, add "constant" to the list of classes allowed for `DW_AT_vtable_elem_location`.
> *The `DW_AT_vtable_elem_location` attribute from earlier > versions of DWARF is deprecated.*
## Optional Variation
In Section 7.5.4, "Attribute Encodings," Table 7.5, replace `DW_AT_vtable_elem_location` with a note that it has been deprecated, and add a new row:
- Add a new `DW_AT_vtable_elem_index` attribute that accepts a slot index instead of a slot offset.
> | Attribute name | Value | Classes | > | -------------- | ----- | ------- | > | `DW_AT_vtable_elem_index` | TBD | constant |
[230524.1]: https://dwarfstd.org/issues/230524.1.html [250506.1]: https://dwarfstd.org/issues/250506.1.html [250506.2]: https://dwarfstd.org/issues/250506.2.html [250506.3]: https://dwarfstd.org/issues/250506.3.html [huey2025]: https://lists.dwarfstd.org/pipermail/dwarf-discuss/2025-April/002671.html [pr11208]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11208 [louzon2022]: https://lists.dwarfstd.org/pipermail/dwarf-discuss/2022-February/002127.html [pr7081]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=7081 [clang130255]: https://github.com/llvm/llvm-project/pull/130255 [rust125126]: https://github.com/rust-lang/rust/issues/125126 [allen2025]: https://lists.dwarfstd.org/pipermail/dwarf-discuss/2025-May/002690.html
--- 2025-09-24: [Revised][diff1]. Deprecate `DW_AT_vtable_elem_location` and add `DW_AT_vtable_elem_index`.