brintos

brintos / llvm-project-archived public Read only

0
0
Text · 12.8 KiB · 4d4674c Raw
215 lines · plain
1.. _ABIGuarantees:2 3=======================4libc++'s ABI Guarantees5=======================6 7libc++ provides multiple types of ABI guarantees. These include stability of the layout of structs, the linking of TUs8built against different versions and configurations of the library, and more. This document describes what guarantees9libc++ provides in these different areas as well as what options exist for vendors to affect these guarantees.10 11Note that all of the guarantees listed below come with an asterisk that there may be circumstances where we deem it12worth it to break that guarantee. These breaks are communicated to vendors by CCing #libcxx-vendors on GitHub. If you13are a vendor, please ask to be added to that group to be notified about changes that potentially affect you.14 15ABI flags16=========17All the ABI flags listed below can be added to the ``__config_site`` header by the vendor to opt in to an ABI breaking18change. These flags should never be set by the user. When porting libc++ to a new platform, vendord should consider19which flags to enable, assuming that ABI stability is relevant to them. Please contact the libc++ team on Discord or20through other means to be able to make an informed decision on which flags make sense to enable, and to avoid enabling21flags which may not be stable. Flags can be enabled via the ``LIBCXX_ABI_DEFINES`` CMake option.22 23 24Stability of the Layout of Structs25==================================26 27The layout of any user-observable struct is kept stable across versions of the library and any user-facing options28documented :ref:`here <libcxx-configuration-macros>`. There are a lot of structs that have internal names, but are none29the less observable by users; for example through public aliases to these types or because they affect the layout of30other types.31 32There are multiple ABI flags which affect the layout of certain structs:33 34``_LIBCPP_ABI_ALTERNATE_STRING_LAYOUT``35---------------------------------------36This changes the internal layout of ``basic_string`` to move the section that is used for the internal buffer to the37front, making it eight byte aligned instead of being unaligned, improving the performance of some operations38significantly.39 40``_LIBCPP_ABI_NO_ITERATOR_BASES``41---------------------------------42This removes the ``iterator`` base class from ``back_insert_iterator``, ``front_insert_iterator``, ``insert_iterator``,43``istream_iterator``, ``ostream_iterator``, ``ostreambuf_iterator``, ``reverse_iterator``, and ``raw_storage_iterator``.44This doesn't directly affect the layout of these types in most cases, but may result in more padding being used when45they are used in combination, for example ``reverse_iterator<reverse_iterator<T>>``.46 47``_LIBCPP_ABI_NO_REVERSE_ITERATOR_SECOND_MEMBER``48-------------------------------------------------49This removes a second member in ``reverse_iterator`` that is unused after LWG2360.50 51``_LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION``52-------------------------------------------------53This changes the index type used inside ``variant`` to the smallest required type to reduce the datasize of variants in54most cases.55 56``_LIBCPP_ABI_OPTIMIZED_FUNCTION``57----------------------------------58This significantly restructures how ``function`` is written to provide better performance, but is currently not ABI59stable.60 61``_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT``62-----------------------------------------------------63This changes the layout of ``random_device`` to only holds state with an implementation that gets entropy from a file64(see ``_LIBCPP_USING_DEV_RANDOM``). When switching from this implementation to another one on a platform that has65already shipped ``random_device``, one needs to retain the same object layout to remain ABI compatible. This flag66removes these workarounds for platforms that don't care about ABI compatibility.67 68``_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING``69------------------------------------------70This removes artificial padding from ``_LIBCPP_COMPRESSED_PAIR`` and ``_LIBCPP_COMPRESSED_TRIPLE``.71 72These macros are used inside the associative and unordered containers, ``deque``, ``forward_list``, ``future``,73``list``, ``basic_string``, ``function``, ``shared_ptr``, ``unique_ptr``, and ``vector`` to stay ABI compatible with the74legacy ``__compressed_pair`` type. ``__compressed_pair`` had historically been used to reduce storage requirements in75the case of empty types, but has been replaced by ``[[no_unique_address]]``. ``[[no_unique_address]]`` is significantly76lighter in terms of compile time and debug information, and also improves the layout of structs further. However, to77keep ABI stability, the additional improvements in layout had to be reverted by introducing artificial padding. This78flag removes that artificial padding.79 80``_LIBCPP_ABI_IOS_ALLOW_ARBITRARY_FILL_VALUE``81----------------------------------------------82``basic_ios`` uses ``WEOF`` to indicate that the fill value is uninitialized. However, on platforms where the size of83``char_type`` is equal to or greater than the size of ``int_type`` and ``char_type`` is unsigned,84``char_traits<char_type>::eq_int_type()`` cannot distinguish between ``WEOF`` and ``WCHAR_MAX``. This flag changes85``basic_ios`` to instead track whether the fill value has been initialized using a separate boolean.86 87 88Linking TUs which have been compiled against different releases of libc++89=========================================================================90libc++ supports linking TUs which have been compiled against different releases of libc++ by marking symbols with91hidden visibility and changing the mangling of header-only functions in every release.92 93 94Linking TUs which have been compiled with different flags affecting code gen95============================================================================96There are a lot of compiler (and library) flags which change the code generated for functions. This includes flags like97``-O1``, which are guaranteed by the compiler to not change the observable behaviour of a correct program, as well as98flags like ``-fexceptions``, which **do** change the observable behaviour. libc++ allows linking of TUs which have been99compiled with specific flags only and makes no guarantees for any of the flags not listed below.100 101The flags allowed (in any combination) are:102- ``-f[no-]exceptions``103- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE{_FAST,_EXTENSIVE,_DEBUG,_NONE}``104 105Note that this does not provide any guarantees about user-defined functions, but only that the libc++ functions linked106behave as the flags say.107 108 109Availability of symbols in the built library (both static and shared)110=====================================================================111In general, libc++ does not make any guarantees about forwards-compatibility. That is, a TU compiled against new headers112may not work with an older library. Vendors who require such support can leverage availability markup. On the other113hand, backwards compatibility is generally guaranteed.114 115There are multiple ABI flags that change the symbols exported from the built library:116 117``_LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON``118-------------------------------------------------119This removes ``__basic_string_common<true>::__throw_length_error()`` and120``__basic_string_common<true>::__throw_out_of_range()``. These symbols have been used by ``basic_string`` in the past,121but are not referenced from the headers anymore.122 123``_LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON``124------------------------------------------------125This removes ``__vector_base_common<true>::__throw_length_error()`` and126``__vector_base_common<true>::__throw_out_of_range()``. These symbols have been used by ``vector`` in the past, but are127not referenced from the headers anymore.128 129``_LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10``130----------------------------------------------131This removes ``__itoa::__u32toa()`` and ``__iota::__u64toa``. These symbols have been used by ``to_chars`` in the past,132but are not referenced from the headers anymore.133 134``_LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION``135-------------------------------------------------------136This replaces the symbols that are exported for ``basic_string`` to avoid exporting functions which are likely to be137inlined as well as explicitly moving paths to the built library which are slow, improving fast-path inlining of multiple138functions. This flag is currently unstable.139 140 141Stability of the traits of a type142=================================143Whether a particular trait of a type is kept stable depends heavily on the type in question and the trait. The most144important trait of a type to keep stable is the triviality for the purpose of calls, since that directly affects the145function call ABI. Which types are considered non-trivial for the purpose of calls is defined in the146`Itanium ABI <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#definitions>`_.147``is_trivially_copyable`` should also be kept stable usually, since many programs depend on this trait for their own148layouting. This isn't as rigid as the previous requirement though.149 150There are multiple ABI flags that change traits of a struct:151 152``_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI``153---------------------------------------------154This flag adds ``[[clang::trivial_abi]]`` to ``unique_ptr``, which makes it trivial for the purpose of calls.155 156``_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI``157---------------------------------------------158This flag adds ``[[clang::trivial_abi]]`` to ``shared_ptr``, which makes it trivial for the purpose of calls.159 160 161Types that public aliases reference162===================================163There are a lot of aliases that reference types with library internal names. For example, containers contain an164``iterator`` alias to a type with a library internal name. These have to always reference the same type, since the165mangling of user-defined function overloads would change otherwise. A notable exception to this are the alias templates166to type traits. There doesn't seem to be anybody who relies on these names staying the same, so it is OK to change what167these aliases actually reference.168 169There are multiple ABI flags which change which type an alias references:170 171``_LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE``172-----------------------------------------173This changes ``deque::iterator`` to avoid requiring complete types for ``deque``.174 175``_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE``176-------------------------------------------------177This changes the unordered container's ``size_types`` aliases.178 179``_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY`` and ``_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW``180-----------------------------------------------------------------------------------------------181This changes the ``iterator`` and ``const_iterator`` of ``array`` and ``string_view`` respectively to reference182``__wrap_iter`` instead, which makes it less likely for users to depend on non-portable implementation details. This is183especially useful because enabling bounded iterators hardening requires code not to make these assumptions.184 185``_LIBCPP_ABI_BOUNDED_ITERATORS``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR``, and ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY``186-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------187These flags change the ``iterator`` member of various classes to reference hardened iterators instead. See the188:ref:`hardening documentation <hardening>` for more details.189 190 191Meaning of values192=================193The meaning of specific values can usually not be changed, since programs compiled against older versions of the headers194may check for these values. These specific values don't have to be hard-coded, but can also depend on user input.195 196There are multiple ABI flags that change the meaning of particular values:197 198``_LIBCPP_ABI_REGEX_CONSTANTS_NONZERO``199---------------------------------------200This changes the value of ``regex_constants::syntax_option-type::ECMAScript`` to be standards-conforming.201 202``_LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION``203-------------------------------------------204This flag fixes the implementation of CityHash used for ``hash<fundamental-type>``. The incorrect implementation of205CityHash has the problem that it drops some bits on the floor. Fixing the implementation changes the hash of values,206resulting in an ABI break.207 208inline namespaces209=================210Inline namespaces which contain types that are observable by the user need to be kept the same, since they affect211mangling. Almost all of libc++'s symbols are inside an inline namespace. By default that namespace is ``__1``, but can212be changed by the vendor by setting `LIBCXX_ABI_NAMESPACE` during CMake configuration. There is also213``_LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE`` to remove the ``__fs`` namespace from surrounding the ``filesystem``214namespace. This shortens the mangling of the filesystem symbols a bit.215