blob: 0c1999bc8f664f3ccee7ed0c17f5ea3541a727da [file] [log] [blame]
George Burgess IVb97049c2017-07-24 15:05:05 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#ifndef _STRING_H
30#error "Never include this file directly; instead, include <string.h>"
31#endif
32
Elliott Hughes3f66e742017-08-01 13:24:40 -070033void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
34void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
35char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
36char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
37size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
38size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
George Burgess IVb97049c2017-07-24 15:05:05 -070039
40/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
41 * have the definition out here.
42 */
43struct __bionic_zero_size_is_okay_t {};
44
45#if defined(__BIONIC_FORTIFY)
46// These can share their implementation between gcc and clang with minimal
47// trickery...
48#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
49__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070050void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
George Burgess IVb97049c2017-07-24 15:05:05 -070051 __overloadable {
52 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
53}
54
55__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070056void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070057 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
58}
59#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
60
61#if __ANDROID_API__ >= __ANDROID_API_L__
62__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070063char* stpcpy(char* const dst __pass_object_size, const char* src) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070064 return __builtin___stpcpy_chk(dst, src, __bos(dst));
65}
66#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
67
68#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
69__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070070char* strcpy(char* const dst __pass_object_size, const char* src) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070071 return __builtin___strcpy_chk(dst, src, __bos(dst));
72}
73
74__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070075char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070076 return __builtin___strcat_chk(dst, src, __bos(dst));
77}
78
79__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070080char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070081 return __builtin___strncat_chk(dst, src, n, __bos(dst));
82}
83
84__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070085void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070086 return __builtin___memset_chk(s, c, n, __bos0(s));
87}
88#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
89
90
91#if defined(__clang__)
92
93#define __error_if_overflows_dst(name, dst, n, what) \
94 __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
95 __bos0(dst) < (n), "selected when the buffer is too small") \
96 __errorattr(#name " called with " what " bigger than buffer")
97
George Burgess IVb97049c2017-07-24 15:05:05 -070098__BIONIC_ERROR_FUNCTION_VISIBILITY
99void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
100 __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
101
102__BIONIC_ERROR_FUNCTION_VISIBILITY
103void* memmove(void *dst, const void* src, size_t len) __overloadable
104 __error_if_overflows_dst(memmove, dst, len, "size");
105
106__BIONIC_ERROR_FUNCTION_VISIBILITY
107void* memset(void* s, int c, size_t n) __overloadable
108 __error_if_overflows_dst(memset, s, n, "size");
109
110__BIONIC_ERROR_FUNCTION_VISIBILITY
111char* stpcpy(char* dst, const char* src) __overloadable
112 __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
113
114__BIONIC_ERROR_FUNCTION_VISIBILITY
115char* strcpy(char* dst, const char* src) __overloadable
116 __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
117
118#if __ANDROID_API__ >= __ANDROID_API_M__
119__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700120void* memchr(const void* const s __pass_object_size, int c, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700121 __overloadable {
122 size_t bos = __bos(s);
123
124 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
125 return __builtin_memchr(s, c, n);
126 }
127
128 return __memchr_chk(s, c, n, bos);
129}
130
131__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700132void* memrchr(const void* const s __pass_object_size, int c, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700133 __overloadable {
134 size_t bos = __bos(s);
135
136 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
137 return __call_bypassing_fortify(memrchr)(s, c, n);
138 }
139
140 return __memrchr_chk(s, c, n, bos);
141}
142#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
143
144#if __ANDROID_API__ >= __ANDROID_API_L__
145__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700146char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700147 __overloadable {
148 size_t bos_dst = __bos(dst);
149 size_t bos_src = __bos(src);
150
151 /* Ignore dst size checks; they're handled in strncpy_chk */
152 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
153 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
154 }
155
156 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
157}
158
159__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700160char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700161 __overloadable {
162 size_t bos_dst = __bos(dst);
163 size_t bos_src = __bos(src);
164
165 /* Ignore dst size checks; they're handled in strncpy_chk */
166 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
167 return __builtin___strncpy_chk(dst, src, n, bos_dst);
168 }
169
170 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
171}
172#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
173
174#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
175__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700176size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
George Burgess IVb97049c2017-07-24 15:05:05 -0700177 __overloadable {
178 size_t bos = __bos(dst);
179
180 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
181 return __call_bypassing_fortify(strlcpy)(dst, src, size);
182 }
183
184 return __strlcpy_chk(dst, src, size, bos);
185}
186
187__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700188size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
George Burgess IVb97049c2017-07-24 15:05:05 -0700189 __overloadable {
190 size_t bos = __bos(dst);
191
192 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
193 return __call_bypassing_fortify(strlcat)(dst, src, size);
194 }
195
196 return __strlcat_chk(dst, src, size, bos);
197}
198
199/*
200 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
201 * on it directly. This makes it way easier for compilers to fold things like
202 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
203 * because it's large.
204 */
205__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700206size_t strlen(const char* const s __pass_object_size)
George Burgess IVb97049c2017-07-24 15:05:05 -0700207 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
208 "enabled if s is a known good string.") {
209 return __builtin_strlen(s);
210}
211
212__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700213size_t strlen(const char* const s __pass_object_size0)
George Burgess IVb97049c2017-07-24 15:05:05 -0700214 __overloadable {
215 size_t bos = __bos0(s);
216
217 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
218 return __builtin_strlen(s);
219 }
220
221 // return __builtin_strlen(s);
222 return __strlen_chk(s, bos);
223}
224#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
225
226#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
227__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700228char* strchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700229 size_t bos = __bos(s);
230
231 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
232 return __builtin_strchr(s, c);
233 }
234
235 return __strchr_chk(s, c, bos);
236}
237
238__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700239char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700240 size_t bos = __bos(s);
241
242 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
243 return __builtin_strrchr(s, c);
244 }
245
246 return __strrchr_chk(s, c, bos);
247}
248#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
249
250#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
251/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
252 * flipped the size + value arguments. However, there may be cases (e.g. with
253 * macros) where it's okay for the size to fold to zero. We should warn on this,
254 * but we should also provide a FORTIFY'ed escape hatch.
255 */
256__BIONIC_ERROR_FUNCTION_VISIBILITY
Elliott Hughes3f66e742017-08-01 13:24:40 -0700257void* memset(void* s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
George Burgess IVb97049c2017-07-24 15:05:05 -0700258 __overloadable
259 __error_if_overflows_dst(memset, s, n, "size");
260
261__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700262void* memset(void* const s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
George Burgess IVb97049c2017-07-24 15:05:05 -0700263 __overloadable {
264 return __builtin___memset_chk(s, c, n, __bos0(s));
265}
266
267extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
268/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
269 * flipping size + count will do nothing.
270 */
271__BIONIC_ERROR_FUNCTION_VISIBILITY
Elliott Hughes3f66e742017-08-01 13:24:40 -0700272void* memset(void* s, int c, size_t n) __overloadable
George Burgess IVb97049c2017-07-24 15:05:05 -0700273 __enable_if(c && !n, "selected when we'll set zero bytes")
274 __RENAME_CLANG(memset)
275 __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
276 "(Add __bionic_zero_size_is_okay as a fourth argument "
277 "to silence this.)");
278#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
279
280#undef __error_zero_size
281#undef __error_if_overflows_dst
282#else // defined(__clang__)
Elliott Hughesec6850d2017-08-01 08:28:46 -0700283extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
George Burgess IVb97049c2017-07-24 15:05:05 -0700284extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
Elliott Hughesec6850d2017-08-01 08:28:46 -0700285extern size_t __strlcpy_real(char*, const char*, size_t)
George Burgess IVb97049c2017-07-24 15:05:05 -0700286 __RENAME(strlcpy);
Elliott Hughesec6850d2017-08-01 08:28:46 -0700287extern size_t __strlcat_real(char*, const char*, size_t)
George Burgess IVb97049c2017-07-24 15:05:05 -0700288 __RENAME(strlcat);
289
290__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
291__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
292
293#if __ANDROID_API__ >= __ANDROID_API_M__
294__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700295void* memchr(const void* s __pass_object_size, int c, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700296 size_t bos = __bos(s);
297
298 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
299 return __builtin_memchr(s, c, n);
300 }
301
302 if (__builtin_constant_p(n) && (n > bos)) {
303 __memchr_buf_size_error();
304 }
305
306 if (__builtin_constant_p(n) && (n <= bos)) {
307 return __builtin_memchr(s, c, n);
308 }
309
310 return __memchr_chk(s, c, n, bos);
311}
312
313__BIONIC_FORTIFY_INLINE
314void* memrchr(const void* s, int c, size_t n) {
315 size_t bos = __bos(s);
316
317 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
318 return __memrchr_real(s, c, n);
319 }
320
321 if (__builtin_constant_p(n) && (n > bos)) {
322 __memrchr_buf_size_error();
323 }
324
325 if (__builtin_constant_p(n) && (n <= bos)) {
326 return __memrchr_real(s, c, n);
327 }
328
329 return __memrchr_chk(s, c, n, bos);
330}
331#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
332
333#if __ANDROID_API__ >= __ANDROID_API_L__
334__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700335char* stpncpy(char* dst, const char* src, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700336 size_t bos_dst = __bos(dst);
337 size_t bos_src = __bos(src);
338
339 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
340 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
341 }
342
343 if (__builtin_constant_p(n) && (n <= bos_src)) {
344 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
345 }
346
347 size_t slen = __builtin_strlen(src);
348 if (__builtin_constant_p(slen)) {
349 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
350 }
351
352 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
353}
354
355__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700356char* strncpy(char* dst, const char* src, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700357 size_t bos_dst = __bos(dst);
358 size_t bos_src = __bos(src);
359
360 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
361 return __strncpy_real(dst, src, n);
362 }
363
364 if (__builtin_constant_p(n) && (n <= bos_src)) {
365 return __builtin___strncpy_chk(dst, src, n, bos_dst);
366 }
367
368 size_t slen = __builtin_strlen(src);
369 if (__builtin_constant_p(slen)) {
370 return __builtin___strncpy_chk(dst, src, n, bos_dst);
371 }
372
373 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
374}
375#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
376
377#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
378__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700379size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700380 size_t bos = __bos(dst);
381
382 // Compiler doesn't know destination size. Don't call __strlcpy_chk
383 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
384 return __strlcpy_real(dst, src, size);
385 }
386
387 // Compiler can prove, at compile time, that the passed in size
388 // is always <= the actual object size. Don't call __strlcpy_chk
389 if (__builtin_constant_p(size) && (size <= bos)) {
390 return __strlcpy_real(dst, src, size);
391 }
392
393 return __strlcpy_chk(dst, src, size, bos);
394}
395
396__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700397size_t strlcat(char* dst, const char* src, size_t size) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700398 size_t bos = __bos(dst);
399
400 // Compiler doesn't know destination size. Don't call __strlcat_chk
401 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
402 return __strlcat_real(dst, src, size);
403 }
404
405 // Compiler can prove, at compile time, that the passed in size
406 // is always <= the actual object size. Don't call __strlcat_chk
407 if (__builtin_constant_p(size) && (size <= bos)) {
408 return __strlcat_real(dst, src, size);
409 }
410
411 return __strlcat_chk(dst, src, size, bos);
412}
413
414__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700415size_t strlen(const char* s) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700416 size_t bos = __bos(s);
417
418 // Compiler doesn't know destination size. Don't call __strlen_chk
419 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
420 return __builtin_strlen(s);
421 }
422
423 size_t slen = __builtin_strlen(s);
424 if (__builtin_constant_p(slen)) {
425 return slen;
426 }
427
428 return __strlen_chk(s, bos);
429}
430#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
431
432#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
433__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700434char* strchr(const char* s, int c) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700435 size_t bos = __bos(s);
436
437 // Compiler doesn't know destination size. Don't call __strchr_chk
438 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
439 return __builtin_strchr(s, c);
440 }
441
442 size_t slen = __builtin_strlen(s);
443 if (__builtin_constant_p(slen) && (slen < bos)) {
444 return __builtin_strchr(s, c);
445 }
446
447 return __strchr_chk(s, c, bos);
448}
449
450__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700451char* strrchr(const char* s, int c) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700452 size_t bos = __bos(s);
453
454 // Compiler doesn't know destination size. Don't call __strrchr_chk
455 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
456 return __builtin_strrchr(s, c);
457 }
458
459 size_t slen = __builtin_strlen(s);
460 if (__builtin_constant_p(slen) && (slen < bos)) {
461 return __builtin_strrchr(s, c);
462 }
463
464 return __strrchr_chk(s, c, bos);
465}
466#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
467#endif /* defined(__clang__) */
468#endif /* defined(__BIONIC_FORTIFY) */