<div dir="ltr"><div></div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Jan 24, 2020 at 11:42 AM Leonard Chan <<a href="mailto:leonardchan@google.com">leonardchan@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hi all,<div><br></div><div>We're attempting to implement a <a href="https://reviews.llvm.org/D72959" target="_blank">PC-relative vtable ABI for C++ in Fuchsia</a> and I wanted to ask about the etiquette for contributions to libc++abi for different ABIs.</div><div><br></div><div>The purpose of this ABI is to replace the 64 bit absolute address of virtual functions in a vtable with 32 bit relative offsets between the vtable and the virtual function. This would effectively make the vtable readonly and help save on memory by reducing copy on write pages. The same technique is applied to the typeinfo pointer in the vtable, replacing it with an offset to the typeinfo object.</div><div><br></div><div>We ran into an issue though where changing the size and value of this typeinfo component breaks dynamic_cast. More specifically, in this snippet from __dynamic_cast in libc++abi:</div><div><br></div><div>```</div><div><font face="monospace">    // Get (dynamic_ptr, dynamic_type) from static_ptr<br>    void **vtable = *static_cast<void ** const *>(static_ptr);<br>    ptrdiff_t offset_to_derived = reinterpret_cast<ptrdiff_t>(vtable[-2]);<br>    const void* dynamic_ptr = static_cast<const char*>(static_ptr) + offset_to_derived;<br>    const __class_type_info* dynamic_type = static_cast<const __class_type_info*>(vtable[-1]);</font><br></div><div>```</div><div><br></div><div>there is an assumption that the offset_to_derived is 16 bytes behind the first function in the vtable, where for us it would take 12 bytes (8 for the offset to top + 4 for the relative rtti component). The same thing applies to __class_type_info which instead should be 4 bytes behind the vtable pointer and would require an additional dereference and add since it's an offset for us.</div><div><br></div><div>Off the top of my head, it seems like a simple solution to this is to create another __dynamic_cast function (like __dynamic_cast_fuchsia_relative or something) that would calculate these variables correctly for our ABI.</div></div></blockquote><div><br></div><div>Could this be a build configuration (e.g. CMake option that changes the behavior or __dynamic_cast) that we would set when compiling libc++abi for Fuchsia? I don't think we want to change the existing code to use a different function when compiling for Fuchsia, rather we want the new ABI to be the default on Fuchsia and be completely transparent to the code and developers.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>So, finally to my question, is the proper etiquette for making ABI changes this way to contribute them to libc++abi directly, or is there another recommended way? Or is there a better way to address this problem that I haven't thought of yet? So far, this seems to be the only RTTI breakage I could find, but I'm still actively looking.</div><div><br></div><div>Thanks,</div><div>Leonard</div></div>
</blockquote></div></div>