|
1 | 1 | Auto generated patch. Do not edit or delete it, even if empty. |
2 | | -diff -ruN --strip-trailing-cr a/libcxx/src/include/overridable_function.h b/libcxx/src/include/overridable_function.h |
3 | | ---- a/libcxx/src/include/overridable_function.h |
4 | | -+++ b/libcxx/src/include/overridable_function.h |
5 | | -@@ -29,81 +29,106 @@ |
6 | | - // This is a low-level utility which does not work on all platforms, since it needs |
7 | | - // to make assumptions about the object file format in use. Furthermore, it requires |
8 | | - // the "base definition" of the function (the one we want to check whether it has been |
9 | | --// overridden) to be defined using the _LIBCPP_OVERRIDABLE_FUNCTION macro. |
10 | | -+// overridden) to be annotated with the _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro. |
11 | | - // |
12 | | - // This currently works with Mach-O files (used on Darwin) and with ELF files (used on Linux |
13 | | - // and others). On platforms where we know how to implement this detection, the macro |
14 | | - // _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION is defined to 1, and it is defined to 0 on |
15 | | --// other platforms. The _LIBCPP_OVERRIDABLE_FUNCTION macro expands to regular function |
16 | | --// definition on unsupported platforms so that it can be used to decorate functions |
17 | | --// regardless of whether detection is actually supported. |
18 | | -+// other platforms. The _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro is defined to |
19 | | -+// nothing on unsupported platforms so that it can be used to decorate functions regardless |
20 | | -+// of whether detection is actually supported. |
21 | | - // |
22 | | - // How does this work? |
23 | | - // ------------------- |
24 | | - // |
25 | | - // Let's say we want to check whether a weak function `f` has been overridden by the user. |
26 | | --// The general mechanism works by defining a symbol `f_impl__` and a weak alias `f` via the |
27 | | --// _LIBCPP_OVERRIDABLE_FUNCTION macro. |
28 | | -+// The general mechanism works by placing `f`'s definition (in the libc++ built library) |
29 | | -+// inside a special section, which we do using the `__section__` attribute via the |
30 | | -+// _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE macro. |
31 | | - // |
32 | | - // Then, when comes the time to check whether the function has been overridden, we take |
33 | | --// the address of the function `f` and we check whether it is different from `f_impl__`. |
34 | | --// If so it means the function was overriden by the user. |
35 | | -+// the address of the function and we check whether it falls inside the special function |
36 | | -+// we created. This can be done by finding pointers to the start and the end of the section |
37 | | -+// (which is done differently for ELF and Mach-O), and then checking whether `f` falls |
38 | | -+// within those bounds. If it falls within those bounds, then `f` is still inside the |
39 | | -+// special section and so it is the version we defined in the libc++ built library, i.e. |
40 | | -+// it was not overridden. Otherwise, it was overridden by the user because it falls |
41 | | -+// outside of the section. |
42 | | - // |
43 | | - // Important note |
44 | | - // -------------- |
45 | | - // |
46 | | --// This mechanism should never be used outside of the libc++ built library. Functions defined |
47 | | --// with this macro must be defined at global scope. |
48 | | -+// This mechanism should never be used outside of the libc++ built library. In particular, |
49 | | -+// attempting to use this within the libc++ headers will not work at all because we don't |
50 | | -+// want to be defining special sections inside user's executables which use our headers. |
51 | | - // |
52 | | - |
53 | | - #if defined(_LIBCPP_OBJECT_FORMAT_MACHO) |
54 | | - |
55 | | --_LIBCPP_BEGIN_NAMESPACE_STD |
56 | | -- |
57 | | --template <auto _Func> |
58 | | --_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden(); |
59 | | -+# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 |
60 | | -+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE \ |
61 | | -+ __attribute__((__section__("__TEXT,__lcxx_override,regular,pure_instructions"))) |
62 | | - |
63 | | -+_LIBCPP_BEGIN_NAMESPACE_STD |
64 | | -+template <class _Ret, class... _Args> |
65 | | -+_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept { |
66 | | -+ // Declare two dummy bytes and give them these special `__asm` values. These values are |
67 | | -+ // defined by the linker, which means that referring to `&__lcxx_override_start` will |
68 | | -+ // effectively refer to the address where the section starts (and same for the end). |
69 | | -+ extern char __lcxx_override_start __asm("section$start$__TEXT$__lcxx_override"); |
70 | | -+ extern char __lcxx_override_end __asm("section$end$__TEXT$__lcxx_override"); |
71 | | -+ |
72 | | -+ // Now get a uintptr_t out of these locations, and out of the function pointer. |
73 | | -+ uintptr_t __start = reinterpret_cast<uintptr_t>(&__lcxx_override_start); |
74 | | -+ uintptr_t __end = reinterpret_cast<uintptr_t>(&__lcxx_override_end); |
75 | | -+ uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr); |
76 | | -+ |
77 | | -+# if __has_feature(ptrauth_calls) |
78 | | -+ // We must pass a void* to ptrauth_strip since it only accepts a pointer type. Also, in particular, |
79 | | -+ // we must NOT pass a function pointer, otherwise we will strip the function pointer, and then attempt |
80 | | -+ // to authenticate and re-sign it when casting it to a uintptr_t again, which will fail because we just |
81 | | -+ // stripped the function pointer. See rdar://122927845. |
82 | | -+ __ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer)); |
83 | | -+# endif |
84 | | -+ |
85 | | -+ // Finally, the function was overridden if it falls outside of the section's bounds. |
86 | | -+ return __ptr < __start || __ptr > __end; |
87 | | -+} |
88 | | - _LIBCPP_END_NAMESPACE_STD |
89 | | - |
90 | | -+// The NVPTX linker cannot create '__start/__stop' sections. |
91 | | -+#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) && !defined(__NVPTX__) |
92 | | -+ |
93 | | - # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 |
94 | | --# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \ |
95 | | -- static type symbol##_impl__ arglist __asm__("_" _LIBCPP_TOSTRING(symbol)); \ |
96 | | -- __asm__(".globl _" _LIBCPP_TOSTRING(symbol)); \ |
97 | | -- __asm__(".weak_definition _" _LIBCPP_TOSTRING(symbol)); \ |
98 | | -- extern __typeof(symbol##_impl__) name __attribute__((weak_import)); \ |
99 | | -- _LIBCPP_BEGIN_NAMESPACE_STD \ |
100 | | -- template <> \ |
101 | | -- bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \ |
102 | | -- return static_cast<type(*) arglist>(name) != symbol##_impl__; \ |
103 | | -- } \ |
104 | | -- _LIBCPP_END_NAMESPACE_STD \ |
105 | | -- static type symbol##_impl__ arglist |
106 | | -+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE __attribute__((__section__("__lcxx_override"))) |
107 | | - |
108 | | --#elif defined(_LIBCPP_OBJECT_FORMAT_ELF) |
109 | | -+// This is very similar to what we do for Mach-O above. The ELF linker will implicitly define |
110 | | -+// variables with those names corresponding to the start and the end of the section. |
111 | | -+// |
112 | | -+// See https://stackoverflow.com/questions/16552710/how-do-you-get-the-start-and-end-addresses-of-a-custom-elf-section |
113 | | -+extern char __start___lcxx_override; |
114 | | -+extern char __stop___lcxx_override; |
115 | | - |
116 | | - _LIBCPP_BEGIN_NAMESPACE_STD |
117 | | -+template <class _Ret, class... _Args> |
118 | | -+_LIBCPP_HIDE_FROM_ABI bool __is_function_overridden(_Ret (*__fptr)(_Args...)) noexcept { |
119 | | -+ uintptr_t __start = reinterpret_cast<uintptr_t>(&__start___lcxx_override); |
120 | | -+ uintptr_t __end = reinterpret_cast<uintptr_t>(&__stop___lcxx_override); |
121 | | -+ uintptr_t __ptr = reinterpret_cast<uintptr_t>(__fptr); |
122 | | -+ |
123 | | -+# if __has_feature(ptrauth_calls) |
124 | | -+ // We must pass a void* to ptrauth_strip since it only accepts a pointer type. See full explanation above. |
125 | | -+ __ptr = reinterpret_cast<uintptr_t>(ptrauth_strip(reinterpret_cast<void*>(__ptr), ptrauth_key_function_pointer)); |
126 | | -+# endif |
127 | | - |
128 | | --template <auto _Func> |
129 | | --_LIBCPP_HIDE_FROM_ABI constexpr bool __is_function_overridden(); |
130 | | -- |
131 | | -+ return __ptr < __start || __ptr > __end; |
132 | | -+} |
133 | | - _LIBCPP_END_NAMESPACE_STD |
134 | | - |
135 | | --# define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 1 |
136 | | --# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) \ |
137 | | -- static type symbol##_impl__ arglist __asm__(_LIBCPP_TOSTRING(symbol##_impl__)); \ |
138 | | -- [[gnu::weak, gnu::alias(_LIBCPP_TOSTRING(symbol##_impl__))]] type name arglist; \ |
139 | | -- _LIBCPP_BEGIN_NAMESPACE_STD \ |
140 | | -- template <> \ |
141 | | -- bool __is_function_overridden<static_cast<type(*) arglist>(name)>() { \ |
142 | | -- return static_cast<type(*) arglist>(name) != symbol##_impl__; \ |
143 | | -- } \ |
144 | | -- _LIBCPP_END_NAMESPACE_STD \ |
145 | | -- static type symbol##_impl__ arglist |
146 | | -- |
147 | | - #else |
148 | | - |
149 | | - # define _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION 0 |
150 | | --# define _LIBCPP_OVERRIDABLE_FUNCTION(symbol, type, name, arglist) _LIBCPP_WEAK type name arglist |
151 | | -+# define _LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE /* nothing */ |
152 | | - |
153 | | - #endif |
154 | | - |
155 | | -diff -ruN --strip-trailing-cr a/libcxx/src/new.cpp b/libcxx/src/new.cpp |
156 | | ---- a/libcxx/src/new.cpp |
157 | | -+++ b/libcxx/src/new.cpp |
158 | | -@@ -43,7 +43,7 @@ |
159 | | - return p; |
160 | | - } |
161 | | - |
162 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_Znwm, void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC { |
163 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { |
164 | | - void* p = operator_new_impl(size); |
165 | | - if (p == nullptr) |
166 | | - __throw_bad_alloc_shim(); |
167 | | -@@ -54,7 +54,7 @@ |
168 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
169 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
170 | | - _LIBCPP_ASSERT_SHIM( |
171 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new)>(), |
172 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)), |
173 | | - "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, " |
174 | | - "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because " |
175 | | - "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case " |
176 | | -@@ -74,7 +74,7 @@ |
177 | | - # endif |
178 | | - } |
179 | | - |
180 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_Znam, void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { |
181 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { |
182 | | - return ::operator new(size); |
183 | | - } |
184 | | - |
185 | | -@@ -82,7 +82,7 @@ |
186 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
187 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
188 | | - _LIBCPP_ASSERT_SHIM( |
189 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new[])>(), |
190 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])), |
191 | | - "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, " |
192 | | - "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because " |
193 | | - "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case " |
194 | | -@@ -136,8 +136,8 @@ |
195 | | - return p; |
196 | | - } |
197 | | - |
198 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_ZnwmSt11align_val_t, void*, operator new, (std::size_t size, std::align_val_t alignment)) |
199 | | --_THROW_BAD_ALLOC { |
200 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* |
201 | | -+operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { |
202 | | - void* p = operator_new_aligned_impl(size, alignment); |
203 | | - if (p == nullptr) |
204 | | - __throw_bad_alloc_shim(); |
205 | | -@@ -148,7 +148,7 @@ |
206 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
207 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
208 | | - _LIBCPP_ASSERT_SHIM( |
209 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)>(), |
210 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)), |
211 | | - "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, " |
212 | | - "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " |
213 | | - "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will " |
214 | | -@@ -168,14 +168,16 @@ |
215 | | - # endif |
216 | | - } |
217 | | - |
218 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_ZnamSt11align_val_t, void*, operator new[], (size_t size, std::align_val_t alignment)) |
219 | | --_THROW_BAD_ALLOC { return ::operator new(size, alignment); } |
220 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* |
221 | | -+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { |
222 | | -+ return ::operator new(size, alignment); |
223 | | -+} |
224 | | - |
225 | | - _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { |
226 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
227 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
228 | | - _LIBCPP_ASSERT_SHIM( |
229 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])>(), |
230 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])), |
231 | | - "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, " |
232 | | - "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " |
233 | | - "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will " |
234 | | -diff -ruN --strip-trailing-cr a/libcxxabi/src/stdlib_new_delete.cpp b/libcxxabi/src/stdlib_new_delete.cpp |
235 | | ---- a/libcxxabi/src/stdlib_new_delete.cpp |
236 | | -+++ b/libcxxabi/src/stdlib_new_delete.cpp |
237 | | -@@ -63,7 +63,7 @@ |
238 | | - return p; |
239 | | - } |
240 | | - |
241 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_Znwm, void*, operator new, (std::size_t size)) _THROW_BAD_ALLOC { |
242 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new(std::size_t size) _THROW_BAD_ALLOC { |
243 | | - void* p = operator_new_impl(size); |
244 | | - if (p == nullptr) |
245 | | - __throw_bad_alloc_shim(); |
246 | | -@@ -74,7 +74,7 @@ |
247 | | - #if !_LIBCPP_HAS_EXCEPTIONS |
248 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
249 | | - _LIBCPP_ASSERT_SHIM( |
250 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new)>(), |
251 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new)), |
252 | | - "libc++ was configured with exceptions disabled and `operator new(size_t)` has been overridden, " |
253 | | - "but `operator new(size_t, nothrow_t)` has not been overridden. This is problematic because " |
254 | | - "`operator new(size_t, nothrow_t)` must call `operator new(size_t)`, which will terminate in case " |
255 | | -@@ -94,7 +94,7 @@ |
256 | | - #endif |
257 | | - } |
258 | | - |
259 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_Znam, void*, operator new[], (size_t size)) _THROW_BAD_ALLOC { |
260 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* operator new[](size_t size) _THROW_BAD_ALLOC { |
261 | | - return ::operator new(size); |
262 | | - } |
263 | | - |
264 | | -@@ -102,7 +102,7 @@ |
265 | | - #if !_LIBCPP_HAS_EXCEPTIONS |
266 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
267 | | - _LIBCPP_ASSERT_SHIM( |
268 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t)>(&operator new[])>(), |
269 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t)>(&operator new[])), |
270 | | - "libc++ was configured with exceptions disabled and `operator new[](size_t)` has been overridden, " |
271 | | - "but `operator new[](size_t, nothrow_t)` has not been overridden. This is problematic because " |
272 | | - "`operator new[](size_t, nothrow_t)` must call `operator new[](size_t)`, which will terminate in case " |
273 | | -@@ -156,8 +156,8 @@ |
274 | | - return p; |
275 | | - } |
276 | | - |
277 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_ZnwmSt11align_val_t, void*, operator new, (std::size_t size, std::align_val_t alignment)) |
278 | | --_THROW_BAD_ALLOC { |
279 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* |
280 | | -+operator new(std::size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { |
281 | | - void* p = operator_new_aligned_impl(size, alignment); |
282 | | - if (p == nullptr) |
283 | | - __throw_bad_alloc_shim(); |
284 | | -@@ -168,7 +168,7 @@ |
285 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
286 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
287 | | - _LIBCPP_ASSERT_SHIM( |
288 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)>(), |
289 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new)), |
290 | | - "libc++ was configured with exceptions disabled and `operator new(size_t, align_val_t)` has been overridden, " |
291 | | - "but `operator new(size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " |
292 | | - "`operator new(size_t, align_val_t, nothrow_t)` must call `operator new(size_t, align_val_t)`, which will " |
293 | | -@@ -188,14 +188,16 @@ |
294 | | - # endif |
295 | | - } |
296 | | - |
297 | | --_LIBCPP_OVERRIDABLE_FUNCTION(_ZnamSt11align_val_t, void*, operator new[], (size_t size, std::align_val_t alignment)) |
298 | | --_THROW_BAD_ALLOC { return ::operator new(size, alignment); } |
299 | | -+_LIBCPP_MAKE_OVERRIDABLE_FUNCTION_DETECTABLE _LIBCPP_WEAK void* |
300 | | -+operator new[](size_t size, std::align_val_t alignment) _THROW_BAD_ALLOC { |
301 | | -+ return ::operator new(size, alignment); |
302 | | -+} |
303 | | - |
304 | | - _LIBCPP_WEAK void* operator new[](size_t size, std::align_val_t alignment, const std::nothrow_t&) noexcept { |
305 | | - # if !_LIBCPP_HAS_EXCEPTIONS |
306 | | - # if _LIBCPP_CAN_DETECT_OVERRIDDEN_FUNCTION |
307 | | - _LIBCPP_ASSERT_SHIM( |
308 | | -- !std::__is_function_overridden<static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])>(), |
309 | | -+ !std::__is_function_overridden(static_cast<void* (*)(std::size_t, std::align_val_t)>(&operator new[])), |
310 | | - "libc++ was configured with exceptions disabled and `operator new[](size_t, align_val_t)` has been overridden, " |
311 | | - "but `operator new[](size_t, align_val_t, nothrow_t)` has not been overridden. This is problematic because " |
312 | | - "`operator new[](size_t, align_val_t, nothrow_t)` must call `operator new[](size_t, align_val_t)`, which will " |
0 commit comments