Issue 250506.2: Improve Support for Downcasting Objects
| Author: | Cary Coutant |
|---|---|
| Champion: | Cary Coutant |
| Date submitted: | 2025-05-06 |
| Date revised: | 2025-11-20 |
| Date closed: | 2026-01-05 |
| Type: | Enhancement |
| Status: | Accepted |
| DWARF version: | 6 |
Comparing original with 2025-11-20. [ View this version ] [ Return to the latest version ]
This is the second 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 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 `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 second request in [PR 7081][pr7081] was for a way to associate vtables with their class definitions, to make it easier to downcast pointers from the base class to the most-derived class, based on the vtable pointer. The clang and Rust approaches are similar, but not exactly the same, and the Concurrent approach puts a relocatable address of the vtable in the type DIE. Adding an attribute directly to the type DIE that points to the vtable has the disadvantage that type de-duplication might discard all but one of several copies of a vtable, if multiple copies of the vtable remain after linking. We also desire a fast lookup mechanism where a vtable address can be translated into the corresponding type DIE without requiring the consumer to parse all the DWARF info at once. ## Proposal To make the association between a vtable and a type DIE, we add a new DWARF tag for a vtable object, `DW_TAG_vtable`, whose `DW_AT_location` provides the address of the vtable, and whose (new) `DW_AT_vtable_type` attribute points to the type DIE corresponding to the vtable. Additional attributes may provide additional details about the vtable.
To provide for faster lookup of vtable addresses, we add a
To provide for faster lookup of vtable addresses, we add
`DW_AT_vtable_ranges` attribute to the compilation unit DIEs.
vtable ranges to the `DW_AT_ranges` attribute of the compilation unit DIE.
In Section 2.1, "The Debugging Information Entry," add `DW_TAG_vtable` to Table 2.1.
In Section 2.2, "Attribute Types," add two rows to Table 2.2:
In Section 2.2, "Attribute Types," add a row to Table 2.2:
> | Attribute | Usage | > | --------- | ----- | > | `DW_AT_vtable_type` | Type corresponding to a vtable |
> | `DW_AT_vtable_ranges` | Ranges of vtable addresses |
In Section 3.1.1, "Full and Partial Compilation Unit Entries," add a numbered item:
In Section 2.16, "Code Addresses, Ranges and Base Addresses," change the first paragraph as follows:
> 18\. A `DW_AT_vtable_ranges` attribute, whose value is of > class rnglist, which provides a range of addresses containing > vtables defined by this compilation unit.
> Any debugging information entry describing an entity that > has a machine code address or range of machine code > addresses <ins>or virtual tables (see Section 4.4)</ins>, > which includes compilation units, module initialization, > subroutines, lexical blocks, try/catch blocks (see Section > 4.8 on page 108), labels and the like, may have
In Section 3.1.2, "Skeleton Compilation Unit Entries,"
In Section 4.1.2 [OLD 3.1.2], "Skeleton Compilation Unit Entries,"
add a numbered item:
change item 2 as follows:
> 9\. A `DW_AT_vtable_ranges` attribute.
> 2\. Either a `DW_AT_low_pc` and `DW_AT_high_pc` pair of > attributes or a `DW_AT_ranges` attribute whose values encode > the contiguous or non-contiguous address ranges, > respectively, of the machine instructions > <ins>and the virtual tables</ins> > generated for the compilation unit (see Section 2.16 on page 34).
In Chapter 4, "Data Object and Object List Entries," add a new section:
In Chapter 5 [OLD 4], "Data Object and Object List Entries," add a new section:
> 4.4 Virtual Function Table (vtable) Entries
> 5.4 Virtual Function Table (vtable) Entries
> > Virtual function tables (vtables) are represented by > debugging information entries with the tag `DW_TAG_vtable`. > It may have the following attributes: > > 1. A `DW_AT_location` attribute, whose value describes > the location of the vtable. > > 2. A `DW_AT_vtable_type` attribute, which is a reference > to the debugging information entry for the associated > type. > > 3. A `DW_AT_artificial` attribute, which is a flag > indicating that the vtable entry represents an object > created by the compiler that does not correspond directly to > source code. > > *Virtual Function Table entries allow a debugger to > associate vtables with the corresponding class type, in > order to downcast a pointer whose type is > "pointer-to-base-class" to a pointer with type > "pointer-to-derived-class," using the vtable pointer of > the object.*
In Section 7.5.3, "Abbreviations Tables," add a row to Table 7.3:
In Section 8.5.3 [OLD 7.5.3], "Abbreviations Tables," add a row to Table 8.3:
> | TAG name | Value | > | -------- | ----- | > | `DW_TAG_vtable` | TBD |
In Section 7.5.4, "Attribute Encodings," add two rows to Table 7.5:
In Section 8.5.4 [OLD 7.5.4], "Attribute Encodings," add a row to Table 8.5:
> | Attribute name | Value | Classes | > | -------------- | ----- | ------- | > | `DW_AT_vtable_type` | TBD | reference |
> | `DW_AT_vtable_ranges` | TBD | rnglist |
In Appendix A, "Attribute by Tag," add a row for `DW_TAG_vtable`: > | TAG name | Applicable attributes | > | -------- | --------------------- | > | `DW_TAG_vtable` | `DW_AT_artificial` <br> `DW_AT_location` <br> `DW_AT_vtable_type` |
In the same table, add `DW_AT_vtable_ranges` to the row for `DW_TAG_compile_unit`.
## Optional Variations - If useful, we could add additional attributes to the `DW_TAG_vtable` DIE to identify construction/destruction vtables, and A-in-B vtables.
- Instead of `DW_AT_vtable_ranges`, we could require including the vtable ranges in the `DW_AT_ranges` attribute of a CU.
[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-11-20: [Revised][diff1] to put vtable ranges in the `DW_AT_ranges` attribute instead of a new attribute; updated chapter and section numbers. 2025-12-08: Accepted.