[libcxx-commits] [PATCH] D77606: [libcxxabi] Add macro for changing functions to support the relative vtables ABI
Leonard Chan via Phabricator via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Nov 25 13:40:20 PST 2020
leonardchan updated this revision to Diff 307712.
leonardchan marked 2 inline comments as done.
leonardchan added a comment.
Removed formatting for existing code.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D77606/new/
https://reviews.llvm.org/D77606
Files:
libcxxabi/src/private_typeinfo.cpp
Index: libcxxabi/src/private_typeinfo.cpp
===================================================================
--- libcxxabi/src/private_typeinfo.cpp
+++ libcxxabi/src/private_typeinfo.cpp
@@ -61,6 +61,16 @@
return x == y || strcmp(x->name(), y->name()) == 0;
}
+static inline ptrdiff_t update_offset_to_base(const char* vtable,
+ ptrdiff_t offset_to_base) {
+#if __has_feature(cxx_abi_relative_vtable)
+ // VTable components are 32 bits in the relative vtables ABI.
+ return *reinterpret_cast<const int32_t*>(vtable + offset_to_base);
+#else
+ return *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+#endif
+}
+
namespace __cxxabiv1
{
@@ -297,7 +307,7 @@
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(adjustedPtr);
- offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+ offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
}
__base_type->has_unambiguous_public_base(
@@ -615,10 +625,26 @@
// Possible future optimization: Take advantage of src2dst_offset
// Get (dynamic_ptr, dynamic_type) from static_ptr
+#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).
+ const int32_t* vtable =
+ *reinterpret_cast<const int32_t* const*>(static_ptr);
+ int32_t offset_to_derived = vtable[-2];
+ const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
+
+ // The typeinfo component is now a relative offset to a proxy.
+ int32_t offset_to_ti_proxy = vtable[-1];
+ const uint8_t* ptr_to_ti_proxy =
+ reinterpret_cast<const uint8_t*>(vtable) + offset_to_ti_proxy;
+ const __class_type_info* dynamic_type =
+ *(reinterpret_cast<const __class_type_info* const*>(ptr_to_ti_proxy));
+#else
void **vtable = *static_cast<void ** const *>(static_ptr);
ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);
const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;
const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(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
@@ -1267,7 +1293,7 @@
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(current_ptr);
- offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+ offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
__base_type->search_above_dst(info, dst_ptr,
static_cast<const char*>(current_ptr) + offset_to_base,
@@ -1287,7 +1313,7 @@
if (__offset_flags & __virtual_mask)
{
const char* vtable = *static_cast<const char*const*>(current_ptr);
- offset_to_base = *reinterpret_cast<const ptrdiff_t*>(vtable + offset_to_base);
+ offset_to_base = update_offset_to_base(vtable, offset_to_base);
}
__base_type->search_below_dst(info,
static_cast<const char*>(current_ptr) + offset_to_base,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D77606.307712.patch
Type: text/x-patch
Size: 3459 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/libcxx-commits/attachments/20201125/3ad735b6/attachment-0001.bin>
More information about the libcxx-commits
mailing list