Summary: | vtable offset position seems wrong | ||
---|---|---|---|
Product: | libabigail | Reporter: | Ben Woodard <woodard> |
Component: | default | Assignee: | Dodji Seketeli <dodji> |
Status: | NEW --- | ||
Severity: | normal | CC: | libabigail |
Priority: | P2 | ||
Version: | unspecified | ||
Target Milestone: | --- | ||
Host: | Target: | ||
Build: | Last reconfirmed: | ||
Bug Depends on: | |||
Bug Blocks: | 27019 |
Description
Ben Woodard
2021-12-02 00:21:21 UTC
The removal of the int parameter to the virtual class destructor is probably a second problem but that could be a bug in clang where it doesn't give virtual destructors a parameter (I would have to look at the assembly) or it may be a problem with the DWARF that clang generates for that function. I would have thought that removing the parameter would have changed the C++ function name mangling thus making the functions linkage name different. If the resulting codegen didn't make a destructor which took the int, it would have serious ABI implications that would break at execution time. This suggests to me that it is more likely a clang DWARF generation bug. Anyway, I think that the removal of the int parameter is a different problem from the offset in the vtable. Some background information on the hidden parameter to a class's virtual destructor and why it takes an int. https://stackoverflow.com/questions/7750280/how-does-virtual-destructor-work-in-c/7750873#7750873 it appears in the DWARF that clang explicitly provides the vtable offset using the DW_AT_vtable_elem_location for the function but GCC relies on the C++ABI rules to layout the vtable and so the element location in the vtable is inferred rather than being specified. So it appears like when libabigail doesn't get an explicit vtable_element it sets its position to -1 which is 0xFFFF FFFF FFFF FFFF 18446744073709551615 for a 64b int in twos compliment. There is some trickiness to inferring the vtable position of a particular function. It is by order of declaration in the class declaration. Quoting the C++ABI section 2.5.2 http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-components "The order of the virtual function pointers in a virtual table is the order of declaration of the corresponding member functions in the class. If an implicitly-declared copy assignment operator, move assignment operator, or destructor is virtual, it is treated as if it were declared at the end of the class, in that order. (Implicitly-declared assignment operators may be virtual if a base class declares a virtual assignment operator taking a reference to a derived class type.)" Unless I am missing something, it would seem like this logic would have to be implemented in libabigail to ensure that the vtable order is right. This is from the abixml from the gcc version of the library: <function-decl name='~section' mangled-name='_ZN7abigail3ini6config7sectionD4Ev' filepath='../../../../Work/libabigail/src/abg-ini.cc' line='856' column='1' visibility='default' binding='global' size-in-bits='64'> <parameter type-id='type-id-20101' is-artificial='yes'/> <parameter type-id='type-id-8712' is-artificial='yes'/> <return type-id='type-id-3'/> </function-decl> </member-function> <member-function access='public' destructor='yes' vtable-offset='-1'> <function-decl name='~section' mangled-name='_ZN7abigail3ini6config7sectionD0Ev' filepath='../../../../Work/libabigail/src/abg-ini.cc' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN7abigail3ini6config7sectionD0Ev'> <parameter type-id='type-id-20101' is-artificial='yes'/> <parameter type-id='type-id-8712' is-artificial='yes'/> <return type-id='type-id-3'/> </function-decl> </member-function> <member-function access='public' destructor='yes' vtable-offset='-1'> <function-decl name='~section' mangled-name='_ZN7abigail3ini6config7sectionD2Ev' filepath='../../../../Work/libabigail/src/abg-ini.cc' line='856' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN7abigail3ini6config7sectionD2Ev'> <parameter type-id='type-id-20101' is-artificial='yes'/> <parameter type-id='type-id-8712' is-artificial='yes'/> <return type-id='type-id-3'/> </function-decl> </member-function> There are the vtable-offsets being set to -1. ---- Here is the abixml for the clang version. <member-function access='public' destructor='yes' vtable-offset='0'> <function-decl name='~section' mangled-name='_ZN7abigail3ini6config7sectionD0Ev' filepath='/home/ben/Shared/test/libabigail-test/l5/../../../Work/libabigail/include/abg-ini.h' line='386' column='1' visibility='default' binding='global' size-in-bits='64' elf-symbol-id='_ZN7abigail3ini6config7sectionD2Ev'> <parameter type-id='type-id-19664' is-artificial='yes'/> <return type-id='type-id-11'/> </function-decl> </member-function> it does appear that the parameter is missing. Note that every single virtual destructor in code compiled by gcc has a -1 vtable offset. Other virtual methods seem to have reasonable numbers. All the virtual destructors in the same code compiled by LLVM have an offset of 0. |