[libc++] Document our ABI guarantees and what ABI flags exist to modi… · llvm/llvm-project@f2fede6 (original) (raw)
``
1
`+
.. _ABIGuarantees:
`
``
2
+
``
3
`+
=======================
`
``
4
`+
libc++'s ABI Guarantees
`
``
5
`+
=======================
`
``
6
+
``
7
`+
libc++ provides multiple types of ABI guarantees. These include stability of the layout of structs, the linking of TUs
`
``
8
`+
built against different versions and configurations of the library, and more. This document describes what guarantees
`
``
9
`+
libc++ provides in these different areas as well as what options exist for vendors to affect these guarantees.
`
``
10
+
``
11
`+
Note that all of the guarantees listed below come with an asterisk that there may be circumstances where we deem it
`
``
12
`+
worth it to break that guarantee. These breaks are communicated to vendors by CCing #libcxx-vendors on GitHub. If you
`
``
13
`+
are a vendor, please ask to be added to that group to be notified about changes that potentially affect you.
`
``
14
+
``
15
`+
ABI flags
`
``
16
`+
=========
`
``
17
All the ABI flags listed below can be added to the ``__config_site`` header by the vendor to opt in to an ABI breaking
``
18
`+
change. These flags should never be set by the user. When porting libc++ to a new platform, vendord should consider
`
``
19
`+
which flags to enable, assuming that ABI stability is relevant to them. Please contact the libc++ team on Discord or
`
``
20
`+
through other means to be able to make an informed decision on which flags make sense to enable, and to avoid enabling
`
``
21
flags which may not be stable. Flags can be enabled via the ``LIBCXX_ABI_DEFINES`` CMake option.
``
22
+
``
23
+
``
24
`+
Stability of the Layout of Structs
`
``
25
`+
==================================
`
``
26
+
``
27
`+
The layout of any user-observable struct is kept stable across versions of the library and any user-facing options
`
``
28
`` +
documented :ref:here <libcxx-configuration-macros>
. There are a lot of structs that have internal names, but are none
``
``
29
`+
the less observable by users; for example through public aliases to these types or because they affect the layout of
`
``
30
`+
other types.
`
``
31
+
``
32
`+
There are multiple ABI flags which affect the layout of certain structs:
`
``
33
+
``
34
``_LIBCPP_ABI_ALTERNATE_STRING_LAYOUT``
``
35
`+
`
``
36
This changes the internal layout of ``basic_string`` to move the section that is used for the internal buffer to the
``
37
`+
front, making it eight byte aligned instead of being unaligned, improving the performance of some operations
`
``
38
`+
significantly.
`
``
39
+
``
40
``_LIBCPP_ABI_NO_ITERATOR_BASES``
``
41
`+
`
``
42
This removes the ``iterator`` base class from ``back_insert_iterator``, ``front_insert_iterator``, ``insert_iterator``,
``
43
``istream_iterator``, ``ostream_iterator``, ``ostreambuf_itreator``, ``reverse_iterator``, and ``raw_storage_iterator``.
``
44
`+
This doesn't directly affect the layout of these types in most cases, but may result in more padding being used when
`
``
45
they are used in combination, for example ``reverse_iterator<reverse_iterator<T>>``.
``
46
+
``
47
``_LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION``
``
48
`+
`
``
49
This changes the index type used inside ``variant`` to the smallest required type to reduce the datasize of variants in
``
50
`+
most cases.
`
``
51
+
``
52
``_LIBCPP_ABI_OPTIMIZED_FUNCTION``
``
53
`+
`
``
54
This significantly restructures how ``function`` is written to provide better performance, but is currently not ABI
``
55
`+
stable.
`
``
56
+
``
57
``_LIBCPP_ABI_NO_RANDOM_DEVICE_COMPATIBILITY_LAYOUT``
``
58
`+
`
``
59
This changes the layout of ``random_device`` to only holds state with an implementation that gets entropy from a file
``
60
(see ``_LIBCPP_USING_DEV_RANDOM``). When switching from this implementation to another one on a platform that has
``
61
already shipped ``random_device``, one needs to retain the same object layout to remain ABI compatible. This flag
``
62
`+
removes these workarounds for platforms that don't care about ABI compatibility.
`
``
63
+
``
64
``_LIBCPP_ABI_NO_COMPRESSED_PAIR_PADDING``
``
65
`+
`
``
66
This removes artifical padding from ``_LIBCPP_COMPRESSED_PAIR`` and ``_LIBCPP_COMPRESSED_TRIPLE``.
``
67
+
``
68
These macros are used inside the associative and unordered containers, ``deque``, ``forward_list``, ``future``,
``
69
``list``, ``basic_string``, ``function``, ``shared_ptr``, ``unique_ptr``, and ``vector`` to stay ABI compatible with the
``
70
legacy ``__compressed_pair`` type. ``__compressed_pair`` had historically been used to reduce storage requirements in
``
71
the case of empty types, but has been replaced by ``[[no_unique_address]]``. ``[[no_unique_address]]`` is significantly
``
72
`+
lighter in terms of compile time and debug information, and also improves the layout of structs further. However, to
`
``
73
`+
keep ABI stability, the additional improvements in layout had to be reverted by introducing artificial padding. This
`
``
74
`+
flag removes that artificial padding.
`
``
75
+
``
76
``_LIBCPP_ABI_IOS_ALLOW_ARBITRARY_FILL_VALUE``
``
77
`+
`
``
78
``basic_ios`` uses ``WEOF`` to indicate that the fill value is uninitialized. However, on platforms where the size of
``
79
``char_type`` is equal to or greater than the size of ``int_type`` and ``char_type`` is unsigned,
``
80
``char_traits<char_type>::eq_int_type()`` cannot distinguish between ``WEOF`` and ``WCHAR_MAX``. This flag changes
``
81
``basic_ios`` to instead track whether the fill value has been initialized using a separate boolean.
``
82
+
``
83
+
``
84
`+
Linking TUs which have been compiled against different releases of libc++
`
``
85
`+
=========================================================================
`
``
86
`+
libc++ supports linking TUs which have beeen compiled against different releases of libc++ by marking symbols with
`
``
87
`+
hidden visibility and changing the mangling of header-only functions in every release.
`
``
88
+
``
89
+
``
90
`+
Linking TUs which have been compiled with different flags affecting code gen
`
``
91
`+
============================================================================
`
``
92
`+
There are a lot of compiler (and library) flags which change the code generated for functions. This includes flags like
`
``
93
``-O1``, which are guaranteed by the compiler to not change the observable behaviour of a correct program, as well as
``
94
flags like ``-fexceptions``, which **do** change the observable behaviour. libc++ allows linking of TUs which have been
``
95
`+
compiled whith specific flags only and makes no guarantees for any of the flags not listed below.
`
``
96
+
``
97
`+
The flags allowed (in any combination) are:
`
``
98
- ``-f[no-]exceptions``
``
99
- ``-D_LIBCPP_HARDENING_MODE=_LIBCPP_HARDENING_MODE{_FAST,_EXTENSIVE,_DEBUG,_NONE}``
``
100
+
``
101
`+
Note that this does not provide any guarantees about user-defined functions, but only that the libc++ functions linked
`
``
102
`+
behave as the flags say.
`
``
103
+
``
104
+
``
105
`+
Availability of symbols in the built library (both static and shared)
`
``
106
`+
=====================================================================
`
``
107
`+
In general, libc++ does not make any guarantees about forwards-compability. That is, a TU compiled against new headers
`
``
108
`+
may not work with an older library. Vendors who require such support can leverage availability markup. On the other
`
``
109
`+
hand, backwards compatibility is generally guaranteed.
`
``
110
+
``
111
`+
There are multiple ABI flags that change the symbols exported from the built library:
`
``
112
+
``
113
``_LIBCPP_ABI_DO_NOT_EXPORT_BASIC_STRING_COMMON``
``
114
`+
`
``
115
This removes ``__basic_string_common<true>::__throw_length_error()`` and
``
116
``__basic_string_common<true>::__throw_out_of_range()``. These symbols have been used by ``basic_string`` in the past,
``
117
`+
but are not referenced from the headers anymore.
`
``
118
+
``
119
``_LIBCPP_ABI_DO_NOT_EXPORT_VECTOR_BASE_COMMON``
``
120
`+
`
``
121
This removes ``__vector_base_common<true>::__throw_length_error()`` and
``
122
``__vector_base_common<true>::__throw_out_of_range()``. These symbols have been used by ``vector`` in the past, but are
``
123
`+
not referenced from the headers anymore.
`
``
124
+
``
125
``_LIBCPP_ABI_DO_NOT_EXPORT_TO_CHARS_BASE_10``
``
126
`+
`
``
127
This removes ``__itoa::__u32toa()`` and ``__iota::__u64toa``. These symbols have been used by ``to_chars`` in the past,
``
128
`+
but are not referenced from the headers anymore.
`
``
129
+
``
130
``_LIBCPP_ABI_STRING_OPTIMIZED_EXTERNAL_INSTANTIATION``
``
131
`+
`
``
132
This replaces the symbols that are exported for ``basic_string`` to avoid exporting functions which are likely to be
``
133
`+
inlined as well as explicitly moving paths to the built library which are slow, improving fast-path inlining of multiple
`
``
134
`+
functions. This flag is currently unstable.
`
``
135
+
``
136
+
``
137
`+
Stability of the traits of a type
`
``
138
`+
=================================
`
``
139
`+
Whether a particular trait of a type is kept stable depends heavily on the type in question and the trait. The most
`
``
140
`+
important trait of a type to keep stable is the triviality for the purpose of calls, since that directly affects the
`
``
141
`+
function call ABI. Which types are considered non-trivial for the purpose of calls is defined in the
`
``
142
`` +
Itanium ABI <https://itanium-cxx-abi.github.io/cxx-abi/abi.html#definitions>
_.
``
``
143
``is_trivially_copyable`` should also be kept stable usually, since many programs depend on this trait for their own
``
144
`+
layouting. This isn't as rigid as the previous requirement though.
`
``
145
+
``
146
`+
There are multiple ABI flags that change traits of a struct:
`
``
147
+
``
148
``_LIBCPP_ABI_ENABLE_UNIQUE_PTR_TRIVIAL_ABI``
``
149
`+
`
``
150
This flag adds ``[[clang::trivial_abi]]`` to ``unique_ptr``, which makes it trivial for the purpose of calls.
``
151
+
``
152
``_LIBCPP_ABI_ENABLE_SHARED_PTR_TRIVIAL_ABI``
``
153
`+
`
``
154
This flag adds ``[[clang::trivial_abi]]`` to ``shared_ptr``, which makes it trivial for the purpose of calls.
``
155
+
``
156
+
``
157
`+
Types that public aliases reference
`
``
158
`+
===================================
`
``
159
`+
There are a lot of aliases that reference types with library internal names. For example, containers contain an
`
``
160
``iterator`` alias to a type with a library internal name. These have to always reference the same type, since the
``
161
`+
mangling of user-defined function overloads would change otherwise. A notable exception to this are the alias templates
`
``
162
`+
to type traits. There doesn't seem to be anybody who relies on these names staying the same, so it is OK to change what
`
``
163
`+
these aliases actually reference.
`
``
164
+
``
165
`+
There are multiple ABI flags which change which type an alias references:
`
``
166
+
``
167
``_LIBCPP_ABI_INCOMPLETE_TYPES_IN_DEQUE``
``
168
`+
`
``
169
This changes ``deque::iterator`` to avoid requring complete types for ``deque``.
``
170
+
``
171
``_LIBCPP_ABI_FIX_UNORDERED_CONTAINER_SIZE_TYPE``
``
172
`+
`
``
173
This changes the unordered container's ``size_types`` aliases.
``
174
+
``
175
``_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_ARRAY`` and ``_LIBCPP_ABI_USE_WRAP_ITER_IN_STD_STRING_VIEW``
``
176
`+
`
``
177
This changes the ``iterator`` and ``const_iterator`` of ``array`` and ``string_view`` respectively to reference
``
178
``__wrap_iter`` instead, which makes it less likely for users to depend on non-portable implementation details. This is
``
179
`+
especially useful because enabling bounded iterators hardening requires code not to make these assumptions.
`
``
180
+
``
181
``_LIBCPP_ABI_BOUNDED_ITERATORS``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STRING``, ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_VECTOR``, and ``_LIBCPP_ABI_BOUNDED_ITERATORS_IN_STD_ARRAY``
``
182
`+
`
``
183
These flags change the ``iterator`` member of various classes to reference hardened iterators instead. See the
``
184
`` +
:ref:hardening documentation <hardening>
for more details.
``
``
185
+
``
186
+
``
187
`+
Meaning of values
`
``
188
`+
=================
`
``
189
`+
The meaning of specific values can usually not be changed, since programs compiled against older versions of the headers
`
``
190
`+
may check for these values. These specific values don't have to be hard-coded, but can also depend on user input.
`
``
191
+
``
192
`+
There are multiple ABI flags that change the meaning of particular values:
`
``
193
+
``
194
``_LIBCPP_ABI_REGEX_CONSTANTS_NONZERO``
``
195
`+
`
``
196
This changes the value of ``regex_constants::syntax_option-type::ECMAScript`` to be standards-conforming.
``
197
+
``
198
``_LIBCPP_ABI_FIX_CITYHASH_IMPLEMENTATION``
``
199
`+
`
``
200
This flag fixes the implementation of CityHash used for ``hash<fundamental-type>``. The incorrect implementation of
``
201
`+
CityHash has the roblem that it drops some bits on the floor. Fixing the implementation changes the hash of values,
`
``
202
`+
resulting in an ABI break.
`
``
203
+
``
204
`+
inline namespaces
`
``
205
`+
=================
`
``
206
`+
Inline namespaces which contain types that are observable by the user need to be kept the same, since they affect
`
``
207
mangling. Almost all of libc++'s symbols are inside an inline namespace. By default that namespace is ``__1``, but can
``
208
`` +
be changed by the vendor by setting LIBCXX_ABI_NAMESPACE
during CMake configuration. There is also
``
``
209
``_LIBCPP_ABI_NO_FILESYSTEM_INLINE_NAMESPACE`` to remove the ``__fs`` namespace from surrounding the ``filesystem``
``
210
`+
namespace. This shortens the mangling of the filesystem symbols a bit.
`