diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp --- a/libcxxabi/src/private_typeinfo.cpp +++ b/libcxxabi/src/private_typeinfo.cpp @@ -615,10 +615,27 @@ // Possible future optimization: Take advantage of src2dst_offset // Get (dynamic_ptr, dynamic_type) from static_ptr - void **vtable = *static_cast(static_ptr); - ptrdiff_t offset_to_derived = reinterpret_cast(vtable[-2]); +#if __has_feature(cxx_abi_relative_vtable) + // The vtable address will point to the first virtual function, which is 8 + // bytes after the start of the vtable (4 for the offset from top + 4 for the typeinfo component). + uint32_t* vtable = *reinterpret_cast(static_ptr); + uint32_t offset_to_derived = vtable[-2]; const void* dynamic_ptr = static_cast(static_ptr) + offset_to_derived; - const __class_type_info* dynamic_type = static_cast(vtable[-1]); + + // The typeinfo component is now a relative offset to a proxy. + int32_t offset_to_ti_proxy = static_cast(vtable[-1]); + uint8_t* ptr_to_ti_proxy = + reinterpret_cast(vtable) + offset_to_ti_proxy; + const __class_type_info* dynamic_type = + *(reinterpret_cast<__class_type_info**>(ptr_to_ti_proxy)); +#else + void** vtable = *static_cast(static_ptr); + ptrdiff_t offset_to_derived = reinterpret_cast(vtable[-2]); + const void* dynamic_ptr = + static_cast(static_ptr) + offset_to_derived; + const __class_type_info* dynamic_type = + static_cast(vtable[-1]); +#endif // Initialize answer to nullptr. This will be changed from the search // results if a non-null answer is found. Regardless, this is what will